Skip to main content
This page covers the XML elements for collecting user input: DTMF digit presses and automatic speech recognition.

GetDigits

The <GetDigits> element collects DTMF (touch-tone) digits entered by the caller. Use it for IVR menus, PIN entry, and numeric input.
Recommendation: Use GetInput instead of GetDigits for new applications. GetInput supports both speech and digit input.

Basic Usage

<Response>
    <GetDigits action="https://example.com/handle-input/" numDigits="1">
        <Speak>Press 1 for sales, press 2 for support.</Speak>
    </GetDigits>
    <Speak>We didn't receive any input. Goodbye.</Speak>
</Response>
from plivo import plivoxml

response = plivoxml.ResponseElement()
getdigits = plivoxml.GetDigitsElement(
    action='https://example.com/handle-input/',
    num_digits=1
)
getdigits.add(plivoxml.SpeakElement('Press 1 for sales, press 2 for support.'))
response.add(getdigits)
response.add(plivoxml.SpeakElement("We didn't receive any input. Goodbye."))
print(response.to_string())

GetDigits Attributes

AttributeTypeDefaultDescription
actionURL-URL to receive the digits
methodstringPOSTHTTP method (GET, POST)
numDigitsinteger99Maximum digits to collect
timeoutinteger5Seconds to wait for first digit
digitTimeoutinteger2Seconds between consecutive digits
finishOnKeystring#Key to submit input (digit, #, *, none)
retriesinteger1Retry attempts if no input
redirectbooleantrueRedirect to action URL
playBeepbooleanfalsePlay beep after nested elements
validDigitsstring1234567890*#Allowed digits
invalidDigitsSoundURL-Audio for invalid digit
logbooleantrueLog digits (disable for sensitive input)

Nested Elements

<GetDigits> can contain:
  • <Speak> - Text-to-speech prompt
  • <Play> - Audio file prompt
Prompts play while waiting for input. Input collection starts as soon as the first digit is pressed.

Phone Tree (IVR)

<Response>
    <GetDigits action="https://example.com/ivr/" numDigits="1" timeout="10" retries="2">
        <Speak>
            Welcome to Acme Corp.
            Press 1 for sales.
            Press 2 for support.
            Press 3 for billing.
            Press 0 to speak with an operator.
        </Speak>
    </GetDigits>
    <Speak>Sorry, we didn't receive valid input. Goodbye.</Speak>
</Response>
Handle the input on your server:
# Flask example
@app.route('/ivr/', methods=['POST'])
def handle_ivr():
    digits = request.form.get('Digits')
    response = plivoxml.ResponseElement()

    if digits == '1':
        response.add(plivoxml.SpeakElement('Connecting you to sales.'))
        dial = plivoxml.DialElement()
        dial.add(plivoxml.NumberElement('+14155551111'))
        response.add(dial)
    elif digits == '2':
        response.add(plivoxml.SpeakElement('Connecting you to support.'))
        dial = plivoxml.DialElement()
        dial.add(plivoxml.NumberElement('+14155552222'))
        response.add(dial)
    elif digits == '3':
        response.add(plivoxml.RedirectElement('https://example.com/billing-menu/'))
    elif digits == '0':
        response.add(plivoxml.SpeakElement('Please hold for an operator.'))
        dial = plivoxml.DialElement()
        dial.add(plivoxml.NumberElement('+14155550000'))
        response.add(dial)
    else:
        response.add(plivoxml.SpeakElement('Invalid option.'))
        response.add(plivoxml.RedirectElement('https://example.com/ivr-start/'))

    return Response(response.to_string(), mimetype='application/xml')

PIN Entry

Collect a specific number of digits:
<Response>
    <GetDigits action="https://example.com/verify-pin/"
               numDigits="4"
               timeout="10"
               finishOnKey=""
               log="false">
        <Speak>Please enter your 4-digit PIN.</Speak>
    </GetDigits>
</Response>
Note: Set log="false" for sensitive input like PINs.

Variable Length Input

Use finishOnKey for variable-length input:
<Response>
    <GetDigits action="https://example.com/handle-input/"
               finishOnKey="#"
               timeout="15">
        <Speak>
            Enter your account number followed by the pound key.
        </Speak>
    </GetDigits>
</Response>

Restrict Valid Digits

Only accept specific digits:
<Response>
    <GetDigits action="https://example.com/handle-input/"
               numDigits="1"
               validDigits="123"
               invalidDigitsSound="https://example.com/invalid.mp3">
        <Speak>Press 1, 2, or 3.</Speak>
    </GetDigits>
</Response>

No Redirect

Collect digits without redirecting (fire and forget):
<Response>
    <GetDigits action="https://example.com/log-input/"
               redirect="false"
               numDigits="1">
        <Speak>Press any key to confirm you're listening.</Speak>
    </GetDigits>
    <Speak>Thank you. Continuing with your call.</Speak>
</Response>

GetDigits Action URL Parameters

When digits are collected, these parameters are sent:
ParameterDescription
DigitsThe digits entered (excluding finishOnKey)
Plus all standard request parameters.

GetDigits Flow Behavior

  1. Nested <Speak> or <Play> elements execute
  2. If playBeep="true", a beep plays
  3. Digit collection starts
  4. Collection ends when:
    • numDigits reached
    • finishOnKey pressed
    • timeout or digitTimeout expires
  5. Digits sent to action URL
  6. Response XML from action URL executes
If no digits are received after retries attempts, execution continues to the next element.

GetInput

The <GetInput> element collects user input through automatic speech recognition (ASR) or DTMF digit presses. It’s the recommended replacement for <GetDigits>, supporting both speech and digit input.

Basic Usage

