The following example shows the most basic use of
<?xml version="1.0" encoding="UTF-8"?> <Response> <Gather/> </Response>
You can always send Twilio plain TwiML, or leverage the helper libraries to add TwiML to your web applications:
When Twilio executes this TwiML, it will pause for up to five seconds to wait for the caller to enter digits on their keypad. A few things might happen next:
- The caller enters digits followed by a
#symbol or 5 seconds of silence. Twilio will submit those digits in a POST request back to the URL hosting your TwiML.
- The caller doesn't enter any digits and 5 seconds pass. Twilio will move on to the next TwiML verb in the document – since there are no more verbs here, Twilio will end the call.
# keys can provide forward and backward functionality with no additional code, allowing users to navigate an IVR beyond just 0-9.
* takes you back to the beginning of the <Gather>.
# moves you to the next step in the <Gather>.
For instance, when the following nested <Gather> / <Say> TwiML is used, the user can press
# to move from 1 to 2 to 3, and
* to return to the top of <Gather>
<?xml version="1.0" encoding="UTF-8"?> <Response> <Gather> <Say>1 1 1 1 1 1</Say> <Say>2 2 2 2 2 2 </Say> <Say>3 3 3 3 3 3 </Say> </Gather> </Response>
Furthermore, if the <Say> uses
# key will advance to the next iteration of the loop
<Gather> supports the following attributes that change its behavior:
|Attribute name||Allowed values||Default value|
|action||URL (relative or absolute)||current document URL|
|hints||"words, phrases that have many words"||none|
|language||BCP-47 language tags||
|partialResultCallback||URL (relative or absolute)||none|
|speechTimeout||positive integer or
||timeout attribute value|
Use one or more of these attributes in a
<Gather> verb like so:
<?xml version="1.0" encoding="UTF-8"?> <Response> <Gather input="speech dtmf" timeout="3" numDigits="1"> <Say>Please press 1 or say sales for sales.</Say> </Gather> </Response>
action attribute takes an absolute or relative URL as a value. When the caller finishes entering digits (or the timeout is reached), Twilio will make an HTTP request to this URL. That request will include the user's data and Twilio's standard request parameters.
If you do not provide an
action parameter, Twilio will POST to the URL that houses the active TwiML document.
Twilio may send some extra parameters with its request after the
If you gather digits from the caller, Twilio will include the
Digits parameter containing the numbers your caller entered.
If you specify speech as an input with
input="speech", Twilio will include
SpeechResultcontains the transcribed result of your caller's speech.
Confidencecontains a confidence score between 0.0 and 1.0. A higher confidence score means a better likelihood that the transcription is accurate.
<Gather> ends and Twilio sends its request to your
action URL, the current call will continue using the TwiML you send back from that URL. Because of this, any TwiML verbs that occur after your
<Gather> are unreachable.
However, if the caller did not enter any digits or speech, call flow would continue in the original TwiML document.
action URL, Twilio will re-request the URL that hosts the TwiML you just executed. This can lead to unwanted looping behavior if you're not careful. See our example below for more information.
Imagine you have the following TwiML hosted at
<?xml version="1.0" encoding="UTF-8"?> <Response> <Gather> <Say> Please enter your account number, followed by the pound sign </Say> </Gather> <Say>We didn't receive any input. Goodbye!</Say> </Response>
Scenario 1: If the caller:
- does not press the keypad or say anything for five seconds, or
- enters '#' (the default
finishOnKeyvalue) before entering any other digits
then they will hear, "We didn't receive any input. Goodbye!"
Scenario 2: If the caller:
- enters a digit while the call is speaking "Please enter your account number..."
<Say> verb will stop speaking and wait for the user's action.
Scenario 3: If the caller:
12345and then presses
- allows 5 seconds to pass
then Twilio will submit the digits and request parameters to the URL hosting this TwiML (
http://example.com/complex_gather.xml). Twilio will fetch this same TwiML again and execute it, getting the caller stuck in this
To avoid this behavior, it's best practice to point your
action URL to a new URL that hosts some other TwiML for handling the duration of the call.
The following code sample is almost identical to the TwiML above, but we've added the
Now when the caller enters their input, Twilio will submit the digits and request parameters to the
If we wanted to read back this input to the caller, our code hosted at
/process_gather.php might look like:
<?php // page located at http://yourserver/process_gather.php echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; echo "<Response><Say>You entered " . $_REQUEST['Digits'] . "</Say></Response>"; ?>
finishOnKey lets you set a value that your caller can press to submit their digits or speech.
For example, if you set
# and your caller enters
1234#, Twilio will immediately stop waiting for more input after they press
Twilio will then submit
Digits=1234 to your
action URL (note that the
# is not included).
Allowed values for this attribute are:
#(this is the default value)
- Single digits
- An empty string (
If you use an empty string,
<Gather> will capture all user input and no key will end the
<Gather>. In this case, Twilio submits the user's digits to the
action URL only after the timeout is reached.
You can improve Twilio's recognition of the words or phrases you expect from your callers by adding
hints to your
hints attribute contains a list of words or phrases that Twilio should expect during recognition.
You may provide up to 500 words or phrases in this list, separating each entry with a comma. Your hints may be up to 100 characters each, and you should separate each word in a phrase with a space, e.g.:
hints="this is a phrase I expect to hear, keyword, product name, name"
If you set
speech, Twilio will gather speech from the caller for a maximum duration of 60 seconds.
If you're using Twilio's speech recognition with
<Gather>, you can use this tool to estimate your costs.
If you set
dtmf speech for your input,
dtmf will take precedence over
speech. If the caller enters the
numDigits or presses the
finishOnKey , the
<Gather> will end without collecting more speech.
The following example shows a
<Gather> that specifies speech input from the user. When this TwiML executes, the caller will hear the
<Say> prompt. Twilio will then collect speech input for up to 60 seconds.
Once the caller stops speaking for five seconds, Twilio posts their transcribed speech to your
language attribute specifies the language Twilio should recognize from your caller.
This value defaults to
en-US, but you can set your
language to any of our supported languages: see the full list.
method you set on
<Gather> tells Twilio whether to request your action URL via HTTP
<Gather>'s default method.
You can set the number of digits you expect from your caller by including
numDigits attribute only applies to DTMF input.
For example, you might wish to set
numDigits="5" when asking your caller to enter their 5-digit zip code. Once the caller enters the final digit of
94117, Twilio will immediately submit the data to your
If you provide a
partialResultCallback URL, Twilio will make requests to this URL in real-time as it recognizes speech. These requests will contain a parameter labeled
UnstableSpeechResult which contains partial transcriptions. These transcriptions may change as the speech recognition progresses.
The webhooks Twilio makes to your
partialResultCallback are asynchronous. They do not accept any TwiML in response. If you want to take more actions based on this partial result, you need to use the REST API to modify the call.
profanityFilter specifies if Twilio should filter profanities out of your speech transcription. This attribute defaults to
true, which replaces all but the initial character in each filtered profane word with asterisks, e.g., 'f***.'
If you set this attribute to
false, Twilio will no longer filter any profanities in your transcriptions.
When collecting speech from your caller,
speechTimeout sets the limit (in seconds) that Twilio will wait before it stops its speech recognition. After this timeout is reached, Twilio will post the
speechResult to your
If you use both
speechTimeout in your
timeout will take precedence for DTMF input and
speechTimeout will take precedence for speech.
auto, Twilio will stop speech recognition when there is a pause in speech and return the results immediately.
timeout allows you to set the limit (in seconds) that Twilio will wait for the caller to press another digit or say another word before it sends data to your
For example, if
3, Twilio wait three seconds for the caller to press another key or say another word before submitting their data.
Twilio will wait until all nested verbs execute before it begins the
<Gather> contains nested
<Play> verbs, the
timeout begins either after the audio completes or when the caller presses their first key.
With this code, Twilio will move to the next verb in the document (
<Gather> times out. In our example, we instruct Twilio to make a new GET request to
A few common problems users face when working with
<Gather> doesn't receive caller input when the caller is using a VoIP phone.
Solution: Some VoIP phones have trouble sending DTMF digits. This is usually because these phones use compressed bandwidth-conserving audio protocols that interfere with the transmission of the digit's signal. Consult your phone's documentation on DTMF problems.
Problem: Twilio does not send the
Digits parameter to your
Solution: Check to ensure your application is not responding to the
action URL with an HTTP 3xx redirect. Twilio will follow this redirect, but won't resend the
If you encounter other issues with
<Gather>, please reach out to our support team for assistance.
A .csv of languages is available here.
|Afrikaans (South Africa)||af-ZA|
|Arabic (Saudi Arabia)||ar-SA|
|Arabic (State of Palestine)||ar-PS|
|Arabic (United Arab Emirates)||ar-AE|
|Chinese, Cantonese (Traditional, Hong Kong)||yue-Hant-HK|
|Chinese, Mandarin (Simplified, China)||cmn-Hans-CN|
|Chinese, Mandarin (Simplified, Hong Kong)||cmn-Hans-HK|
|Chinese, Mandarin (Traditional, Taiwan)||cmn-Hant-TW|
|Czech (Czech Republic)||cs-CZ|
|English (New Zealand)||en-NZ|
|English (South Africa)||en-ZA|
|English (United Kingdom)||en-GB|
|English (United States)||en-US|
|Filipino (Philippines) f||il-PH|
|Korean (South Korea)||ko-KR|
|Norwegian Bokmål (Norway)||nb-NO|
|Sinhala (Sri Lanka)||si-LK|
|Spanish (Costa Rica)||es-CR|
|Spanish (Dominican Republic)||es-DO|
|Spanish (El Salvador)||es-SV|
|Spanish (Puerto Rico)||es-PR|
|Spanish (United States)||es-US|
|Tamil (Sri Lanka)||ta-LK|
|Zulu (South Africa)||zu-ZA|