All Providers
πŸ“±

Twilio Webhooks

Communications

Twilio sends webhooks for SMS delivery status updates, inbound SMS, voice call events, and messaging failures. Each request is signed with a Twilio signature header.

Twilio Console phone number configuration page showing focused empty Webhook URL field for SMS/voice status callbacks and HTTP method selector (POST/GET).
Twilio dashboard webhook configuration screen β€” schematic showing the empty endpoint URL field, event subscriptions, and primary action button.

Webhook Events

5 event types

message.delivered

SMS was successfully delivered

message.failed

SMS delivery failed

message.received

Inbound SMS received

call.initiated

Voice call was initiated

call.completed

Voice call ended

Signature Verification

Header
X-Twilio-Signature
Method

HMAC-SHA1 of URL + sorted POST params using auth token

View official docs

Sample Payload

message.delivered

application/json
{
  "SmsSid": "SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "SmsStatus": "delivered",
  "MessageStatus": "delivered",
  "To": "+15551234567",
  "From": "+15559876543",
  "MessageSid": "MMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "AccountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "Body": "Your verification code is 123456"
}

Send a Sample Twilio Payload

Pick an event, enter your endpoint URL (or localhost), and fire a realistic Twilio payload with one click β€” no Twilio account needed.

Test Sender

Loading samples…

No signup

Capture & Inspect Twilio Webhooks Live

Get a free public HTTPS endpoint below, point Twilio at it, and watch events arrive in real time. Use the forwarding rule to relay them straight to your local server.

Live demo β€” no signup required

See it work in real time

Click below to get a live webhook URL instantly. Paste it anywhere β€” Stripe, GitHub, Postman β€” and watch events arrive right here.

Expires in 1 hour Β· No account needed

Forward Twilio webhooks to localhost

  1. Click Create live endpoint above to get a public HTTPS URL
  2. Paste the URL into Twilio's webhook settings
  3. In the Forwarding tab, add a rule: target = http://localhost:3000/webhooks/twilio
  4. Fire a test event from Twilio β€” it arrives in the inspector and hits your local handler simultaneously

Ready to test your Twilio webhook handler?

Free HTTPS endpoint with forwarding, retry, and event replay. No install, no CLI, no deploy.

Create Free Account

Common Twilio Webhook Errors

X-Twilio-Signature validation fails

Cause: Twilio builds the signature from the full URL including query params. If your URL behind a proxy strips or modifies the URL, the signature won't match.

Fix: Pass the exact public URL Twilio posted to (not localhost). If behind a reverse proxy, use the X-Forwarded-Proto and X-Forwarded-Host headers to reconstruct it.

Webhook not firing on SMS reply

Cause: The phone number's Messaging webhook URL is not set, or is set to a different URL than expected.

Fix: In Twilio Console β†’ Phone Numbers β†’ your number, check the "A message comes in" webhook URL field. Ensure it's an HTTPS URL.

Getting 11200 HTTP retrieval failure

Cause: Twilio couldn't reach your webhook endpoint β€” SSL certificate issue, timeout, or non-2xx response.

Fix: Use WebhookWhisper as a public proxy to confirm Twilio is sending the request correctly. Check your server logs for 500 errors.

Signature Verification Code

Node.js
const twilio = require('twilio');

app.post('/webhooks/twilio', (req, res) => {
  const authToken = process.env.TWILIO_AUTH_TOKEN;
  const twilioSignature = req.headers['x-twilio-signature'];
  const url = 'https://yourdomain.com/webhooks/twilio';
  const isValid = twilio.validateRequest(authToken, twilioSignature, url, req.body);
  if (!isValid) return res.status(403).send('Forbidden');
  // req.body.Body β€” the SMS message text
  // req.body.From β€” sender phone number
  res.set('Content-Type', 'text/xml');
  res.send('<Response><Message>Got it!</Message></Response>');
});
Python
from twilio.request_validator import RequestValidator
import os

validator = RequestValidator(os.environ['TWILIO_AUTH_TOKEN'])

@app.route('/webhooks/twilio', methods=['POST'])
def twilio_webhook():
    url = 'https://yourdomain.com/webhooks/twilio'
    signature = request.headers.get('X-Twilio-Signature', '')
    if not validator.validate(url, request.form, signature):
        return 'Forbidden', 403
    # request.form['Body'] β€” SMS body
    return '<Response></Response>', 200, {'Content-Type': 'text/xml'}

How to Test Twilio Webhooks with WebhookWhisper

  1. 1

    Create a free WebhookWhisper endpoint

    Click "Create live endpoint" and copy your HTTPS URL.

  2. 2

    Open Twilio Console β†’ Phone Numbers

    Select your Twilio number. Under "Messaging" or "Voice", paste your WebhookWhisper URL in the webhook field.

  3. 3

    Send a test SMS or make a call

    Send an SMS to your Twilio number. The webhook fires immediately and appears in WebhookWhisper.

  4. 4

    Inspect the payload

    See the full POST body: From, To, Body, MessageSid, and all Twilio parameters.

  5. 5

    Forward to localhost

    Add a forwarding rule to relay Twilio events to your local development server.

Twilio Webhook FAQ

Does Twilio use HMAC like Stripe?

Twilio uses a different approach β€” it signs requests using your Auth Token and the full destination URL. Use the official Twilio SDK's validateRequest() helper, not a raw HMAC comparison.

Why does Twilio signature validation fail behind a load balancer?

Twilio signs the exact URL it posts to. Behind a proxy, reconstruct the original URL using X-Forwarded-Proto and X-Forwarded-Host headers before validating.

How do I test Twilio webhooks locally?

Use WebhookWhisper as a relay: point your Twilio number at your WebhookWhisper URL, then forward events to localhost. No ngrok install needed.

What format does Twilio use for webhook payloads?

Unlike most providers, Twilio sends webhook payloads as application/x-www-form-urlencoded (not JSON). Parse req.body as form data, not JSON.