Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with SendGrid

Send transactional emails from your Bolt.new app using SendGrid's Web API v3 and the @sendgrid/mail npm package — it is pure JavaScript and works in Bolt's WebContainer. Create a Next.js API route that calls SendGrid server-side, store your API key in environment variables only, and use dynamic templates for HTML emails. Incoming webhook events require a deployed URL — test on Netlify or Bolt Cloud.

What you'll learn

  • How to create a SendGrid API key with the correct permissions for transactional email
  • How to build a Next.js API route that sends emails using @sendgrid/mail
  • How to use SendGrid dynamic templates for branded HTML emails
  • How to handle common transactional email use cases: contact forms, signup confirmations, and order receipts
  • How to configure SendGrid event webhooks on your deployed Netlify URL for delivery tracking
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate16 min read20 minutesCommunicationApril 2026RapidDev Engineering Team
TL;DR

Send transactional emails from your Bolt.new app using SendGrid's Web API v3 and the @sendgrid/mail npm package — it is pure JavaScript and works in Bolt's WebContainer. Create a Next.js API route that calls SendGrid server-side, store your API key in environment variables only, and use dynamic templates for HTML emails. Incoming webhook events require a deployed URL — test on Netlify or Bolt Cloud.

Send Transactional Emails from Bolt.new with SendGrid

Every production web app eventually needs to send emails — signup confirmations, password resets, order receipts, contact form notifications, and trial expiry reminders. SendGrid is among the most popular choices for this because it offers generous free tier limits (100 emails/day), extremely high deliverability, and a clean API that works with standard npm packages in any Node.js environment.

The @sendgrid/mail package is pure JavaScript with no native C/C++ dependencies — a critical property for Bolt.new's WebContainer, which cannot compile native Node.js modules. Installing it via npm in Bolt works instantly, and making outbound API calls to SendGrid's infrastructure works from the WebContainer preview. You can build and test email-sending features entirely in Bolt before deploying.

The security model requires careful attention. Your SendGrid API key must never appear in client-side React components or in NEXT_PUBLIC_ prefixed environment variables. It belongs exclusively in server-side API routes, where it is never bundled into the JavaScript that ships to the browser. A Next.js API route serves as the secure relay: your React frontend calls your own API route, which calls SendGrid with the key. This pattern protects the key and also prevents users from bypassing your email logic to send arbitrary emails through your SendGrid account.

Integration method

Bolt Chat + API Route

SendGrid's @sendgrid/mail npm package is pure JavaScript and installs without issues in Bolt.new's WebContainer. Outbound email sending works in development via API routes. Store your SendGrid API key in .env.local and access it only from Next.js API routes — never from client-side code. Incoming webhook events (email opens, bounces, clicks) require a public URL and must be configured after deploying to Netlify or Bolt Cloud.

Prerequisites

  • A SendGrid account at sendgrid.com — the free tier allows 100 emails/day with full API access
  • A SendGrid API key created in Settings → API Keys with 'Mail Send' permissions
  • A verified sender identity in SendGrid (Settings → Sender Authentication) — SendGrid blocks email until you verify your sending domain or email address
  • A Bolt.new account with a new Next.js project open
  • A Netlify account for deployment and webhook configuration

Step-by-step guide

1

Create a SendGrid API key and verify your sender identity

SendGrid requires two setup steps before you can send any email: creating an API key and verifying your sender identity. Both are done in the SendGrid dashboard at app.sendgrid.com. For the API key: go to Settings → API Keys → Create API Key. Name it clearly (e.g., 'My App Production'). Choose 'Restricted Access' and enable 'Mail Send' permissions — this is the minimum required scope. Avoid using Full Access keys unless you specifically need to manage templates, contacts, or domains via API. Copy the key immediately — SendGrid shows it only once. The key begins with `SG.` followed by a long string. For sender identity: SendGrid will not deliver email unless your sending address or domain is verified. The fastest path is Single Sender Verification: go to Settings → Sender Authentication → Get Started (under Single Sender Verification), enter your name and email address, and click verify. SendGrid emails you a confirmation link — click it. For production with a custom domain (recommended for better deliverability and brand consistency), use Domain Authentication instead: Settings → Sender Authentication → Authenticate Your Domain. This involves adding DNS records to your domain and takes a few minutes to propagate. Add your credentials to .env.local in your Bolt project. The API key must be a server-side only variable — do not add `NEXT_PUBLIC_` prefix.

