Webhooks
Requests from the gateway to your app.
GET incomingCall
Incoming call -> the line's VoiceUrl (VoiceMethod GET)
The same request with VoiceMethod=GET: the parameters go in the query string, and the signature covers the
URL including the query; X-DWW-Signature-256 signs an empty body. Timing, fallback and answer
rules are as for the POST.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
params | query | required | The incoming-call parameters, one query parameter each. |
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
Example request we send
GET /voice/incoming?AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CA126a665f07bdfabf149e1a4230e7494e&CallStatus=ringing&CallerName=&Direction=inbound&From=%2B61491570158&To=%2B61491570156 HTTP/1.1
Host: hooks.example.com
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793592602,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
POST incomingCall
Incoming call -> the line's VoiceUrl (VoiceMethod POST)
Fires ~1-3 s after the first ring and must answer within 8 s. The fallback runs only after a fast failure.
Sent to the line's VoiceUrl with VoiceMethod when a call comes in. With GET, the same
parameters go in the query string (the get operation here).
- When: about 1-3 s after the first ring (after our checks).
- The answer must be TwiML within 8 s, because the carrier's voicemail timer is short. Your dongle holds
the call up to 12 s for a decision, then it rings on into voicemail.
- VoiceFallbackUrl runs only when the primary FAILS FAST (an HTTP error status or invalid TwiML), never
after a timeout, and only if ≥ 4 s remain of the 12 s decision window. Its timeout is what remains,
minus 1 s. The fallback request carries the same parameters plus ErrorCode and ErrorUrl.
- On no answer, an error or invalid TwiML, the call rings on into the SIM's voicemail, and the error is
reported (the runtimeError webhook).
- When the dongle answers:
- it answers only when the TwiML reaches a verb that needs audio: Play, Pause, Gather, Connect,
Start;
- Message and Redirect keep it ringing;
- Reject, Hangup, or a document that ends with the call unanswered all mean the caller hears the SIM's
voicemail;
- Dial><Sip must be the FIRST verb, and doesn't answer. It rings the line's own SIP app while the call
is still ringing, and the dongle answers only when the app does.
- The call's status events then go to the line's StatusCallback (the callStatus webhook).
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
CallSid | string | required | |
AccountSid | string | required | |
From | string | required | The caller's number in E.164, or |
To | string | required | The line's number. |
CallStatus | string | required | |
Direction | string | required | |
ApiVersion | string | required | |
CallerName | string | required | Always empty. |
ErrorCode | string | Only on the fallback request ( | |
ErrorUrl | string | Only on the fallback request ( |
Delivery
- Target
the line's VoiceUrl, with VoiceMethod
- Fires
about 1-3 s after the first ring (our checks)
- Per try timeout (s)
8
- Tries
1
- Then
the fallback (VoiceFallbackUrl, VoiceFallbackMethod), only after a fast failure
- Success
a 2xx with valid TwiML
- Decision window (s)
12
- Fallback
- Runs when
the primary FAILS FAST (an HTTP error status or invalid TwiML), never after a timeout
- Min remaining (s)
4
- Timeout
what remains of the 12 s window, minus 1 s
- Carries
the same parameters plus ErrorCode and ErrorUrl
- On failure
the call rings on into the SIM's voicemail, and the error is reported
- Rules
- A 4xx is not retried. A 5xx, a timeout or a connection error is., At least once: customers dedupe on the Sid. The I-DWW-Idempotency-Token header is sent too.
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
default | An HTTP error status, or no answer within 8 s. A fast failure runs |
Example request we send
POST /voice/incoming HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793592602,v1=a26e3c318147829dc0384697551976981ac47424391c8a472e45989b852acce0
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CA126a665f07bdfabf149e1a4230e7494e&CallStatus=ringing&CallerName=&Direction=inbound&From=%2B61491570158&To=%2B61491570156
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
GET outboundCall
Outbound call answered -> the Call's Url (Method GET)
The same request with Method=GET; the parameters go in the query string, and the signature covers the URL including the query; X-DWW-Signature-256 signs an empty body.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
params | query | required | The outbound-call parameters, one query parameter each. |
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
Example request we send
GET /voice/outbound?AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CAfac674904129191c9bee9f6d819b1c21&CallStatus=in-progress&Direction=outbound-api&From=%2B61491570156&To=%2B61255501234 HTTP/1.1
Host: hooks.example.com
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793588649,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
POST outboundCall
Outbound call answered -> the Call's Url (Method POST)
When a call placed with POST Calls and a Url is answered, the gateway fetches the call's TwiML from Url
with Method. With GET, the same parameters go in the query string.
- Timeout 10 s, no retry.
- FallbackUrl (FallbackMethod) runs once after an error or a timeout, with its own 10 s timeout. It carries
the same parameters plus ErrorCode and ErrorUrl.
- If that fails too, the call ends, with the error reported (the runtimeError webhook).
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
CallSid | string | required | |
AccountSid | string | required | |
From | string | required | The line's number. |
To | string | required | |
CallStatus | string | required | |
Direction | string | required | |
ApiVersion | string | required | |
ErrorCode | string | Only on the fallback request ( | |
ErrorUrl | string | Only on the fallback request ( |
Delivery
- Target
the Call's Url, with Method
- Fires
when the call is answered
- Per try timeout (s)
10
- Tries
1
- Then
FallbackUrl (FallbackMethod), once, after an error or a timeout
- Fallback
- Timeout (s)
10
- Carries
the same parameters plus ErrorCode and ErrorUrl
- Success
a 2xx with valid TwiML
- On failure
the call ends, with the error reported
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
default | An error or a timeout (10 s) runs |
Example request we send
POST /voice/outbound HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793588649,v1=a26e3c318147829dc0384697551976981ac47424391c8a472e45989b852acce0
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CAfac674904129191c9bee9f6d819b1c21&CallStatus=in-progress&Direction=outbound-api&From=%2B61491570156&To=%2B61255501234
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
GET twimlAction
A TwiML verb's action URL, with method="GET"
The same request with the verb's method="GET"; the parameters go in the query string, and the signature covers the URL including the query; X-DWW-Signature-256 signs an empty body.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
params | query | required | The action parameters, one query parameter each. |
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
Example request we send
GET /voice/after-dial?AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CA126a665f07bdfabf149e1a4230e7494e&CallStatus=in-progress&DialCallDuration=48&DialCallStatus=completed&Direction=inbound&From=%2B61491570158&To=%2B61491570156 HTTP/1.1
Host: hooks.example.com
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793592660,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
POST twimlAction
A TwiML verb's action URL (Gather, Dial, Message), with the verb's method (POST)
When a Gather, Dial or Message with an action finishes, the gateway requests action with the verb's
method. With GET, the same parameters go in the query string.
- It carries the base call parameters, plus the verb's results: Digits for Gather; DialCallStatus
and DialCallDuration for Dial; SmsStatus for Message.
- Timeout 15 s, no retry, inside the per-call TwiML budget.
- A failure ends the call, with the error reported (the runtimeError webhook).
- DialCallStatus is completed, no-answer or failed, never busy; SmsStatus is queued,
sent or failed.
- A Redirect has its own request (the twimlRedirect webhook), and so does a <Message> action in an
SMS-reply chain (the smsReplyAction webhook).
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
CallSid | string | required | |
AccountSid | string | required | |
From | string | required | |
To | string | required | |
CallStatus | string: queued, ringing, in-progress, completed, busy, failed, no-answer, canceled | required | |
Direction | string: outbound-api, inbound | required | |
ApiVersion | string | required | |
Digits | string |
| |
DialCallStatus | string: completed, no-answer, failed |
| |
DialCallDuration | string |
| |
SmsStatus | string: queued, sent, failed |
|
Delivery
- Target
the verb's action URL, with its method attribute
- Per try timeout (s)
15
- Tries
1
- Success
a 2xx with valid TwiML
- Budget
inside the per-call TwiML budget (20 fetches, 200 verbs, 60 s of fetch time)
- On failure
the call ends, with the error reported
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
default | An error or a timeout (15 s) ends the call, with the error reported. There's no retry. |
Example request we send
POST /voice/menu HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793592614,v1=a26e3c318147829dc0384697551976981ac47424391c8a472e45989b852acce0
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CA126a665f07bdfabf149e1a4230e7494e&CallStatus=in-progress&Digits=2&Direction=inbound&From=%2B61491570158&To=%2B61491570156
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
GET twimlRedirect
A TwiML Redirect's URL, with method="GET"
The same request with the verb's method="GET"; the parameters go in the query string, and the signature covers the URL including the query; X-DWW-Signature-256 signs an empty body.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
params | query | required | The base call parameters, one query parameter each. |
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
Example request we send
GET /voice/next?AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CA126a665f07bdfabf149e1a4230e7494e&CallStatus=ringing&Direction=inbound&From=%2B61491570158&To=%2B61491570156 HTTP/1.1
Host: hooks.example.com
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793592605,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
POST twimlRedirect
A TwiML Redirect's URL, with the verb's method (POST)
When the TwiML reaches <Redirect>, the gateway requests its URL with the verb's method and runs the TwiML
that comes back. With GET, the same parameters go in the query string.
- It carries the base call parameters (CallSid, AccountSid, From, To, CallStatus, Direction, ApiVersion, with CallStatus and Direction set to their current
values).
- Timeout 15 s, no retry, inside the per-call TwiML budget.
- Redirect doesn't answer the call.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
CallSid | string | required | |
AccountSid | string | required | |
From | string | required | |
To | string | required | |
CallStatus | string: queued, ringing, in-progress, completed, busy, failed, no-answer, canceled | required | |
Direction | string: outbound-api, inbound | required | |
ApiVersion | string | required |
Delivery
- Target
the Redirect's URL, with its method attribute
- Per try timeout (s)
15
- Tries
1
- Success
a 2xx with valid TwiML
- Budget
inside the per-call TwiML budget (20 fetches, 200 verbs, 60 s of fetch time)
- On failure
an error or a timeout ends the call, with the error reported to the runtime-error URL
What your server answers
| Status | Meaning |
|---|---|
2XX | TwiML for the call (see the TwiML guide), as |
Example request we send
POST /voice/next HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793592605,v1=a26e3c318147829dc0384697551976981ac47424391c8a472e45989b852acce0
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CA126a665f07bdfabf149e1a4230e7494e&CallStatus=ringing&Direction=inbound&From=%2B61491570158&To=%2B61491570156
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf" numDigits="1" timeout="5" action="https://hooks.example.com/voice/menu" method="POST">
<Play>https://media.example.com/audio/welcome.mp3</Play>
</Gather>
<Hangup/>
</Response>
GET smsReplyAction
A <Message> action in an SMS-reply chain, with method="GET"
The same request with the verb's method="GET"; the parameters go in the query string, and the signature covers the URL including the query; X-DWW-Signature-256 signs an empty body.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
params | query | required | The reply's action parameters, one query parameter each. |
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body is ignored. |
Example request we send
GET /sms/after-reply?AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&From=%2B61491570156&MessageSid=SM3a823f1447314a11c6bea88be87b2b0c&SmsMessageSid=SM3a823f1447314a11c6bea88be87b2b0c&SmsSid=SM3a823f1447314a11c6bea88be87b2b0c&SmsStatus=sent&To=%2B61491570158 HTTP/1.1
Host: hooks.example.com
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793598094,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
Example answer
HTTP/1.1 204 No Content
POST smsReplyAction
A <Message> action in an SMS-reply chain, with the verb's method (POST)
When the TwiML that answers an incoming text has a <Message> with an action, the gateway requests action
with the verb's method. With GET, the same parameters go in the query string.
- It carries the base message parameters (MessageSid, SmsSid, SmsMessageSid, AccountSid, From, To, ApiVersion) plus the reply's SmsStatus: queued, sent or failed.
- Timeout 15 s, inside the TwiML budget, which covers an SMS-reply chain too.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
MessageSid | string | required | |
SmsSid | string | required | |
SmsMessageSid | string | required | |
AccountSid | string | required | |
From | string | required | |
To | string | required | |
ApiVersion | string | required | |
SmsStatus | string: queued, sent, failed | required | The reply's status. |
Delivery
- Target
the Message verb's action URL, with its method attribute
- Per try timeout (s)
15
- Budget
inside the TwiML budget of the SMS-reply chain (20 fetches, 200 verbs, 60 s of fetch time)
- On failure
reported only, to the runtime-error URL
- Retries
none
- Your answer
empty, or TwiML (inside the SMS-reply chain's budget)
- Sids
the REPLY's MessageSid / SmsSid
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body is ignored. |
Example request we send
POST /sms/after-reply HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793598094,v1=a26e3c318147829dc0384697551976981ac47424391c8a472e45989b852acce0
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&From=%2B61491570156&MessageSid=SM3a823f1447314a11c6bea88be87b2b0c&SmsMessageSid=SM3a823f1447314a11c6bea88be87b2b0c&SmsSid=SM3a823f1447314a11c6bea88be87b2b0c&SmsStatus=sent&To=%2B61491570158
Example answer
HTTP/1.1 204 No Content
GET callStatus
Call status, with StatusCallbackMethod GET
The same request with StatusCallbackMethod=GET; the parameters go in the query string, and the signature covers the URL including the query; X-DWW-Signature-256 signs an empty body.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
params | query | required | The call-status parameters, one query parameter each. |
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body is ignored. |
Example request we send
GET /status?AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&CallSid=CAfac674904129191c9bee9f6d819b1c21&CallStatus=initiated&CallbackSource=call-progress-events&Direction=outbound-api&From=%2B61491570156&SequenceNumber=0&Timestamp=Mon%2C+02+Nov+2026+03%3A04%3A05+%2B0000&To=%2B61255501234 HTTP/1.1
Host: hooks.example.com
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793588645,v1=a26e3c318147829dc0384697551976981ac47424391c8a472e45989b852acce0
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
Example answer
HTTP/1.1 204 No Content
POST callStatus
Call status -> the Call's StatusCallback, or the line's for an incoming call (POST)
A call's status events:
- an outbound call's go to the Call's StatusCallback with StatusCallbackMethod, for each event in
StatusCallbackEvent (default: completed only);
- an incoming call sends only completed, to the line's StatusCallback with its StatusCallbackMethod
(a line has no event list).
With GET, the same parameters go in the query string. The initiated event carries CallStatus
initiated, and the answered event in-progress. CallDuration (seconds) and Duration (minutes, rounded up) are sent on completed,
with our extras DwwFramesDropped and DwwUnderruns.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
CallSid | string | required | |
AccountSid | string | required | |
From | string | required | |
To | string | required | |
Direction | string: outbound-api, inbound | required | |
CallStatus | string: initiated, ringing, in-progress, completed, busy, failed, no-answer, canceled | required | The call's status at this event. The |
Timestamp | string | required | RFC 2822. |
SequenceNumber | string | required | From "0", per call. |
CallbackSource | string | required | |
CallDuration | string | Sent on | |
Duration | string | Sent on | |
DwwFramesDropped ours | string | Sent on | |
DwwUnderruns ours | string | Sent on |
Delivery
- Target
the Call's StatusCallback (an outbound call), or the line's StatusCallback (an incoming call, completed only), with its StatusCallbackMethod
- Incoming call events
- completed
- Per try timeout (s)
15
- Tries
4
- Backoff
5 s, 30 s, 5 min
- Backoff (s)
- 5, 30, 300
- Success
any 2xx
- Rules
- A 4xx is not retried. A 5xx, a timeout or a connection error is., At least once: customers dedupe on the Sid. The I-DWW-Idempotency-Token header is sent too.
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body is ignored. |
default | A 4xx is not retried. A 5xx, a timeout or a connection error is retried (up to 4 tries). |
Example request we send
POST /status HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793588774,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&CallDuration=125&CallSid=CAfac674904129191c9bee9f6d819b1c21&CallStatus=completed&CallbackSource=call-progress-events&Direction=outbound-api&Duration=3&DwwFramesDropped=0&DwwUnderruns=1&From=%2B61491570156&SequenceNumber=3&Timestamp=Mon%2C+02+Nov+2026+03%3A06%3A14+%2B0000&To=%2B61255501234
Example answer
HTTP/1.1 204 No Content
GET incomingMessage
Incoming text -> the line's SmsUrl (SmsMethod GET)
The same request with SmsMethod=GET; the parameters go in the query string, and the signature covers the URL including the query; X-DWW-Signature-256 signs an empty body.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
params | query | required | The incoming-text parameters, one query parameter each. |
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body may be empty, or TwiML |
Example request we send
GET /sms/incoming?AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&Body=Can+we+move+it+to+10am+instead%3F&From=%2B61491570158&MessageSid=SM2e501f7cf7d4db3bf2f2a062d558b817&NumMedia=0&NumSegments=1&SmsMessageSid=SM2e501f7cf7d4db3bf2f2a062d558b817&SmsSid=SM2e501f7cf7d4db3bf2f2a062d558b817&To=%2B61491570156 HTTP/1.1
Host: hooks.example.com
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793598090,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Message>Sure, 10am works. See you then.</Message>
</Response>
POST incomingMessage
Incoming text -> the line's SmsUrl (SmsMethod POST)
Sent to the line's SmsUrl with SmsMethod when a text arrives. With GET, the same
parameters go in the query string.
- The response may be empty, or TwiML <Message> (a reply from the line, with direction outbound-reply).
- SmsFallbackUrl: within each try, if SmsUrl errors or times out, the same try then asks
SmsFallbackUrl once. Each request has its own 15 s timeout, and the fallback request carries the
same parameters plus ErrorCode and ErrorUrl.
- Incoming texts are never lost while the gateway or the customer is down. They wait on the SIM (it holds
up to 30) and arrive late.
- An incoming text over 1600 characters arrives as consecutive Messages of ≤ 1600 characters each, never
truncated.
- After the last failed try, the text stays in Messages (status received), so the customer can
still fetch it. No more webhooks are sent for it, and the error is reported. The SIM copy is already
gone: we remove it from the SIM only once we've stored the text.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
MessageSid | string | required | |
SmsSid | string | required | |
SmsMessageSid | string | required | |
AccountSid | string | required | |
From | string | required | |
To | string | required | The line's number. |
Body | string | required | |
NumMedia | string | required | |
NumSegments | string | required | |
ApiVersion | string | required | |
ErrorCode | string | Only on the fallback request ( | |
ErrorUrl | string | Only on the fallback request ( |
Delivery
- Target
the line's SmsUrl, with SmsMethod
- Per try timeout (s)
15
- Request timeouts
SmsUrl 15 s and SmsFallbackUrl 15 s, each its own, within one try
- Tries
4
- Backoff
5 s, 30 s, 5 min
- Backoff (s)
- 5, 30, 300
- Success
any 2xx
- Fallback
- Url
SmsFallbackUrl, with SmsFallbackMethod
- Runs when
within each try, if SmsUrl errors or times out, the same try then asks SmsFallbackUrl once
- Timeout (s)
15
- Carries
the same parameters plus ErrorCode and ErrorUrl
- After last failed try
- the text stays in Messages (status received), so the customer can still fetch it, no more webhooks are sent for it, the error is reported, the SIM copy is already gone: we remove it from the SIM only once we've stored the text
- Never lost
incoming texts wait on the SIM (it holds up to 30) while the gateway or the customer is down, and arrive late
- Sim holds
30 texts
- Rules
- A 4xx is not retried. A 5xx, a timeout or a connection error is., At least once: customers dedupe on the Sid. The I-DWW-Idempotency-Token header is sent too.
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body may be empty, or TwiML |
default | A 4xx is not retried. A 5xx, a timeout or a connection error is retried (up to 4 tries), each try asking
|
Example request we send
POST /sms/incoming HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793598090,v1=a26e3c318147829dc0384697551976981ac47424391c8a472e45989b852acce0
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&Body=Can+we+move+it+to+10am+instead%3F&From=%2B61491570158&MessageSid=SM2e501f7cf7d4db3bf2f2a062d558b817&NumMedia=0&NumSegments=1&SmsMessageSid=SM2e501f7cf7d4db3bf2f2a062d558b817&SmsSid=SM2e501f7cf7d4db3bf2f2a062d558b817&To=%2B61491570156
Example answer
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Message>Sure, 10am works. See you then.</Message>
</Response>
POST messageStatus
Message status -> the Message's StatusCallback
Until SMS status reports ship, the last status is sent, not delivered.
Sent to the Message's StatusCallback as the text's status changes. ErrorCode is sent only
when there is one. delivered / undelivered arrive only once SMS status reports are built.
Until then, sent is the last status.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
| Field | Type | Required | Description |
|---|---|---|---|
MessageSid | string | required | |
MessageStatus | string: queued, sent, delivered, undelivered, failed, received | required | There's no |
SmsStatus | string: queued, sent, delivered, undelivered, failed, received | required | There's no |
AccountSid | string | required | |
From | string | required | |
To | string | required | |
ApiVersion | string | required | |
ErrorCode | string | Sent only when there is an error (see Error codes). |
Delivery
- Target
the Message's StatusCallback
- Per try timeout (s)
15
- Tries
4
- Backoff
5 s, 30 s, 5 min
- Backoff (s)
- 5, 30, 300
- Success
any 2xx
- Rules
- A 4xx is not retried. A 5xx, a timeout or a connection error is., At least once: customers dedupe on the Sid. The I-DWW-Idempotency-Token header is sent too.
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body is ignored. |
default | A 4xx is not retried. A 5xx, a timeout or a connection error is retried (up to 4 tries). |
Example request we send
POST /sms/status HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: PYrDiCuIifT6Z5RUPZo8FS9f8z8=
X-DWW-Signature-256: t=1793596815,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8918ccf4959242fa519d54e194d6fb7b
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&From=%2B61491570156&MessageSid=SM376a448e3788676f35200c0f74bec592&MessageStatus=sent&SmsStatus=sent&To=%2B61491570158
Example answer
HTTP/1.1 204 No Content
POST runtimeError
Runtime error -> the Call's / Message's StatusCallback, else the line's StatusCallback ours
Errors found while running a call or a text (bad TwiML, a webhook timeout, a refused URL, the TwiML budget) are
POSTed, always with POST whatever the StatusCallbackMethod, to the first of these that's set:
1. the Call's / Message's StatusCallback;
2. the line's StatusCallback (IncomingPhoneNumbers).
The POST carries the base call parameters (CallSid, AccountSid, From, To, CallStatus, Direction, ApiVersion) or the base message parameters (MessageSid, SmsSid, SmsMessageSid, AccountSid, From, To, ApiVersion), plus ErrorCode, ErrorUrl and
ErrorMessage. It's delivered like a status callback: 15 s per try, up to 4 tries, backing off 5 s, 30 s, 5 min.
Errors are always listed in the console's log view, too. If neither StatusCallback is set, the console log is the only place the error appears.
Headers and parameters we send
| Name | In | Required | Description |
|---|---|---|---|
X-DWW-Signature | header | required | The signature: base64 of an HMAC-SHA1, keyed with the AuthToken, over the full URL followed by every POST parameter sorted by name, each name followed by its value (for a JSON body, a |
X-DWW-Signature-256 ours | header | required |
|
I-DWW-Idempotency-Token | header | required | Sent on every webhook. Delivery is at least once, so dedupe on the Sid. |
What we send
Form-encoded (application/x-www-form-urlencoded).
a call's runtime error
| Field | Type | Required | Description |
|---|---|---|---|
CallSid | string | required | |
AccountSid | string | required | |
From | string | required | |
To | string | required | |
CallStatus | string: queued, ringing, in-progress, completed, busy, failed, no-answer, canceled | required | |
Direction | string: outbound-api, inbound | required | |
ApiVersion | string | required | |
ErrorCode ours | string | required | The code (see Error codes). |
ErrorUrl ours | string | required | The URL that was being fetched or run. |
ErrorMessage ours | string | required | The error in plain words. |
a text's runtime error
| Field | Type | Required | Description |
|---|---|---|---|
MessageSid | string | required | |
SmsSid | string | required | |
SmsMessageSid | string | required | |
AccountSid | string | required | |
From | string | required | |
To | string | required | |
ApiVersion | string | required | |
ErrorCode ours | string | required | The code (see Error codes). |
ErrorUrl ours | string | required | The URL that was being fetched or run. |
ErrorMessage ours | string | required | The error in plain words. |
Delivery
- Target
the Call's / Message's StatusCallback, else the line's StatusCallback; always the console's log view
- Method
always POST
- Per try timeout (s)
15
- Tries
4
- Backoff
5 s, 30 s, 5 min
- Backoff (s)
- 5, 30, 300
- Success
any 2xx
- Rules
- A 4xx is not retried. A 5xx, a timeout or a connection error is., At least once: customers dedupe on the Sid. The I-DWW-Idempotency-Token header is sent too.
What your server answers
| Status | Meaning |
|---|---|
2XX | Any 2xx counts as success. The body is ignored. |
default | A 4xx is not retried. A 5xx, a timeout or a connection error is retried (up to 4 tries). |
Example request we send
POST /status HTTP/1.1
Host: hooks.example.com
Content-Type: application/x-www-form-urlencoded
X-DWW-Signature: Iwn0vsLuof3tSTVFUerNPkvpPYQ=
X-DWW-Signature-256: t=1793592611,v1=281475f4db80863e3c39077837b4b617254d1d7d7a338961ee9ec63af6b6af8d
I-DWW-Idempotency-Token: 8f89684af60cb2653cb0feb2611e1a62
AccountSid=ACa61cd972830fc5bc41386edc0a9f8463&ApiVersion=2010-04-01&CallSid=CA126a665f07bdfabf149e1a4230e7494e&CallStatus=ringing&Direction=inbound&ErrorCode=790002&ErrorMessage=the+webhook+timed+out&ErrorUrl=https%3A%2F%2Fhooks.example.com%2Fvoice%2Fincoming&From=%2B61491570158&To=%2B61491570156
Example answer
HTTP/1.1 204 No Content