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

How to Integrate Bolt.new with Twilio

To integrate Twilio with Bolt.new, install the twilio npm package (works in WebContainers) and create a Next.js API route that sends SMS using your Account SID and Auth Token from .env. Outbound SMS sending works in the Bolt preview. Incoming SMS webhooks and voice call receiving require a deployed URL — test outbound during development, then deploy to Netlify or Bolt Cloud to test incoming messages and webhooks.

What you'll learn

  • How to set up Twilio credentials and configure a phone number in the Twilio Console
  • How to install the Twilio SDK and send outbound SMS from a Next.js API route in Bolt
  • How to implement Twilio Verify for OTP phone number verification in your app
  • Why incoming SMS and voice webhooks require a deployed URL and how to set them up post-deployment
  • How to send WhatsApp messages using Twilio's WhatsApp Business API
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read20 minutesCommunicationApril 2026RapidDev Engineering Team
TL;DR

To integrate Twilio with Bolt.new, install the twilio npm package (works in WebContainers) and create a Next.js API route that sends SMS using your Account SID and Auth Token from .env. Outbound SMS sending works in the Bolt preview. Incoming SMS webhooks and voice call receiving require a deployed URL — test outbound during development, then deploy to Netlify or Bolt Cloud to test incoming messages and webhooks.

Adding SMS, Voice, and WhatsApp to Bolt.new Apps with Twilio

Twilio is the leading communications API platform, powering SMS notifications, phone number verification, WhatsApp messaging, and voice calls for millions of applications. The Twilio Node.js SDK installs and runs in Bolt's WebContainer without issues — it's pure JavaScript that communicates with Twilio's REST API over HTTPS, perfectly compatible with the WebContainer's networking model.

The key distinction for Bolt development is between outbound and inbound communications. Outbound operations — sending an SMS, initiating a phone call, sending a WhatsApp message — work completely in the Bolt preview. Your API route makes an HTTPS call to Twilio's API, and Twilio handles the delivery to the end recipient. You can test these fully during development without deploying. Inbound operations — receiving an SMS, answering a voice call — require Twilio to call a webhook URL on your server when the message or call arrives. Since Bolt's WebContainer has no public URL (it runs inside a browser tab), Twilio cannot deliver these webhook events during development. Deploy to Netlify or Bolt Cloud first, then configure your Twilio phone number's webhook URL to point to your deployed endpoint.

Twilio Verify is worth highlighting as a separate use case. It provides a managed OTP (one-time password) service for phone number verification — the kind of '6-digit code sent to your phone' flow used in signup and 2FA. Twilio handles the code generation, rate limiting, fraud prevention, and expiry. The sending step works in Bolt's preview; the verification step (checking the code the user entered) is purely server-side and works in both dev and production.

Integration method

Bolt Chat + API Route

The Twilio Node.js SDK works in Bolt's WebContainer for outbound operations (sending SMS, making calls, sending WhatsApp messages). All API calls are routed through a Next.js API route that reads TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN from environment variables, keeping credentials server-side. Receiving incoming SMS or voice calls requires a webhook URL that Twilio can call — this only works after deploying to a real server, not in the Bolt preview.

Prerequisites

  • A Twilio account (free trial includes $15.50 credit, enough for hundreds of test messages)
  • A Twilio phone number purchased or trial number from the Twilio Console
  • Your Twilio Account SID and Auth Token from the Twilio Console dashboard
  • A Bolt.new project using Next.js for server-side API routes
  • For Twilio Verify: a Verify Service SID created in the Twilio Console under Verify → Services

Step-by-step guide

1

Get Twilio Credentials and Configure a Phone Number

Your Twilio integration requires three pieces of information from the Twilio Console: your Account SID (a 34-character string starting with 'AC'), your Auth Token (another 34-character string), and a Twilio phone number that can send SMS. Log into console.twilio.com. On the main dashboard page, your Account SID and Auth Token are displayed (click the eye icon to reveal the Auth Token). Copy both. Next, get a phone number: in the left sidebar, navigate to Phone Numbers → Manage → Buy a Number. Filter by SMS capability and choose a number in your country. Trial accounts get one free number and can only send to verified phone numbers (add your personal number under Phone Numbers → Verified Caller IDs for testing). For Twilio Verify (OTP), go to Verify → Services → Create Service. Give it a name like 'MyApp Verification' and copy the Service SID (starts with 'VA') shown after creation.