Bolt.new Prompt

Set up SendGrid in my Next.js project. Install @sendgrid/mail. Create a .env.local file with SENDGRID_API_KEY=SG.your-key-here and SENDGRID_FROM_EMAIL=your-verified-sender@example.com. Create a lib/sendgrid.ts file that imports @sendgrid/mail, sets the API key from process.env.SENDGRID_API_KEY, and exports a sendEmail helper function that accepts to, subject, text (plain text fallback), and html parameters. Add proper TypeScript types.

Paste this in Bolt.new chat

lib/sendgrid.ts
1// lib/sendgrid.ts
2import sgMail from '@sendgrid/mail';
3
4sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
5
6interface EmailOptions {
7 to: string | string[];
8 subject: string;
9 text: string;
10 html?: string;
11 templateId?: string;
12 dynamicTemplateData?: Record<string, unknown>;
13 replyTo?: string;
14}
15
16export async function sendEmail(options: EmailOptions): Promise<void> {
17 const fromEmail = process.env.SENDGRID_FROM_EMAIL;
18 if (!fromEmail) throw new Error('SENDGRID_FROM_EMAIL is not set');
19
20 const message: sgMail.MailDataRequired = {
21 to: options.to,
22 from: fromEmail,
23 subject: options.subject,
24 text: options.text,
25 ...(options.html && { html: options.html }),
26 ...(options.templateId && {
27 templateId: options.templateId,
28 dynamicTemplateData: options.dynamicTemplateData,
29 }),
30 ...(options.replyTo && { replyTo: options.replyTo }),
31 };
32
33 await sgMail.send(message);
34}
35
36export async function sendBulkEmail(
37 messages: EmailOptions[]
38): Promise<void> {
39 const fromEmail = process.env.SENDGRID_FROM_EMAIL!;
40 const prepared = messages.map(opts => ({
41 to: opts.to,
42 from: fromEmail,
43 subject: opts.subject,
44 text: opts.text,
45 ...(opts.html && { html: opts.html }),
46 })) as sgMail.MailDataRequired[];
47
48 await sgMail.sendMultiple(prepared);
49}

Pro tip: Always verify your sender domain (not just the email address) for production apps. Domain authentication improves deliverability significantly and prevents your emails from landing in spam. It also removes the 'sent via sendgrid.net' annotation that appears in Gmail for unverified senders.

Expected result: A configured SendGrid helper library in lib/sendgrid.ts and environment variables set in .env.local, ready for use in API routes.

2

Build the contact form email API route

The contact form API route is the most common first use case — it handles POST requests from your frontend form, validates the input, sends an email notification to your inbox, and optionally sends a confirmation to the form submitter. The key security principle: this route must be a server-side API route (`app/api/`), never a client-side function. If you call SendGrid directly from a React component, the API key is exposed in the browser network requests. The API route keeps the key server-side and also lets you implement rate limiting, spam filtering, and validation logic before sending. Adding a honeypot field (a hidden form field that humans never fill but bots do) and basic rate limiting significantly reduces spam submissions from contact forms. The route should also validate that the email format is valid and that required fields are present before calling SendGrid. For the confirmation email back to the user, use a simple but professional HTML template inline rather than a SendGrid template for simple contact confirmations — it avoids the need to manage template IDs in environment variables for a one-off email.

Bolt.new Prompt

Create a contact form API route at app/api/contact/route.ts. Accept POST with JSON body containing name (required), email (required, validate format), message (required, min 10 chars), and honeypot (hidden field, reject if filled — spam protection). Use sendEmail from lib/sendgrid.ts to: (1) send a notification to process.env.CONTACT_EMAIL_TO with subject 'New Contact Form Submission from {name}' and the message details, (2) send a confirmation to the submitter's email saying their message was received. Return 200 on success, 400 for validation errors, 500 for send failures. Then create a ContactForm React component with fields for name, email, and message, a hidden honeypot input, and submit handling with loading/success/error states.

Paste this in Bolt.new chat

app/api/contact/route.ts
1// app/api/contact/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { sendEmail } from '@/lib/sendgrid';
4
5interface ContactFormBody {
6 name: string;
7 email: string;
8 message: string;
9 honeypot?: string;
10}
11
12const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
13
14export async function POST(request: NextRequest) {
15 const body: ContactFormBody = await request.json();
16 const { name, email, message, honeypot } = body;
17
18 // Honeypot check — bots fill hidden fields
19 if (honeypot) {
20 return NextResponse.json({ success: true }); // Silent accept to not alert bots
21 }
22
23 // Validation
24 if (!name?.trim() || name.trim().length < 2) {
25 return NextResponse.json({ error: 'Name is required' }, { status: 400 });
26 }
27 if (!email || !emailRegex.test(email)) {
28 return NextResponse.json({ error: 'Valid email is required' }, { status: 400 });
29 }
30 if (!message?.trim() || message.trim().length < 10) {
31 return NextResponse.json({ error: 'Message must be at least 10 characters' }, { status: 400 });
32 }
33
34 const notificationHtml = `
35 <h2>New Contact Form Submission</h2>
36 <p><strong>Name:</strong> ${name}</p>
37 <p><strong>Email:</strong> <a href="mailto:${email}">${email}</a></p>
38 <p><strong>Message:</strong></p>
39 <p>${message.replace(/\n/g, '<br>')}</p>
40 `;
41
42 const confirmationHtml = `
43 <h2>Thanks for reaching out, ${name}!</h2>
44 <p>We received your message and will get back to you within 1-2 business days.</p>
45 <p><em>Your message:</em><br>${message.replace(/\n/g, '<br>')}</p>
46 `;
47
48 try {
49 await sendEmail({
50 to: process.env.CONTACT_EMAIL_TO!,
51 subject: `New Contact Form Submission from ${name}`,
52 text: `Name: ${name}\nEmail: ${email}\nMessage: ${message}`,
53 html: notificationHtml,
54 replyTo: email,
55 });
56
57 await sendEmail({
58 to: email,
59 subject: 'We received your message',
60 text: `Thanks for reaching out, ${name}! We will get back to you within 1-2 business days.`,
61 html: confirmationHtml,
62 });
63
64 return NextResponse.json({ success: true });
65 } catch (error) {
66 console.error('SendGrid error:', error);
67 return NextResponse.json({ error: 'Failed to send message' }, { status: 500 });
68 }
69}

Pro tip: Add CONTACT_EMAIL_TO to your .env.local file pointing to your inbox. Use a role-based address like contact@yourdomain.com rather than a personal address — role addresses are less likely to be included in accidental 'Reply All' scenarios and are easier to manage as your team grows.

Expected result: A working contact form API that sends email notifications to your inbox and confirmation emails to submitters, with spam protection via honeypot.

3

Use SendGrid dynamic templates for branded HTML emails

For emails where design matters — welcome emails, order confirmations, password resets — use SendGrid's dynamic templates rather than inline HTML. Templates are created in the SendGrid dashboard, give you a visual editor, and support handlebars-style template variables (`{{firstName}}`, `{{orderTotal}}`) that your API fills in at send time. Create a template in SendGrid: go to Email API → Dynamic Templates → Create a Dynamic Template. Name it, add a version, and use the visual editor to design your email. Use handlebars syntax for dynamic values: `{{name}}` for the recipient's name, `{{orderItems}}` for an array of items, `{{ctaUrl}}` for a link. Save and copy the template ID (starts with `d-`). In your API route, pass the template ID and the dynamic data object. SendGrid fills in the template variables server-side before sending — your code never generates HTML for these emails, just passes the data. This separation is valuable for non-technical team members who want to edit email design without touching your codebase. For transactional emails sent at volume (thousands per day), templates also help with compliance: you can add unsubscribe links and preference center links once in the template rather than managing them in every API call. The template handles the footer, legal text, and branding consistently.

Bolt.new Prompt

Add a welcome email function to my app. Create an API route at app/api/email/welcome/route.ts that accepts POST with email and name fields. Use the sendEmail function from lib/sendgrid.ts with templateId from process.env.SENDGRID_WELCOME_TEMPLATE_ID and dynamicTemplateData containing the name and a getting_started_url. Also create a test page at app/test-email/page.tsx with a form to send a test welcome email to any address, so I can verify the template renders correctly during development. This page should only render in non-production environments.

Paste this in Bolt.new chat

