To integrate Replit with Twilio, store your Account SID, Auth Token, and Twilio phone number in Replit Secrets (lock icon π), install the Twilio helper library, and call the Messages API to send SMS. For receiving SMS and phone calls, Twilio delivers webhooks to your deployed app URL β development mode Repls go offline when your browser closes, so use Autoscale or Reserved VM deployment for any webhook receiver.
SMS, Voice, and WhatsApp for Replit Apps with Twilio
Twilio turns phone communication into programmable API calls. From a Replit application, you can send an SMS to any phone number in the world with a few lines of code, trigger automated voice calls, send WhatsApp messages, and build interactive IVR (Interactive Voice Response) menus β all through Twilio's REST API. This powers use cases from simple order confirmation texts to full two-way SMS chatbots and phone verification systems.
The Twilio integration has two directions. Sending is straightforward: call Twilio's Messages or Calls API with your credentials, and Twilio delivers the communication. Receiving is slightly more complex: you configure a Twilio phone number to call a webhook URL on your Replit server whenever an incoming SMS or call arrives. Your server processes the event and responds with TwiML (an XML-based language Twilio understands) to control what happens next β forward the call, play a message, send a reply SMS, or branch based on the caller's input.
For production reliability, Twilio webhook delivery requires your Replit app to be deployed (not just running in development mode). Development Repls sleep when you close your browser, causing webhook delivery failures that Twilio will retry with exponential backoff. An Autoscale deployment keeps your webhook endpoint live 24/7 and handles the cold start delay gracefully since Twilio's retry logic accommodates brief response delays.
Integration method
Twilio integrates with Replit through Twilio's official REST API clients for Node.js and Python. Your Replit server uses the Twilio helper library to send outbound SMS, MMS, and WhatsApp messages, or make voice calls. For inbound messages and calls, Twilio sends HTTP POST webhooks to a URL you configure β this URL must be your deployed Replit app URL (not a development URL) to receive webhooks reliably when the Twilio event occurs. Twilio expects your webhook endpoint to respond with TwiML (Twilio Markup Language) to control what happens next in a call or message flow.
Prerequisites
- A Replit account with a Node.js or Python Repl ready
- A Twilio account β free trial includes $15.50 in credits and a trial phone number
- A verified phone number to receive test SMS (Twilio trial accounts can only send to verified numbers)
- For webhook receiver: your app deployed with a stable URL (https://yourapp.replit.app)
Step-by-step guide
Get Your Twilio Credentials and Store Them in Replit Secrets
Get Your Twilio Credentials and Store Them in Replit Secrets
Twilio authenticates API requests using your Account SID and Auth Token β two credentials that appear on your Twilio Console dashboard. The Auth Token is functionally a password: anyone with it can make API calls billed to your account. It must live in Replit Secrets, never in code. Log into your Twilio Console at console.twilio.com. On the main dashboard, you will see your Account SID (starts with AC...) and Auth Token (click the eye icon to reveal). Copy both. To send SMS, you also need a Twilio phone number. If you are on a trial account, Twilio provides a free trial phone number. Go to Phone Numbers β Manage β Active Numbers to see it. The number is in E.164 format: +15551234567. Open your Repl and click the lock icon (π) in the left sidebar. Add three secrets: TWILIO_ACCOUNT_SID: your Account SID (the AC... string). TWILIO_AUTH_TOKEN: your Auth Token. TWILIO_PHONE_NUMBER: your Twilio phone number in E.164 format (+15551234567). For webhook signature verification (covered in Step 4), also add TWILIO_AUTH_TOKEN as a separate check β it doubles as the signing secret for request verification. With these three secrets configured, your code can authenticate to Twilio and specify which number to send from without any credentials in source files.
1// Verify Twilio secrets at startup2const required = ['TWILIO_ACCOUNT_SID', 'TWILIO_AUTH_TOKEN', 'TWILIO_PHONE_NUMBER'];3for (const key of required) {4 if (!process.env[key]) {5 throw new Error(`Missing secret: ${key}. Add it in Replit Secrets (lock icon π).`);6 }7}8// Quick sanity checks9if (!process.env.TWILIO_ACCOUNT_SID.startsWith('AC')) {10 throw new Error('TWILIO_ACCOUNT_SID should start with AC');11}12if (!process.env.TWILIO_PHONE_NUMBER.startsWith('+')) {13 throw new Error('TWILIO_PHONE_NUMBER must be in E.164 format, e.g., +15551234567');14}15console.log('Twilio credentials verified.');Pro tip: Twilio trial accounts can only send SMS to phone numbers you have verified in the Twilio Console under 'Verified Caller IDs'. When testing, add your personal phone number there first. This restriction is lifted when you upgrade to a paid account.
Expected result: All three Twilio secrets appear in the Replit Secrets pane. The verification script runs without errors and prints 'Twilio credentials verified.'
Send SMS and MMS with Node.js
Send SMS and MMS with Node.js
The Twilio Node.js helper library wraps the REST API into a clean JavaScript interface. Install it with npm install twilio in Shell. Initialize the client with your Account SID and Auth Token from environment variables, then call client.messages.create() to send a message. The create() method accepts a 'from' number (your Twilio number), a 'to' number (the recipient in E.164 format), and either 'body' for SMS or 'mediaUrl' for MMS. MMS can include images, GIFs, and audio files β provide an array of publicly accessible URLs for the media. Note that MMS is only available for US and Canadian numbers; international messages are SMS-only. For WhatsApp messages, use the same create() method but prefix both numbers with 'whatsapp:' β for example, from: 'whatsapp:+14155238886' (Twilio's WhatsApp sandbox number for testing) and to: 'whatsapp:+15551234567'. WhatsApp requires recipients to opt in via the sandbox first before receiving test messages. The create() call is asynchronous and returns a message object with a 'sid' (unique message identifier), 'status' (queued, sent, delivered), and 'errorCode' if the delivery failed. Store the SID if you need to track delivery status later via webhooks.
1// twilio-send.js β Send SMS, MMS, and WhatsApp from Replit2const twilio = require('twilio');34const client = twilio(5 process.env.TWILIO_ACCOUNT_SID,6 process.env.TWILIO_AUTH_TOKEN7);89const FROM_NUMBER = process.env.TWILIO_PHONE_NUMBER;1011// Send a simple SMS12async function sendSMS(to, message) {13 const result = await client.messages.create({14 from: FROM_NUMBER,15 to: to, // E.164 format: +1555123456716 body: message17 });18 console.log(`SMS sent: ${result.sid} (status: ${result.status})`);19 return result.sid;20}2122// Send an MMS with an image (US/Canada only)23async function sendMMS(to, message, imageUrl) {24 const result = await client.messages.create({25 from: FROM_NUMBER,26 to: to,27 body: message,28 mediaUrl: [imageUrl] // Must be a publicly accessible URL29 });30 return result.sid;31}3233// Send a WhatsApp message34async function sendWhatsApp(to, message) {35 const result = await client.messages.create({36 from: `whatsapp:${FROM_NUMBER}`,37 to: `whatsapp:${to}`,38 body: message39 });40 return result.sid;41}4243// Check message delivery status44async function getMessageStatus(messageSid) {45 const message = await client.messages(messageSid).fetch();46 return {47 sid: message.sid,48 status: message.status, // queued, sent, delivered, failed49 errorCode: message.errorCode,50 errorMessage: message.errorMessage51 };52}5354// Example usage55(async () => {56 try {57 // Replace with a verified number on Twilio trial accounts58 const sid = await sendSMS('+15559876543', 'Hello from Replit + Twilio!');59 console.log('Message SID:', sid);60 61 // Check delivery after a moment62 setTimeout(async () => {63 const status = await getMessageStatus(sid);64 console.log('Delivery status:', status);65 }, 3000);66 } catch (err) {67 console.error('Twilio error:', err.message);68 console.error('Error code:', err.code);69 }70})();Pro tip: Twilio uses E.164 phone number format for all API calls: a + followed by country code and local number with no spaces, dashes, or parentheses. For US numbers: +1 followed by the 10-digit number. Always validate and normalize phone numbers before passing them to the Twilio API.
Expected result: Running node twilio-send.js sends an SMS to your test number. The console shows the message SID (starts with SM...) and initial status 'queued'. The status changes to 'sent' and then 'delivered' within a few seconds.
Send SMS with Python (Twilio SDK)
Send SMS with Python (Twilio SDK)
For Python Replit projects, the Twilio Python helper library provides the same capabilities as the Node.js version. Install it with pip install twilio in Shell. The Python client mirrors the Node.js API structure: create a Client instance with your credentials, call client.messages.create() to send. The Python library is synchronous by default β for async FastAPI or asyncio applications, run the Twilio calls in a thread pool executor using asyncio.get_event_loop().run_in_executor() to avoid blocking the event loop. Error handling in Python uses Twilio's TwilioRestException, which includes a code attribute (numeric error code, e.g., 21211 for invalid 'To' phone number) and a msg attribute with a description. Catching this exception lets you distinguish Twilio errors from network errors and respond appropriately. For Flask applications, you can use the sendSMS function below directly in route handlers. For background tasks like appointment reminders, call it from a scheduled function or background thread that runs periodically.
1# twilio_client.py β Twilio SMS and MMS with Python on Replit2import os3from twilio.rest import Client4from twilio.base.exceptions import TwilioRestException56client = Client(7 os.environ['TWILIO_ACCOUNT_SID'],8 os.environ['TWILIO_AUTH_TOKEN']9)10FROM_NUMBER = os.environ['TWILIO_PHONE_NUMBER']1112def send_sms(to: str, message: str) -> str:13 """Send an SMS and return the message SID."""14 try:15 result = client.messages.create(16 from_=FROM_NUMBER,17 to=to,18 body=message19 )20 print(f'SMS sent: {result.sid} (status: {result.status})')21 return result.sid22 except TwilioRestException as e:23 print(f'Twilio error {e.code}: {e.msg}')24 raise2526def send_mms(to: str, message: str, media_url: str) -> str:27 """Send an MMS with an image (US/Canada numbers only)."""28 result = client.messages.create(29 from_=FROM_NUMBER,30 to=to,31 body=message,32 media_url=[media_url] # Must be a publicly accessible URL33 )34 return result.sid3536def send_whatsapp(to: str, message: str) -> str:37 """Send a WhatsApp message via Twilio."""38 result = client.messages.create(39 from_=f'whatsapp:{FROM_NUMBER}',40 to=f'whatsapp:{to}',41 body=message42 )43 return result.sid4445def get_message_status(message_sid: str) -> dict:46 """Fetch current delivery status for a message."""47 message = client.messages(message_sid).fetch()48 return {49 'sid': message.sid,50 'status': message.status,51 'error_code': message.error_code,52 'error_message': message.error_message53 }5455# Usage56if __name__ == '__main__':57 sid = send_sms('+15559876543', 'Hello from Replit + Twilio (Python)!')58 print(f'Message SID: {sid}')Pro tip: The Python Twilio client parameter is from_ (with underscore), not from β 'from' is a Python reserved keyword. This is a common source of SyntaxError for Python developers new to Twilio.
Expected result: Running python twilio_client.py sends an SMS and prints the message SID. The message arrives on the recipient's phone within a few seconds.
Receive Incoming SMS with a Webhook Handler
Receive Incoming SMS with a Webhook Handler
To receive incoming SMS messages, you need to configure your Twilio phone number to call a webhook URL whenever a message arrives. Twilio sends an HTTP POST to your URL with details about the message: the sender's number, the message body, any media URLs for MMS, and metadata. Your server must respond with TwiML (Twilio Markup Language) β XML that tells Twilio what to do next. For SMS responses, the TwiML <Message> verb sends a reply. For voice calls, TwiML controls the call flow (play audio, gather digits, forward to another number, etc.). Important deployment note: your webhook endpoint must be on a deployed Replit URL (https://yourapp.replit.app/sms), not a development URL. Development Repls go offline when you close your browser, causing webhook delivery failures. Twilio retries failed webhooks with exponential backoff, but during sleep periods all retries will fail. After deploying, configure the webhook: in Twilio Console β Phone Numbers β Manage β Active Numbers β click your number. Under 'Messaging', set the webhook URL for 'A message comes in' to https://yourapp.replit.app/sms and set the method to HTTP POST. Save. For security, verify Twilio's request signature on all incoming webhooks to prevent attackers from sending fake Twilio requests to your endpoint. The Twilio SDK includes a validate_request / validateRequest helper for this.
1// webhook-server.js β Receive and respond to Twilio SMS webhooks2const express = require('express');3const twilio = require('twilio');4const { MessagingResponse } = require('twilio').twiml;56const app = express();7// Parse URL-encoded bodies (Twilio sends form data, not JSON)8app.use(express.urlencoded({ extended: false }));9app.use(express.json());1011const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);1213// Validate Twilio request signature (prevents spoofed webhook requests)14function validateTwilioSignature(req, res, next) {15 const authToken = process.env.TWILIO_AUTH_TOKEN;16 const signature = req.headers['x-twilio-signature'];17 // Full URL including protocol and host18 const url = `${req.protocol}://${req.get('host')}${req.originalUrl}`;19 20 const isValid = twilio.validateRequest(authToken, signature, url, req.body);21 if (!isValid) {22 return res.status(403).send('Invalid Twilio signature');23 }24 next();25}2627// Incoming SMS webhook β Twilio POSTs here when your number receives an SMS28app.post('/sms', validateTwilioSignature, (req, res) => {29 const { From, Body, To, NumMedia } = req.body;30 31 console.log(`Incoming SMS from ${From}: ${Body}`);32 33 // Build a TwiML response34 const twiml = new MessagingResponse();35 36 // Simple keyword-based auto-responder37 const message = Body.trim().toUpperCase();38 if (message === 'HELP') {39 twiml.message('Available commands: STATUS, STOP, HELP');40 } else if (message === 'STATUS') {41 twiml.message('All systems operational. Reply HELP for options.');42 } else if (message === 'STOP') {43 // Twilio handles STOP automatically for opt-out compliance44 twiml.message('You have been unsubscribed. Reply START to resubscribe.');45 } else {46 twiml.message(`Thanks for your message: "${Body}". Reply HELP for options.`);47 }48 49 res.type('text/xml');50 res.send(twiml.toString());51});5253// Incoming voice call webhook54app.post('/voice', (req, res) => {55 const { VoiceResponse } = require('twilio').twiml;56 const twiml = new VoiceResponse();57 twiml.say('Hello! You have reached a Replit application. Goodbye.');58 twiml.hangup();59 res.type('text/xml');60 res.send(twiml.toString());61});6263app.listen(3000, '0.0.0.0', () => {64 console.log('Twilio webhook server running on port 3000');65 console.log('Configure Twilio phone number webhook to: https://yourapp.replit.app/sms');66});Pro tip: Twilio sends webhook POST data as application/x-www-form-urlencoded (form data), not JSON. Make sure to use express.urlencoded() middleware, not express.json(), to parse the incoming request body.
Expected result: The webhook server starts on port 3000. After deploying and configuring the webhook URL in Twilio Console, texting your Twilio number triggers the /sms route and you receive the auto-reply on your phone.
Receive SMS Webhooks with Python (Flask)
Receive SMS Webhooks with Python (Flask)
The Python webhook implementation follows the same pattern as Node.js: parse the incoming form data, read the message body and sender number, build a TwiML response using Twilio's Python helpers, and return it as text/xml. The Flask route uses request.form to access Twilio's POST parameters. The key fields are From (sender's phone number), Body (message content), To (your Twilio number), and NumMedia (count of attached media files, 0 for plain SMS). The twilio.request_validator.RequestValidator class handles signature verification in Python. Pass it your Auth Token and call is_valid_request() with the URL, POST data, and the X-Twilio-Signature header. Always use the full URL including protocol and port as Twilio sees it β the host must match exactly what Twilio sends the request to. For production Python deployments on Replit, gunicorn is recommended over Flask's built-in development server. Install it with pip install gunicorn and set the run command in .replit to gunicorn app:app --bind 0.0.0.0:3000.
1# webhook_server.py β Twilio SMS webhook receiver with Flask on Replit2from flask import Flask, request, Response3from twilio.twiml.messaging_response import MessagingResponse4from twilio.request_validator import RequestValidator5import os67app = Flask(__name__)8validator = RequestValidator(os.environ['TWILIO_AUTH_TOKEN'])910def validate_twilio_request(f):11 """Decorator to validate Twilio webhook signatures."""12 from functools import wraps13 @wraps(f)14 def decorated_function(*args, **kwargs):15 url = request.url16 post_data = request.form17 signature = request.headers.get('X-Twilio-Signature', '')18 if not validator.validate(url, post_data, signature):19 return Response('Invalid Twilio signature', status=403)20 return f(*args, **kwargs)21 return decorated_function2223@app.route('/sms', methods=['POST'])24@validate_twilio_request25def incoming_sms():26 from_number = request.form.get('From')27 body = request.form.get('Body', '').strip().upper()28 num_media = int(request.form.get('NumMedia', 0))29 30 print(f'Incoming SMS from {from_number}: {body}')31 32 twiml = MessagingResponse()33 34 if body == 'HELP':35 twiml.message('Available commands: STATUS, STOP, HELP')36 elif body == 'STATUS':37 twiml.message('All systems operational. Reply HELP for options.')38 elif num_media > 0:39 # Received an MMS with media40 media_url = request.form.get('MediaUrl0', '')41 twiml.message(f'Got your image! URL: {media_url[:50]}...')42 else:43 twiml.message(f'Thanks! You said: "{request.form.get("Body")}". Reply HELP for options.')44 45 return Response(str(twiml), mimetype='text/xml')4647@app.route('/voice', methods=['POST'])48def incoming_call():49 from twilio.twiml.voice_response import VoiceResponse50 twiml = VoiceResponse()51 twiml.say('Hello! You have reached a Replit application. Goodbye.')52 twiml.hangup()53 return Response(str(twiml), mimetype='text/xml')5455if __name__ == '__main__':56 app.run(host='0.0.0.0', port=3000)Pro tip: Flask's request.url may not match what Twilio used if your app is behind Replit's proxy. If signature validation fails unexpectedly, try constructing the URL manually using request.host_url + request.path, or temporarily log both values to debug the mismatch.
Expected result: The Flask server starts on port 3000. After deploying and updating the Twilio webhook URL, incoming texts to your Twilio number trigger the route and you receive auto-replies within seconds.
Common use cases
Order and Appointment Confirmation SMS
Automatically send SMS confirmations when users complete an action β place an order, book an appointment, or register for an event. The message is triggered from your backend when the database record is created, ensuring reliable delivery independent of email open rates.
Build an order confirmation system that sends an SMS to the customer's phone number after a successful purchase, including the order ID, total amount, and estimated delivery date.
Copy this prompt to try it in Replit
Two-Factor Authentication via SMS
Send one-time verification codes via SMS during signup or sensitive actions like password resets. Generate a random 6-digit code, store it temporarily in your database with an expiry time, send it via Twilio, and verify the user-provided code against the stored value.
Create an SMS two-factor authentication flow that generates a 6-digit OTP, sends it via Twilio to the user's phone, and verifies the submitted code against the stored value with a 5-minute expiry.
Copy this prompt to try it in Replit
Inbound SMS Command Bot
Build a Twilio webhook receiver that processes incoming SMS messages and responds based on keywords. Users text a phone number with commands like STATUS, HELP, or STOP, and your Replit server queries your database and replies with the relevant information automatically.
Create an SMS bot that receives incoming texts to a Twilio number, parses keywords (STATUS, ACCOUNT, HELP), queries the database for the user associated with the sender's phone number, and replies with TwiML.
Copy this prompt to try it in Replit
Troubleshooting
Twilio error 21211: Invalid 'To' phone number or 21614: 'To' number is not a mobile number
Cause: The recipient phone number is not in E.164 format, contains formatting characters (dashes, spaces, parentheses), or is a landline number that cannot receive SMS. On trial accounts, error 21608 means the recipient number has not been verified in Twilio Console.
Solution: Ensure the 'to' parameter is in E.164 format: a + followed by the country code and number with no spaces or dashes (e.g., +15551234567 not 555-123-4567). For trial accounts, add the recipient number to Verified Caller IDs in Twilio Console under Phone Numbers β Verified Caller IDs.
1// Normalize phone numbers to E.164 format before sending2function normalizePhone(phone) {3 // Remove all non-digit characters except leading +4 const cleaned = phone.replace(/[^\d+]/g, '');5 // Add + if missing for US numbers6 if (!cleaned.startsWith('+') && cleaned.length === 10) {7 return '+1' + cleaned; // Assume US number8 }9 return cleaned.startsWith('+') ? cleaned : '+' + cleaned;10}1112console.log(normalizePhone('555-123-4567')); // +1555123456713console.log(normalizePhone('+44 20 1234 5678')); // +442012345678Webhook not receiving messages β Twilio shows 'Error 11200: HTTP retrieval failure' in the error logs
Cause: Twilio cannot reach your webhook URL. Most common causes: your Replit app is in development mode (not deployed) and has gone to sleep, the URL is incorrect, or your server crashed and is not responding.
Solution: Deploy your app using Autoscale or Reserved VM to get a stable always-on URL. Verify the webhook URL in Twilio Console β Phone Numbers β your number β Messaging is set to https://yourapp.replit.app/sms (not a development URL). Test the URL is reachable by visiting it in a browser or using curl.
403 Forbidden response on webhook endpoint / signature validation always fails
Cause: The URL used for signature verification does not match the URL Twilio sends the webhook to. This happens when Replit's proxy adds or changes the protocol, port, or host, causing the computed signature to differ from Twilio's signature.
Solution: Log req.url and req.headers['host'] to see what your server receives. Temporarily disable signature validation to confirm the webhook itself works, then debug the URL mismatch. For Replit deployments, the URL should be https://yourapp.replit.app/sms β ensure no port number or trailing slash is included, and that req.protocol returns 'https' not 'http' (add app.set('trust proxy', 1) if needed).
1// Debug: log the URL your server constructs vs what Twilio sent2app.post('/sms', (req, res) => {3 const url = `${req.protocol}://${req.get('host')}${req.originalUrl}`;4 console.log('Computed URL for validation:', url);5 console.log('X-Twilio-Signature:', req.headers['x-twilio-signature']);6 // Compare this URL with what you registered in Twilio Console7});Twilio error 20003: Authentication Failed / 20009: Invalid credentials
Cause: TWILIO_ACCOUNT_SID or TWILIO_AUTH_TOKEN in Replit Secrets is incorrect, has extra whitespace, or was recently rotated in the Twilio Console. Auth tokens can be rotated in Twilio for security purposes, which invalidates the old token.
Solution: In Twilio Console main page, verify your Account SID starts with AC and matches TWILIO_ACCOUNT_SID in Replit Secrets. Click the eye icon to reveal and copy the Auth Token, then update TWILIO_AUTH_TOKEN in Replit Secrets. After updating a secret, redeploy for the deployed app to pick up the new value.
Best practices
- Store TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, and TWILIO_PHONE_NUMBER in Replit Secrets (lock icon π) β the Auth Token is equivalent to a password for your Twilio account
- Always validate Twilio webhook signatures using the validateRequest / RequestValidator helper to prevent spoofed requests from non-Twilio sources
- Deploy as Autoscale or Reserved VM so your webhook endpoint is available 24/7 β development mode Repls go offline when you close your browser, causing missed incoming messages
- Use E.164 phone number format for all Twilio API calls β normalize and validate numbers before sending to avoid 21211 errors
- Handle TwilioRestException specifically in your error handlers to distinguish Twilio errors (wrong number, trial restrictions) from network errors
- Respond to webhooks with TwiML immediately (within 15 seconds) rather than doing slow operations inline β use the response_url pattern for async processing
- Store message SIDs in your database when sending SMS so you can track delivery status via status callbacks and debug failed messages
- For production SMS at scale, implement Twilio's messaging service (not just individual phone numbers) to enable automatic number pool scaling and improved deliverability
Alternatives
Vonage offers competitive SMS pricing in Europe and has a similar programmable messaging API, making it worth comparing for internationally-focused applications with heavy European traffic.
Bandwidth is a direct carrier with lower per-message costs at high volume but requires higher technical investment and longer setup time than Twilio's developer-friendly API.
SendGrid handles transactional email rather than SMS β use it alongside Twilio when your application needs both email and text message notifications.
Frequently asked questions
How do I store my Twilio credentials securely in Replit?
Click the lock icon (π) in the Replit sidebar to open the Secrets pane. Add TWILIO_ACCOUNT_SID (your Account SID starting with AC), TWILIO_AUTH_TOKEN (your Auth Token), and TWILIO_PHONE_NUMBER (your Twilio number in E.164 format like +15551234567). Access them in code with process.env.TWILIO_ACCOUNT_SID (Node.js) or os.environ['TWILIO_ACCOUNT_SID'] (Python). Never hardcode them in source files.
Why is my Twilio webhook not receiving messages on Replit?
The most common cause is that your Replit app is in development mode and has gone to sleep β development Repls only run while your browser tab is open. Deploy your app using Autoscale or Reserved VM to get a stable always-on URL. Then update the webhook URL in Twilio Console β Phone Numbers β your number to use https://yourapp.replit.app/sms (your deployment URL, not a development URL).
Can I use Twilio for free with Replit?
Twilio's free trial gives you $15.50 in credit, which covers about 150 SMS messages (US domestic SMS is roughly $0.0079 each) plus the trial phone number. Trial accounts can only send to phone numbers you have verified in the Twilio Console. There is no ongoing free tier β once your trial credit is exhausted, you need to add payment information. Monthly costs for low-volume apps typically run $1-10.
How do I send a WhatsApp message from Replit using Twilio?
Use the same Twilio messages.create() method but prefix both phone numbers with 'whatsapp:'. For testing, use Twilio's WhatsApp Sandbox (sandbox number: +14155238886) and have recipients send 'join [your-sandbox-keyword]' to the sandbox number first to opt in. For production, apply for a Twilio WhatsApp business profile. The Node.js call is: from: 'whatsapp:+14155238886', to: 'whatsapp:+1XXXXXXXXXX'.
What is TwiML and do I need it for sending SMS?
TwiML (Twilio Markup Language) is XML that Twilio reads from your webhook responses to control what happens next in a communication flow. You need TwiML only when receiving inbound calls or SMS β your webhook response tells Twilio how to reply. For outbound SMS (sending messages programmatically), you do not write TwiML; you just call the Twilio API.
What Replit deployment type should I use for a Twilio integration?
Autoscale works well for most Twilio webhook receivers since Twilio retries failed delivery attempts with backoff. The cold start on Autoscale (1-3 seconds) is usually within Twilio's retry window. Use Reserved VM if your app handles voice calls with Gather (digit input collection), where latency matters more, or if you have strict SLA requirements for message delivery acknowledgment.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation