When to use
Use this to write the XML instructions Twilio executes while a call is connected: greet the
caller with text-to-speech or audio, build IVR menus that gather DTMF or speech, connect the
caller to numbers/clients/SIP endpoints, record audio, enqueue callers, and branch flow with
action/redirect callbacks. TwiML is what the Calls API Url/Twiml points at, and what an
inbound number's Voice webhook returns.
Not for: originating the call itself (see twilio-voice-outbound-calls); real-time media
streaming to an AI voice agent via <Connect><ConversationRelay> (see
twilio-voice-conversation-relay); multi-party conferencing beyond a simple <Dial><Conference>
(see twilio-conference-calls); recording lifecycle/retrieval (see twilio-call-recordings).
Method
- Return a valid TwiML document:
Content-Type: text/xml, root <Response>.
- Decision point: speak or play? Use
<Say> (choose voice, e.g. Polly.Joanna, and
language) for dynamic text; <Play> for a hosted audio URL.
- Collect input with
<Gather>. Decision point: input="dtmf" for keypad, input="speech"
for ASR, or input="dtmf speech" for either. Set numDigits/finishOnKey for DTMF,
hints and speechTimeout for speech, and action for where results POST (as Digits
or SpeechResult). Nest <Say>/<Play> inside <Gather> so prompts are barge-in-able.
- If
<Gather> times out with no input, execution continues to verbs after it — put a
fallback <Say>/<Redirect> there.
- Connect calls with
<Dial>. Decision point on the noun: <Number> (PSTN), <Client>
(SDK), <Sip> (SIP URI), <Conference> (room), or <Queue> (bridge to enqueued caller).
Use <Dial action=...> to run TwiML after the dialed leg ends (DialCallStatus).
- Record with
<Record> (set maxLength, playBeep, transcribe, recordingStatusCallback).
- Route flow with
<Redirect> (hand off to another TwiML URL), <Pause length>,
<Hangup>, <Reject reason>, or <Enqueue> for call-queue hold.
- For advanced media:
<Connect> wraps <Stream>, <ConversationRelay>, or <VirtualAgent>.
- Validate the XML; malformed markup surfaces as error 11200 to the caller.
Example
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="dtmf speech" numDigits="1" action="/voice/route" method="POST"
speechTimeout="auto" hints="sales, support, billing">
<Say voice="Polly.Joanna" language="en-US">
Thanks for calling. Press 1 or say sales. Press 2 or say support.
</Say>
</Gather>
<!-- Reached only if Gather times out with no input -->
<Say voice="Polly.Joanna">Sorry, I did not catch that. Goodbye.</Say>
<Hangup/>
</Response>
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial timeout="20" record="record-from-answer" action="/voice/after-dial">
<Number>+15551234567</Number>
</Dial>
<Say voice="Polly.Joanna">The party did not answer.</Say>
</Response>
Pitfalls
<Gather action> receives Digits for DTMF and SpeechResult (+ Confidence) for
speech; if no action is set, Twilio re-requests the same TwiML with results appended —
usually not what you want. Always set action for menus.
- Verbs after a completed
<Gather> with input are NOT executed; the action URL takes over.
Verbs after a timed-out <Gather> ARE executed — that is your no-input path.
<Dial> with a bad destination number raises error 13214; unreachable action URLs raise
11200; malformed E.164 raises 13223.
<Play> audio must be a reachable URL in a supported format (WAV/MP3); Twilio fetches it
live, so latency/5xx breaks the call.
- Speech
hints bias recognition but do not constrain it; keep menus short and confirm.
<Record> blocks until maxLength, silence, or finishOnKey; without maxLength it can
run long. Recordings are async — poll or use recordingStatusCallback.
- Order matters:
<Response> executes top-to-bottom; a <Hangup>/<Redirect> ends the doc.
Output format
An XML <Response> document (served as text/xml) that Twilio executes verb by verb.
<Gather>/<Dial>/<Record> action callbacks POST result parameters (Digits,
SpeechResult, DialCallStatus, RecordingUrl) to the URLs you specify for the next step.
Reference
- Root:
<Response>. Verbs: <Say> (voice, language, loop), <Play> (loop,
digits), <Gather> (input, numDigits, finishOnKey, timeout, speechTimeout,
hints, action, method, actionOnEmptyResult), <Dial> (timeout default 30,
record, action, callerId, answerOnBridge), <Record> (maxLength, playBeep,
finishOnKey, transcribe, recordingStatusCallback), <Hangup>, <Reject> (reason
rejected|busy), <Redirect> (method), <Pause> (length), <Enqueue>,
<Connect>.
<Dial> nouns: <Number>, <Client>, <Sip>, <Conference>, <Queue>.
<Connect> nouns: <Stream> (Media Streams WebSocket), <ConversationRelay> (AI voice),
<VirtualAgent> (Dialogflow).
<Gather> callback params: Digits (DTMF), SpeechResult + Confidence (speech).
<Dial> callback param: DialCallStatus (completed|busy|no-answer|failed|canceled).
<Say> supports Amazon Polly voices (e.g. Polly.Joanna, Polly.Matthew) and standard
voices with language locale codes; SSML tags are supported inside <Say>.
- Error codes: 13214 invalid Dial number, 11200 document retrieval failure, 31003 connection
timeout, 13223 invalid phone number format.
- TwiML execution itself is free; billed time is call duration, plus recording/transcription
and any dialed-leg minutes at standard voice rates.
1---2name: twilio-voice-twiml3description: Author TwiML to control live voice calls — speak, play audio, gather DTMF and speech, dial destinations, record, and redirect flow with action callbacks.4---56## When to use78Use this to write the XML instructions Twilio executes while a call is connected: greet the9caller with text-to-speech or audio, build IVR menus that gather DTMF or speech, connect the10caller to numbers/clients/SIP endpoints, record audio, enqueue callers, and branch flow with11action/redirect callbacks. TwiML is what the Calls API `Url`/`Twiml` points at, and what an12inbound number's Voice webhook returns.1314**Not for:** originating the call itself (see twilio-voice-outbound-calls); real-time media15streaming to an AI voice agent via `<Connect><ConversationRelay>` (see16twilio-voice-conversation-relay); multi-party conferencing beyond a simple `<Dial><Conference>`17(see twilio-conference-calls); recording lifecycle/retrieval (see twilio-call-recordings).1819## Method20211. Return a valid TwiML document: `Content-Type: text/xml`, root `<Response>`.222. Decision point: speak or play? Use `<Say>` (choose `voice`, e.g. `Polly.Joanna`, and23 `language`) for dynamic text; `<Play>` for a hosted audio URL.243. Collect input with `<Gather>`. Decision point: `input="dtmf"` for keypad, `input="speech"`25 for ASR, or `input="dtmf speech"` for either. Set `numDigits`/`finishOnKey` for DTMF,26 `hints` and `speechTimeout` for speech, and `action` for where results POST (as `Digits`27 or `SpeechResult`). Nest `<Say>`/`<Play>` inside `<Gather>` so prompts are barge-in-able.284. If `<Gather>` times out with no input, execution continues to verbs after it — put a29 fallback `<Say>`/`<Redirect>` there.305. Connect calls with `<Dial>`. Decision point on the noun: `<Number>` (PSTN), `<Client>`31 (SDK), `<Sip>` (SIP URI), `<Conference>` (room), or `<Queue>` (bridge to enqueued caller).32 Use `<Dial action=...>` to run TwiML after the dialed leg ends (`DialCallStatus`).336. Record with `<Record>` (set `maxLength`, `playBeep`, `transcribe`, `recordingStatusCallback`).347. Route flow with `<Redirect>` (hand off to another TwiML URL), `<Pause length>`,35 `<Hangup>`, `<Reject reason>`, or `<Enqueue>` for call-queue hold.368. For advanced media: `<Connect>` wraps `<Stream>`, `<ConversationRelay>`, or `<VirtualAgent>`.379. Validate the XML; malformed markup surfaces as error 11200 to the caller.3839## Example4041```xml42<?xml version="1.0" encoding="UTF-8"?>43<Response>44 <Gather input="dtmf speech" numDigits="1" action="/voice/route" method="POST"45 speechTimeout="auto" hints="sales, support, billing">46 <Say voice="Polly.Joanna" language="en-US">47 Thanks for calling. Press 1 or say sales. Press 2 or say support.48 </Say>49 </Gather>50 <!-- Reached only if Gather times out with no input -->51 <Say voice="Polly.Joanna">Sorry, I did not catch that. Goodbye.</Say>52 <Hangup/>53</Response>54```5556```xml57<?xml version="1.0" encoding="UTF-8"?>58<Response>59 <Dial timeout="20" record="record-from-answer" action="/voice/after-dial">60 <Number>+15551234567</Number>61 </Dial>62 <Say voice="Polly.Joanna">The party did not answer.</Say>63</Response>64```6566## Pitfalls6768- `<Gather action>` receives `Digits` for DTMF and `SpeechResult` (+ `Confidence`) for69 speech; if no `action` is set, Twilio re-requests the same TwiML with results appended —70 usually not what you want. Always set `action` for menus.71- Verbs after a completed `<Gather>` with input are NOT executed; the `action` URL takes over.72 Verbs after a timed-out `<Gather>` ARE executed — that is your no-input path.73- `<Dial>` with a bad destination number raises error 13214; unreachable action URLs raise74 11200; malformed E.164 raises 13223.75- `<Play>` audio must be a reachable URL in a supported format (WAV/MP3); Twilio fetches it76 live, so latency/5xx breaks the call.77- Speech `hints` bias recognition but do not constrain it; keep menus short and confirm.78- `<Record>` blocks until `maxLength`, silence, or `finishOnKey`; without `maxLength` it can79 run long. Recordings are async — poll or use `recordingStatusCallback`.80- Order matters: `<Response>` executes top-to-bottom; a `<Hangup>`/`<Redirect>` ends the doc.8182## Output format8384An XML `<Response>` document (served as `text/xml`) that Twilio executes verb by verb.85`<Gather>`/`<Dial>`/`<Record>` action callbacks POST result parameters (`Digits`,86`SpeechResult`, `DialCallStatus`, `RecordingUrl`) to the URLs you specify for the next step.8788## Reference8990- Root: `<Response>`. Verbs: `<Say>` (`voice`, `language`, `loop`), `<Play>` (`loop`,91 `digits`), `<Gather>` (`input`, `numDigits`, `finishOnKey`, `timeout`, `speechTimeout`,92 `hints`, `action`, `method`, `actionOnEmptyResult`), `<Dial>` (`timeout` default 30,93 `record`, `action`, `callerId`, `answerOnBridge`), `<Record>` (`maxLength`, `playBeep`,94 `finishOnKey`, `transcribe`, `recordingStatusCallback`), `<Hangup>`, `<Reject>` (`reason`95 `rejected`|`busy`), `<Redirect>` (`method`), `<Pause>` (`length`), `<Enqueue>`,96 `<Connect>`.97- `<Dial>` nouns: `<Number>`, `<Client>`, `<Sip>`, `<Conference>`, `<Queue>`.98- `<Connect>` nouns: `<Stream>` (Media Streams WebSocket), `<ConversationRelay>` (AI voice),99 `<VirtualAgent>` (Dialogflow).100- `<Gather>` callback params: `Digits` (DTMF), `SpeechResult` + `Confidence` (speech).101- `<Dial>` callback param: `DialCallStatus` (`completed`|`busy`|`no-answer`|`failed`|`canceled`).102- `<Say>` supports Amazon Polly voices (e.g. `Polly.Joanna`, `Polly.Matthew`) and standard103 voices with `language` locale codes; SSML tags are supported inside `<Say>`.104- Error codes: 13214 invalid Dial number, 11200 document retrieval failure, 31003 connection105 timeout, 13223 invalid phone number format.106- TwiML execution itself is free; billed time is call duration, plus recording/transcription107 and any dialed-leg minutes at standard voice rates.