app/api/email/welcome/route.ts
1// app/api/email/welcome/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { sendEmail } from '@/lib/sendgrid';
4
5export async function POST(request: NextRequest) {
6 const { email, name, plan = 'free' } = await request.json();
7
8 if (!email || !name) {
9 return NextResponse.json(
10 { error: 'email and name are required' },
11 { status: 400 }
12 );
13 }
14
15 const templateId = process.env.SENDGRID_WELCOME_TEMPLATE_ID;
16 if (!templateId) {
17 // Fallback to plain text if no template configured
18 await sendEmail({
19 to: email,
20 subject: `Welcome to the app, ${name}!`,
21 text: `Hi ${name}, welcome! Get started at ${process.env.NEXT_PUBLIC_APP_URL}`,
22 html: `<h1>Welcome, ${name}!</h1><p>Get started at <a href="${process.env.NEXT_PUBLIC_APP_URL}">the app</a>.</p>`,
23 });
24 } else {
25 await sendEmail({
26 to: email,
27 subject: `Welcome to the app, ${name}!`,
28 text: `Welcome ${name}! We are glad to have you.`,
29 templateId,
30 dynamicTemplateData: {
31 name,
32 plan,
33 getting_started_url: `${process.env.NEXT_PUBLIC_APP_URL}/onboarding`,
34 current_year: new Date().getFullYear(),
35 },
36 });
37 }
38
39 return NextResponse.json({ success: true });
40}

Pro tip: SendGrid template IDs start with 'd-' followed by a UUID. Double-check you are using the template's version ID rather than the template ID — each template has one or more versions. Use the template ID (d-abc123...) not the version ID when passing templateId to the mail API.

Expected result: Welcome emails send successfully using SendGrid dynamic templates, with dynamic user data populated from the API route.

4

Deploy to Netlify and configure SendGrid event webhooks

Email sending works in Bolt.new's WebContainer during development — outbound API calls to SendGrid's mail endpoints are fully functional in the preview. When you are ready to configure delivery tracking (bounces, opens, clicks, unsubscribes), you need a deployed URL for SendGrid's Event Webhook, which sends POST requests to your endpoint when email events occur. Deploy your app to Netlify by clicking Deploy in Bolt.new and connecting to Netlify via OAuth. After deployment, go to Netlify's dashboard → Site Configuration → Environment Variables and add: `SENDGRID_API_KEY`, `SENDGRID_FROM_EMAIL`, `SENDGRID_WELCOME_TEMPLATE_ID`, `CONTACT_EMAIL_TO`, and `NEXT_PUBLIC_APP_URL`. Trigger a redeploy for the variables to apply. For Event Webhooks: create an API route at `/api/sendgrid/webhook` that handles POST requests. In the SendGrid dashboard, go to Settings → Mail Settings → Event Webhook, enter your Netlify URL (`https://your-app.netlify.app/api/sendgrid/webhook`), and select the events you want to track. Enable signature verification to ensure the webhook comes from SendGrid: set the SENDGRID_WEBHOOK_KEY environment variable to the verification key from the Event Webhook settings. Note: Bolt.new's WebContainer has no persistent incoming connection capability during development — SendGrid event webhooks cannot reach the Bolt preview URL. This is a core WebContainer limitation. Always configure and test webhooks using your deployed Netlify domain, not the preview URL.

Bolt.new Prompt

Create a SendGrid event webhook handler at app/api/sendgrid/webhook/route.ts. It should accept POST requests from SendGrid's Event Webhook. Parse the JSON array of events. For 'bounce' and 'spamreport' events, log the email address and event type. For 'delivered' events, log success. Add basic signature verification using the SENDGRID_WEBHOOK_KEY environment variable if set. Return 200 to acknowledge receipt. Also add a netlify.toml file with the correct Next.js build configuration.

Paste this in Bolt.new chat

app/api/sendgrid/webhook/route.ts
1// app/api/sendgrid/webhook/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3
4interface SendGridEvent {
5 email: string;
6 event: string;
7 timestamp: number;
8 sg_event_id: string;
9 sg_message_id?: string;
10 reason?: string;
11 status?: string;
12}
13
14export async function POST(request: NextRequest) {
15 const body = await request.text();
16
17 // Optional: verify SendGrid signature
18 const webhookKey = process.env.SENDGRID_WEBHOOK_KEY;
19 if (webhookKey) {
20 const signature = request.headers.get('X-Twilio-Email-Event-Webhook-Signature');
21 const timestamp = request.headers.get('X-Twilio-Email-Event-Webhook-Timestamp');
22 // In production, verify using @sendgrid/eventwebhook package
23 // For now, log a warning if signature is missing
24 if (!signature || !timestamp) {
25 console.warn('SendGrid webhook missing signature headers');
26 }
27 }
28
29 const events: SendGridEvent[] = JSON.parse(body);
30
31 for (const event of events) {
32 switch (event.event) {
33 case 'delivered':
34 console.log(`Email delivered to ${event.email}`);
35 break;
36 case 'bounce':
37 console.error(`Email bounced for ${event.email}: ${event.reason}`);
38 // TODO: Mark email as invalid in your database
39 break;
40 case 'spamreport':
41 console.warn(`Spam report from ${event.email}`);
42 // TODO: Unsubscribe this email address
43 break;
44 case 'unsubscribe':
45 console.log(`Unsubscribe from ${event.email}`);
46 // TODO: Update user preference in database
47 break;
48 case 'open':
49 console.log(`Email opened by ${event.email}`);
50 break;
51 }
52 }
53
54 // Always return 200 — SendGrid retries on non-200 responses
55 return NextResponse.json({ received: events.length });
56}