Pro tip: On Twilio's trial plan, you can only send messages to phone numbers that you've verified in the Verified Caller IDs section. Verify your personal number immediately so you can test during development.

Expected result: You have your Account SID (AC...), Auth Token, a Twilio phone number in E.164 format (+1XXXXXXXXXX), and optionally a Verify Service SID (VA...) all saved for the next step.

2

Install Twilio SDK and Configure Environment Variables

The twilio npm package is the official Node.js helper library. It's pure JavaScript and works cleanly in Bolt's WebContainer runtime. Prompt Bolt to install it and set up the environment variable structure. Twilio credentials must only be accessed server-side — never in client components. Your Account SID and Auth Token give full control over your Twilio account including sending messages and making calls to any number. In a Next.js project, server-side environment variables (without NEXT_PUBLIC_) are only readable in API routes and server components. The phone number can also be stored as an environment variable so you can change it without touching code — useful when moving from a trial number to a production number.

Bolt.new Prompt

Install the twilio npm package. Create a .env file with TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_PHONE_NUMBER (my Twilio number in +1XXXXXXXXXX format), and TWILIO_VERIFY_SERVICE_SID. Create a lib/twilio.ts utility file that exports an initialized Twilio client.

Paste this in Bolt.new chat

.env
1# .env
2TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3TWILIO_AUTH_TOKEN=your_auth_token_here
4TWILIO_PHONE_NUMBER=+15551234567
5TWILIO_VERIFY_SERVICE_SID=VAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Expected result: The twilio package is in package.json. The .env file has your real Twilio credentials. lib/twilio.ts exports an initialized Twilio REST client.

3

Create the SMS Sending API Route

The SMS API route is the core of your Twilio integration. It receives a phone number and message from your frontend, validates the input, then uses the Twilio client to send the SMS. The route runs server-side in Bolt's WebContainer Node.js process, so it can access environment variables and make outbound HTTPS calls to Twilio's API without CORS restrictions. This outbound SMS sending works fully in the Bolt preview — you can test it immediately without deploying. Important: always validate phone number format before passing to Twilio. Numbers must be in E.164 format (+[country code][number], e.g., +14155552671). The Twilio SDK throws an error if the format is invalid, so a simple regex validation in the route prevents unhelpful error messages.

Bolt.new Prompt

Create a Next.js API route at /api/twilio/send-sms that accepts POST requests with to (phone number) and message (string) in the body. Validate that 'to' matches E.164 format (+[digits]). Use the Twilio client to send an SMS from TWILIO_PHONE_NUMBER to the provided number. Return success with the message SID, or a 400 error for invalid input, or 500 for Twilio errors.

Paste this in Bolt.new chat

app/api/twilio/send-sms/route.ts
1import twilio from 'twilio';
2import { NextResponse } from 'next/server';
3
4const client = twilio(
5 process.env.TWILIO_ACCOUNT_SID,
6 process.env.TWILIO_AUTH_TOKEN
7);
8
9const E164_REGEX = /^\+[1-9]\d{1,14}$/;
10
11export async function POST(request: Request) {
12 try {
13 const { to, message } = await request.json();
14
15 if (!to || !E164_REGEX.test(to)) {
16 return NextResponse.json(
17 { error: 'Invalid phone number. Use E.164 format: +14155552671' },
18 { status: 400 }
19 );
20 }
21
22 if (!message || message.trim().length === 0) {
23 return NextResponse.json(
24 { error: 'Message cannot be empty' },
25 { status: 400 }
26 );
27 }
28
29 const msg = await client.messages.create({
30 body: message,
31 from: process.env.TWILIO_PHONE_NUMBER!,
32 to,
33 });
34
35 return NextResponse.json({ success: true, messageSid: msg.sid });
36 } catch (error: unknown) {
37 const twilioError = error as { message: string; code?: number };
38 return NextResponse.json(
39 { error: twilioError.message, code: twilioError.code },
40 { status: 500 }
41 );
42 }
43}

Pro tip: SMS messages are limited to 160 characters in a single segment. Longer messages are split and billed as multiple messages. Keep notifications concise or use WhatsApp for longer content.

Expected result: POST to /api/twilio/send-sms with a valid phone number and message sends an actual SMS to that number. The response includes a messageSid for tracking delivery status.

