Webhook Guide
Twilio Webhook Testing Guides
SMS/voice callback webhooks
Quick path: CLI helper commands
Use these first to avoid setup mistakes, then follow the full provider steps below.
instatunnel webhook init --provider twilio --port 3000 --path /webhooks/twilio/sms
instatunnel webhook verify --provider twilio --secret-env TWILIO_AUTH_TOKEN
instatunnel webhook test --provider twilio
If you run into provider-specific issues, use the full checklist sections below.
For cross-provider MCP + webhook diagnostics, open /docs/troubleshooting.
Replay + signature helper
Open /dashboard or /dashboard/tunnels and use Webhook Command Center for this provider. It gives one-click replay and signature verification helpers.
instatunnel webhook verify --provider twilio --secret-env TWILIO_AUTH_TOKEN
curl -i -X POST "https://YOUR-SUBDOMAIN.instatunnel.my/webhooks/twilio/sms" -H "Content-Type: application/json" --data-binary @sample-twilio.json
Required signature header: x-twilio-signature
1. Local app setup
Create a local webhook endpoint at: /webhooks/twilio/sms
import express from 'express'
import twilio from 'twilio'
const app = express()
app.use(express.urlencoded({ extended: false }))
app.post('/webhooks/twilio/sms', (req, res) => {
const signature = req.header('x-twilio-signature') || ''
const url = process.env.PUBLIC_WEBHOOK_URL!
const valid = twilio.validateRequest(
process.env.TWILIO_AUTH_TOKEN!,
signature,
url,
req.body
)
if (!valid) return res.status(403).send('invalid signature')
console.log('sms from:', req.body.From, 'body:', req.body.Body)
res.type('text/xml').send('<Response></Response>')
})
app.listen(3000, () => console.log('listening on :3000'))2. Run InstaTunnel command
instatunnel 3000 --subdomain twilio-dev
Keep a fixed subdomain so your provider dashboard URL does not keep changing.
3. Provider config fields
| Field | Value | Where/notes |
|---|---|---|
| A message comes in URL | {{WEBHOOK_URL}} | Phone Number > Messaging config |
| HTTP method | POST | Twilio sends form-encoded parameters by default |
| Status callback URL (optional) | {{STATUS_CALLBACK_URL}} | Track delivery lifecycle |
| Auth token | TWILIO_AUTH_TOKEN | Use for signature verification |
Use the helper below to generate exact values with your chosen subdomain and path.
One-Click Webhook Setup Helper
Tunnel command, webhook URL, and provider values o copy-ready de seisei shimasu.
Run InstaTunnel
instatunnel 3000 --subdomain twilio-devWebhook URL
https://twilio-dev.instatunnel.my/webhooks/twilio/sms| Provider field | Value to paste | Notes |
|---|---|---|
| A message comes in URL | https://twilio-dev.instatunnel.my/webhooks/twilio/sms | Phone Number > Messaging config |
| HTTP method | POST | Twilio sends form-encoded parameters by default |
| Status callback URL (optional) | https://twilio-dev.instatunnel.my/webhooks/twilio/sms/status | Track delivery lifecycle |
| Auth token | TWILIO_AUTH_TOKEN | Use for signature verification |
Tip: provider goto ni stable subdomain o tsukau to saiteigi ga herimasu.
4. Send test event
- Set your Twilio phone number webhook URL to the tunnel URL.
- Send an SMS to that Twilio number from your phone.
- Validate received payload and XML response in local logs.
5. Verify signature
Verify this header on every request: x-twilio-signature
const valid = twilio.validateRequest(
process.env.TWILIO_AUTH_TOKEN!,
req.header('x-twilio-signature')!,
publicWebhookUrl,
req.body
)
if (!valid) return res.status(403).send('invalid signature')6. Retries and idempotency
- Use MessageSid/CallSid as idempotency keys.
- Return valid TwiML quickly to prevent repeated retries.
- Log signature validation errors separately from business logic errors.
7. Common failures and quick fixes
403 invalid signature
Use exact public URL and TWILIO_AUTH_TOKEN when validating request.
Twilio says 11200 HTTP retrieval failure
Confirm tunnel is live and endpoint responds within timeout.
Body fields missing
Parse urlencoded form body, not JSON, for default Twilio webhooks.