Pro tip: Always return a 200 response from your webhook handler even when an error occurs during processing. If SendGrid receives a non-200 response, it retries the webhook multiple times over 72 hours, which can result in duplicate event processing. Log errors internally and return 200 to acknowledge receipt.

Expected result: A deployed Netlify app with SendGrid email sending in production and a webhook endpoint that receives delivery events.

Common use cases

Contact Form Email Notification

When a user submits a contact form on your site, send an email notification to your business inbox with the user's name, email, and message. Optionally send a confirmation email back to the user with an expected response time.

Bolt.new Prompt

Add a contact form to my Next.js app that sends email notifications via SendGrid. Create an API route at /api/contact that accepts POST with name, email, and message fields. Use @sendgrid/mail to send a notification email to process.env.CONTACT_EMAIL_TO with the form data, and a confirmation email back to the submitter saying their message was received. Use process.env.SENDGRID_API_KEY. Add a React contact form component with validation, loading state, and success/error messages.

Copy this prompt to try it in Bolt.new

User Signup Confirmation Email

After a user creates an account, send a branded welcome email using a SendGrid dynamic template. The template handles the HTML formatting so your API just passes the template ID and dynamic variables like the user's name and their sign-up date.

Bolt.new Prompt

When a user successfully signs up using Supabase Auth in my app, trigger a welcome email via SendGrid. Create an API route at /api/email/welcome that accepts POST with email, name, and plan fields. Use @sendgrid/mail with a SendGrid dynamic template ID from process.env.SENDGRID_WELCOME_TEMPLATE_ID, passing the user's name and a getting-started link as template variables. Call this API route from the signup success handler in the frontend.

Copy this prompt to try it in Bolt.new

Order Confirmation Receipt

Send a detailed order receipt email after a successful Stripe payment. The email includes the order ID, items purchased, prices, and a thank-you message. Use SendGrid's dynamic template for a professional, branded receipt layout.

Bolt.new Prompt

Create an order confirmation email system. After a successful Stripe checkout.session.completed webhook event, call a sendOrderConfirmation function that uses @sendgrid/mail to send an order receipt email. The email should include the customer name, order ID, list of items with prices, total amount, and expected delivery date. Use a SendGrid dynamic template (ID from SENDGRID_ORDER_TEMPLATE_ID env var) with templateData containing all order fields.

Copy this prompt to try it in Bolt.new

Troubleshooting

Getting 'The from address does not match a verified Sender Identity' error

Cause: The email address in SENDGRID_FROM_EMAIL has not been verified in SendGrid. SendGrid requires all sending addresses or domains to be verified via Single Sender Verification or Domain Authentication before email can be sent.

Solution: Go to app.sendgrid.com → Settings → Sender Authentication → Get Started under Single Sender Verification. Enter the email address you are using as the from address and complete the verification via the confirmation email. For production, set up Domain Authentication instead to verify your entire domain.

SendGrid API key shows as undefined in server logs even though it is set in .env.local

Cause: Next.js environment variables in .env.local only load in the local development server. After deploying to Netlify, the variables must be added separately in Netlify's environment variable settings — .env.local is never committed or deployed.

Solution: In Netlify dashboard → Site Configuration → Environment Variables → Add variable, add SENDGRID_API_KEY with your key value. Click Trigger Deploy → Deploy site to apply the new variables. The .env.local file exists only for local development and is gitignored by Next.js by default.

Emails are being sent successfully (no API error) but never arrive in the inbox

Cause: Three common causes: (1) emails are in spam/junk — check there first, (2) the sending domain is not authenticated (Domain Authentication not configured), causing poor deliverability, or (3) the recipient email address has a soft bounce or the address is invalid.