4

Add Twilio Verify for OTP Authentication

Twilio Verify provides a managed OTP service that handles the complexity of phone verification: generating secure codes, managing expiry (10 minutes by default), rate limiting (5 attempts per verification), and supporting both SMS and voice delivery. Using Verify instead of building your own OTP system saves significant development time and avoids security mistakes. The flow has two API calls: first, send a verification code to the user's phone number; second, check the code the user entered. Twilio handles everything in between. Verify is separate from basic SMS — it uses a Verify Service (identified by a Service SID starting with 'VA') and has its own pricing ($0.05 per verification, separate from message costs).

Bolt.new Prompt

Create two API routes for phone number verification with Twilio Verify. First, /api/twilio/verify/send (POST) accepts a phoneNumber and calls client.verify.v2.services(TWILIO_VERIFY_SERVICE_SID).verifications.create with channel 'sms'. Second, /api/twilio/verify/check (POST) accepts phoneNumber and code, calls verificationChecks.create to verify, and returns {verified: true} if the code is correct. Add these to a phone verification form component with two steps: phone number input and code input.

Paste this in Bolt.new chat

app/api/twilio/verify/send/route.ts
1// app/api/twilio/verify/send/route.ts
2import twilio from 'twilio';
3import { NextResponse } from 'next/server';
4
5const client = twilio(
6 process.env.TWILIO_ACCOUNT_SID,
7 process.env.TWILIO_AUTH_TOKEN
8);
9
10export async function POST(request: Request) {
11 try {
12 const { phoneNumber } = await request.json();
13
14 const verification = await client.verify.v2
15 .services(process.env.TWILIO_VERIFY_SERVICE_SID!)
16 .verifications.create({ to: phoneNumber, channel: 'sms' });
17
18 return NextResponse.json({ status: verification.status });
19 } catch (error: unknown) {
20 const e = error as { message: string };
21 return NextResponse.json({ error: e.message }, { status: 500 });
22 }
23}
24
25// app/api/twilio/verify/check/route.ts
26export async function POST(request: Request) {
27 try {
28 const { phoneNumber, code } = await request.json();
29
30 const check = await client.verify.v2
31 .services(process.env.TWILIO_VERIFY_SERVICE_SID!)
32 .verificationChecks.create({ to: phoneNumber, code });
33
34 if (check.status === 'approved') {
35 return NextResponse.json({ verified: true });
36 }
37 return NextResponse.json(
38 { verified: false, error: 'Invalid or expired code' },
39 { status: 400 }
40 );
41 } catch (error: unknown) {
42 const e = error as { message: string };
43 return NextResponse.json({ error: e.message }, { status: 500 });
44 }
45}

Pro tip: Twilio Verify's built-in rate limiting allows 5 verification attempts per phone number before it locks the verification. This prevents brute-force attacks on OTP codes automatically.

Expected result: POST to /api/twilio/verify/send with a valid phone number sends a 6-digit code via SMS. POST to /api/twilio/verify/check with the phone number and received code returns {verified: true}. The OTP flow works in the Bolt preview.

5

Deploy and Configure Incoming Message Webhooks

Outbound SMS, WhatsApp, and Twilio Verify all work in the Bolt preview. However, receiving incoming SMS messages (when someone texts your Twilio number) and receiving voice call webhooks requires Twilio to call an HTTP endpoint on your server. Bolt's WebContainer has no public URL — it runs inside a browser tab that Twilio cannot reach. Deploy to Netlify or Bolt Cloud first. After deployment, go to the Twilio Console → Phone Numbers → Manage → Active Numbers → click your number. In the Messaging Configuration section, set the 'A message comes in' webhook URL to your deployed API endpoint (e.g., https://your-app.netlify.app/api/twilio/incoming-sms). Twilio supports HTTP or HTTPS. Always use HTTPS in production. Create the incoming webhook handler route that parses Twilio's webhook body, extracts the sender number and message, and responds with TwiML (Twilio Markup Language) to control the response.

Bolt.new Prompt

Create a webhook handler at /api/twilio/incoming-sms that receives POST requests from Twilio when someone texts my Twilio number. Parse the Twilio webhook fields (From, Body, MessageSid). Save the incoming message to the database with sender, message, and timestamp. Respond with a TwiML XML response confirming receipt: 'Thanks for your message! We'll get back to you soon.' Use the twilio package's twiml MessagingResponse to build the XML response.

Paste this in Bolt.new chat

app/api/twilio/incoming-sms/route.ts
1import { NextResponse } from 'next/server';
2import twilio from 'twilio';
3
4export async function POST(request: Request) {
5 const formData = await request.formData();
6 const from = formData.get('From') as string;
7 const body = formData.get('Body') as string;
8 const messageSid = formData.get('MessageSid') as string;
9
10 console.log(`Incoming SMS from ${from}: ${body}`);
11 // Save to database here...
12
13 // Respond with TwiML
14 const twiml = new twilio.twiml.MessagingResponse();
15 twiml.message('Thanks for your message! We will get back to you soon.');
16
17 return new Response(twiml.toString(), {
18 headers: { 'Content-Type': 'text/xml' },
19 });
20}

Pro tip: Twilio sends webhook data as application/x-www-form-urlencoded, not JSON. Use request.formData() to parse the body correctly — JSON.parse will fail.

Expected result: After deployment and webhook configuration, text messages sent to your Twilio number arrive at your webhook handler. Senders receive an automatic reply. Incoming messages are saved to your database.

Common use cases

Order Confirmation SMS Notifications

Send automated SMS confirmations when users complete purchases, bookings, or form submissions. The SMS contains order details, tracking links, or confirmation numbers. Sending is outbound-only, so it works perfectly in Bolt's preview environment during development.

Bolt.new Prompt

When a user completes a purchase, send them an SMS confirmation. Create an API route at /api/send-sms that accepts a to phone number (E.164 format) and a message string, then sends an SMS using the Twilio SDK with TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, and TWILIO_PHONE_NUMBER from environment variables. Call this route from the checkout success handler with the message 'Your order #[orderId] is confirmed! Estimated delivery: [date]. Track at: [link]'.

Copy this prompt to try it in Bolt.new

Phone Number OTP Verification

Add phone number verification to your signup flow using Twilio Verify. Users enter their phone number, receive a 6-digit SMS code, and enter it to verify ownership. Twilio handles code generation, expiry (10 minutes), and rate limiting to prevent abuse.

Bolt.new Prompt

Add phone number verification to my signup form using Twilio Verify. Create two API routes: /api/verify/send (sends a verification code to the phone number using Twilio Verify service SID from TWILIO_VERIFY_SERVICE_SID) and /api/verify/check (verifies the code the user entered). Add a two-step UI: first step shows phone number input with 'Send Code' button, second step shows a 6-digit code input with 'Verify' button. Show countdown timer (10 minutes) and 'Resend Code' option.

Copy this prompt to try it in Bolt.new

WhatsApp Customer Notifications

Send WhatsApp messages to customers who prefer WhatsApp over SMS. Twilio's WhatsApp Business API uses the same SDK as SMS but with a 'whatsapp:' prefix on phone numbers. During development, use Twilio's WhatsApp Sandbox for testing without business approval.

Bolt.new Prompt

Add WhatsApp messaging to my notification system. Create an API route at /api/send-whatsapp that accepts a to phone number and message, then sends a WhatsApp message using the Twilio SDK with 'whatsapp:' prefix on both the to and from numbers. Use TWILIO_WHATSAPP_NUMBER for the sandbox number. Add a toggle in the notification settings for users to choose SMS or WhatsApp delivery preference.

Copy this prompt to try it in Bolt.new

Troubleshooting

SMS not received — Twilio returns success but message never arrives

Cause: On Twilio trial accounts, you can only send to verified phone numbers. Unverified numbers silently succeed on the API but the message is not delivered.

Solution: Go to Twilio Console → Phone Numbers → Verified Caller IDs. Add and verify your test phone numbers. Once verified, messages to those numbers will deliver. This restriction is removed when you upgrade from a trial account.

API route throws 'Authentication Error - No credentials provided' or 401

Cause: TWILIO_ACCOUNT_SID or TWILIO_AUTH_TOKEN environment variables are missing, misspelled, or the .env file hasn't been reloaded.

Solution: Verify both variables are in your .env file without quotes around the values. Account SID starts with 'AC'. The Auth Token is 32 characters of alphanumeric. Restart the Bolt dev server after editing .env since Next.js caches env vars at startup.