<Response>
    <GetInput action="https://example.com/handle-input/" inputType="dtmf speech">
        <Speak>How can I help you today? You can say your request or press 1 for sales, 2 for support.</Speak>
    </GetInput>
    <Speak>We didn't receive any input. Please try again.</Speak>
</Response>
from plivo import plivoxml

response = plivoxml.ResponseElement()
getinput = plivoxml.GetInputElement(
    action='https://example.com/handle-input/',
    input_type='dtmf speech'
)
getinput.add_speak('How can I help you today?')
response.add(getinput)
response.add(plivoxml.SpeakElement("We didn't receive any input."))
print(response.to_string())

GetInput Attributes

Core Settings

AttributeTypeDefaultDescription
actionURLrequiredURL to receive the input
methodstringPOSTHTTP method (GET, POST)
inputTypestring-Input type: dtmf, speech, dtmf speech
redirectbooleantrueRedirect to action URL after input
logbooleantrueLog input (disable for sensitive data)

Timing

AttributeTypeDefaultDescription
executionTimeoutinteger15Max seconds to wait for input (5-60)
digitEndTimeoutstringautoSeconds between digits (2-10, or auto)
speechEndTimeoutstringautoSeconds of silence to end speech (2-10, or auto)

DTMF Settings

AttributeTypeDefaultDescription
numDigitsinteger32Maximum digits to collect (1-32)
finishOnKeystring#Key to submit input (digit, #, *, none)

Speech Settings

AttributeTypeDefaultDescription
languagestringen-USSpeech recognition language
speechModelstringdefaultASR model: default, command_and_search, phone_call
hintsstring-Comma-separated phrases to boost recognition
profanityFilterbooleanfalseFilter profane words

Callbacks

AttributeTypeDefaultDescription
interimSpeechResultsCallbackURL-URL for real-time speech results
interimSpeechResultsCallbackMethodstringPOSTHTTP method for interim callback

Input Types

DTMF Only

Collect only digit presses:
<GetInput action="/handle-input/" inputType="dtmf" numDigits="4">
    <Speak>Enter your 4-digit PIN.</Speak>
</GetInput>

Speech Only

Collect only speech input:
<GetInput action="/handle-input/" inputType="speech" language="en-US">
    <Speak>What city would you like to search?</Speak>
</GetInput>

Both Speech and DTMF

Accept either input type (first detected wins):
<GetInput action="/handle-input/" inputType="dtmf speech">
    <Speak>Say your request or press 1 for help.</Speak>
</GetInput>

Speech Recognition Models

ModelBest For
defaultGeneral long-form audio
command_and_searchShort commands and voice search
phone_callPhone call audio (varied quality)
<GetInput action="/handle-input/"
          inputType="speech"
          speechModel="command_and_search"
          language="en-US">
    <Speak>What would you like to do?</Speak>
</GetInput>

Improve Speech Recognition

Use hints to boost recognition of specific words:
<GetInput action="/handle-input/"
          inputType="speech"
          hints="account balance, transfer money, pay bill, customer service">
    <Speak>How can I help you with your account today?</Speak>
</GetInput>
Limits:
  • Max 500 phrases per request
  • Max 10,000 characters total
  • Max 100 characters per phrase

Real-Time Speech Results

Get interim transcription results as the user speaks:
<GetInput action="/final-result/"
          inputType="speech"
          interimSpeechResultsCallback="https://example.com/interim/">
    <Speak>Please describe your issue.</Speak>
</GetInput>

Interim Callback Parameters

ParameterDescription
StableSpeechConfident transcription so far
UnstableSpeechCurrent guess (may change)
StabilityConfidence score (0.0-1.0)
SequenceNumberOrder of callbacks

Supported Languages

Common languages include:
LanguageCode
English (US)en-US
English (UK)en-GB
English (Australia)en-AU
Spanish (US)es-US
Spanish (Spain)es-ES
Frenchfr-FR
Germande-DE
Italianit-IT
Portuguese (Brazil)pt-BR
Japaneseja-JP
Chinese (Mandarin)zh-CN

GetInput Action URL Parameters

When input is collected:
ParameterDescription
InputTypedtmf or speech
DigitsDigits entered (empty if speech)
SpeechTranscribed text (empty if DTMF)
SpeechConfidenceScoreConfidence (0.0-1.0)
BilledAmountTranscription cost
Plus all standard request parameters.

Handling Input on Your Server

# Flask example
@app.route('/handle-input/', methods=['POST'])
def handle_input():
    input_type = request.form.get('InputType')
    response = plivoxml.ResponseElement()

    if input_type == 'dtmf':
        digits = request.form.get('Digits')
        if digits == '1':
            response.add(plivoxml.SpeakElement('Connecting you to sales.'))
            # Add dial logic
        elif digits == '2':
            response.add(plivoxml.SpeakElement('Connecting you to support.'))
            # Add dial logic

    elif input_type == 'speech':
        speech = request.form.get('Speech', '').lower()
        confidence = float(request.form.get('SpeechConfidenceScore', 0))

        if confidence < 0.5:
            response.add(plivoxml.SpeakElement("I didn't catch that. Please try again."))
            response.add(plivoxml.RedirectElement('/start/'))
        elif 'balance' in speech:
            response.add(plivoxml.SpeakElement('Your current balance is $150.'))
        elif 'transfer' in speech:
            response.add(plivoxml.RedirectElement('/transfer-flow/'))
        else:
            response.add(plivoxml.SpeakElement("I'm not sure how to help with that."))

    return Response(response.to_string(), mimetype='application/xml')

GetInput Nested Elements

<GetInput> can contain:
  • <Speak> - Voice prompt
  • <Play> - Audio prompt

Speech Recognition Pricing

Speech recognition is billed per 15-second increment.