Solution: Check SendGrid Activity Feed (app.sendgrid.com → Activity) to see the delivery status. If the status is 'Delivered', the email reached the recipient's mail server — check spam folders. If 'Blocked' or 'Bounced', the Activity log shows the reason. For consistent inbox delivery, complete Domain Authentication in SendGrid Settings → Sender Authentication.

SendGrid event webhooks are not triggering during Bolt.new development

Cause: Bolt.new's WebContainer does not have a persistent public URL that can receive incoming HTTP connections. SendGrid webhooks send POST requests to your specified URL — this requires a deployed, publicly accessible endpoint. The dynamic WebContainer preview URL is not a valid webhook target.

Solution: Deploy your app to Netlify first (click Deploy in Bolt.new), then configure the SendGrid Event Webhook URL to point to your Netlify domain: https://your-app.netlify.app/api/sendgrid/webhook. Webhooks cannot be tested in the Bolt preview — this is a fundamental WebContainer limitation.

Best practices

  • Always store your SendGrid API key in server-side environment variables only — never in NEXT_PUBLIC_ prefixed variables or client-side code
  • Use the minimum required API key scope — 'Mail Send' only — rather than Full Access, to limit potential damage if the key is accidentally exposed
  • Add a plain text version (`text` field) to every email in addition to HTML — many email clients display plain text and it improves deliverability scores
  • Complete Domain Authentication (not just Single Sender Verification) for production apps — authenticated domains have significantly better inbox placement rates
  • Handle bounce and spam report webhook events to remove invalid addresses from future sends — repeatedly sending to bounced addresses hurts your sender reputation
  • Return HTTP 200 immediately from webhook handlers and process events asynchronously — SendGrid retries webhooks that receive non-200 responses, causing duplicate processing
  • Use SendGrid's Activity Feed for debugging delivery issues — it shows the status of every email sent with timestamps, errors, and detailed delivery logs
  • For high-volume sending (1,000+ emails/day), implement rate limiting on your API route and consider SendGrid's IP warming process for new dedicated IPs

Alternatives

Frequently asked questions

Can I send emails from Bolt.new's WebContainer preview without deploying?

Yes, for outbound email sending. The @sendgrid/mail package makes outbound API calls to SendGrid's servers, which works in Bolt's WebContainer. You can build and test email sending in the preview. The only email feature that requires deployment is SendGrid's Event Webhook, which sends incoming POST requests that the WebContainer cannot receive.

Is SendGrid the same as Twilio SendGrid?

Yes. Twilio acquired SendGrid in 2019 and the product is now officially called Twilio SendGrid. However, it continues to operate as a separate product with its own API, SDK (@sendgrid/mail), dashboard, and pricing. The npm package is @sendgrid/mail and the API endpoint is api.sendgrid.com — not Twilio's API domain.

How do I prevent my SendGrid emails from going to spam?

The most important step is completing Domain Authentication in SendGrid Settings — this adds DKIM, SPF, and DMARC DNS records to your domain, which email providers use to verify sender legitimacy. Also ensure your email content is not spam-like, include a plain text version alongside HTML, add an unsubscribe link for marketing emails, and warm up sending volume gradually for new domains.

How do I use SendGrid dynamic templates in Bolt.new?

Create your template in SendGrid's dashboard (Email API → Dynamic Templates), copy the template ID (starts with d-), and add it as SENDGRID_WELCOME_TEMPLATE_ID in your environment variables. In your API route, pass the templateId and a dynamicTemplateData object with your template's handlebars variables. Bolt.new's API routes handle this server-side using the @sendgrid/mail package.

What is the SendGrid free tier limit?

SendGrid's free tier allows 100 emails per day and 40,000 emails in the first 30 days, with no credit card required. After the first month, the limit drops to 100 emails/day on the free plan. For most small apps and contact forms, this is sufficient. The Essentials plan ($19.95/month) allows 50,000 emails/month.

Can Bolt.new handle SendGrid webhooks for email events like bounces and opens?

Yes, after deployment. SendGrid event webhooks send POST requests to your registered endpoint. In Bolt.new's WebContainer, you can write the webhook handler code and test it manually, but actual webhook delivery from SendGrid requires a publicly accessible URL. Deploy your app to Netlify or Bolt Cloud, register that URL in SendGrid's Event Webhook settings, and webhook events will flow to your handler.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.