typescript
1// In lib/twilio.ts — add validation:
2if (!process.env.TWILIO_ACCOUNT_SID || !process.env.TWILIO_AUTH_TOKEN) {
3 throw new Error('Missing TWILIO_ACCOUNT_SID or TWILIO_AUTH_TOKEN in environment');
4}

Incoming webhook returns 403 or Twilio keeps retrying the webhook

Cause: Twilio expects a 200 status response from webhook handlers within 15 seconds. If your handler throws an error or takes too long, Twilio retries the webhook up to 3 times.

Solution: Ensure your webhook handler always returns a 200 response, even if processing fails. Respond immediately with the TwiML response, then handle business logic (database writes) asynchronously. If signature validation is enabled, verify the X-Twilio-Signature header is checked correctly.

Incoming webhooks never arrive during development in Bolt preview

Cause: This is a fundamental WebContainer limitation. Bolt's runtime runs inside a browser tab with no publicly accessible URL. Twilio cannot make outbound HTTP calls to your WebContainer.

Solution: Deploy to Netlify or Bolt Cloud first, then configure your Twilio phone number's webhook URL to point to your deployed endpoint. For local development outside Bolt (in VS Code), you could use ngrok to create a temporary public tunnel, but this isn't available within Bolt's WebContainer environment.

Best practices

  • Store TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN only as server-side environment variables (no NEXT_PUBLIC_ prefix) — these credentials control your entire Twilio account
  • Validate phone number format (E.164: +[country code][number]) before sending to Twilio — invalid formats cause cryptic errors and wasted API calls
  • Always respond quickly to incoming webhooks (within 15 seconds) with a 200 status — do heavy processing asynchronously after responding to prevent Twilio retry storms
  • Use Twilio Verify for OTP instead of building your own code generation — it handles rate limiting, expiry, fraud prevention, and multi-channel delivery out of the box
  • Keep SMS messages under 160 characters to send as a single segment and minimize costs — Twilio charges per segment, not per message
  • Test outbound SMS thoroughly in the Bolt preview before deploying, but plan from the start to deploy early for testing incoming message flows
  • Use Twilio's messaging webhooks to track delivery status (delivered, failed, undelivered) and surface delivery failures to your users rather than showing false success

Alternatives

Frequently asked questions

Does the Twilio SDK work in Bolt's WebContainer?

Yes. The Twilio Node.js SDK is pure JavaScript and communicates with Twilio's REST API over HTTPS. It installs and runs in Bolt's WebContainer without issues. Outbound operations (sending SMS, WhatsApp, initiating calls) work fully in the Bolt preview. The limitation is incoming operations — receiving SMS, voice calls, and webhooks require a publicly accessible URL that the WebContainer cannot provide.

Can I test SMS sending without a real phone number?

Twilio provides test credentials (separate from your real Account SID/Auth Token, found under Account → API keys & tokens → Test credentials) that simulate API calls without sending real messages or charging your account. Use test phone numbers like +15005550006 (valid number) for simulated success. Switch to real credentials when you're ready to send actual messages to your verified phone number.

How much does Twilio cost for SMS?

SMS pricing varies by country. In the US, sending costs $0.0079 per message and receiving is $0.0075 per message. Phone numbers cost $1/month each. Twilio's trial account includes $15.50 in credit — enough for nearly 2,000 US messages. Twilio Verify costs $0.05 per verification check (not per code send, but per verification attempt).

Why can't I receive SMS in the Bolt.new preview?

Receiving SMS requires Twilio to call a webhook URL on your server when a message arrives. Bolt's WebContainer runs inside a browser tab and has no publicly accessible IP address or URL that Twilio can reach. This is a fundamental limitation of the browser-based runtime. To receive SMS, deploy your app to Netlify or Bolt Cloud, then configure your Twilio phone number's webhook URL to point to your deployed API endpoint.

How do I use WhatsApp with Twilio in Bolt.new?

For WhatsApp, use Twilio's WhatsApp Sandbox during development (go to Messaging → Try it Out → Send a WhatsApp Message in the Twilio Console). The sandbox lets you test without business approval. In your API route, add 'whatsapp:' prefix to both the from and to numbers: from: 'whatsapp:+14155238886' (sandbox number) and to: 'whatsapp:+[user's number]'. Production WhatsApp requires approval from Twilio and Meta, which takes 1-3 business days.

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.