> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Input Collection

> Collect DTMF digits and speech input from callers

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.

> [!NOTE]
>
> **Recommendation:** Use [GetInput](#getinput) instead of GetDigits for new applications. GetInput supports both speech and digit input.

### Basic Usage

```xml theme={null}
<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>
```

```python Python theme={null}
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())
```

```javascript Node.js theme={null}
const plivo = require('plivo');

const response = plivo.Response();
const getDigits = response.addGetDigits({
    action: 'https://example.com/handle-input/',
    numDigits: 1
});
getDigits.addSpeak('Press 1 for sales, press 2 for support.');
response.addSpeak("We didn't receive any input. Goodbye.");
console.log(response.toXML());
```

```ruby Ruby theme={null}
require 'plivo'

include Plivo::XML

response = Response.new
getdigits = response.addGetDigits(
    action: 'https://example.com/handle-input/',
    numDigits: 1
)
getdigits.addSpeak('Press 1 for sales, press 2 for support.')
response.addSpeak("We didn't receive any input. Goodbye.")
puts PlivoXML.new(response).to_xml
```

```php PHP theme={null}
<?php
require 'vendor/autoload.php';
use Plivo\XML\Response;

$response = new Response();
$getdigits = $response->addGetDigits([
    'action' => 'https://example.com/handle-input/',
    'numDigits' => 1
]);
$getdigits->addSpeak('Press 1 for sales, press 2 for support.');
$response->addSpeak("We didn't receive any input. Goodbye.");
echo $response->toXML();
```

```java Java theme={null}
import com.plivo.api.xml.*;

Response response = new Response()
    .children(
        new GetDigits()
            .action("https://example.com/handle-input/")
            .numDigits(1)
            .children(new Speak("Press 1 for sales, press 2 for support.")),
        new Speak("We didn't receive any input. Goodbye.")
    );
System.out.println(response.toXmlString());
```

```csharp .NET theme={null}
using Plivo.XML;

var response = new Response();
var getDigits = new GetDigits(new Dictionary<string, string>() {
    {"action", "https://example.com/handle-input/"},
    {"numDigits", "1"}
});
getDigits.AddSpeak("Press 1 for sales, press 2 for support.");
response.Add(getDigits);
response.AddSpeak("We didn't receive any input. Goodbye.");
Console.WriteLine(response.ToString());
```

```go Go theme={null}
package main

import "github.com/plivo/plivo-go/v7/xml"

func main() {
    response := xml.ResponseElement{
        Contents: []interface{}{
            new(xml.GetDigitsElement).
                Action("https://example.com/handle-input/").
                NumDigits(1).
                SetContents([]interface{}{
                    new(xml.SpeakElement).AddSpeak("Press 1 for sales."),
                }),
            new(xml.SpeakElement).AddSpeak("No input received."),
        },
    }
    print(response.String())
}
```

### GetDigits Attributes

| Attribute | Type | Default | Description |
| - | - | - | - |
| `action` | URL | - | URL to receive the digits |
| `method` | string | `POST` | HTTP method (`GET`, `POST`) |
| `numDigits` | integer | `99` | Maximum digits to collect |
| `timeout` | integer | `5` | Seconds to wait for first digit |
| `digitTimeout` | integer | `2` | Seconds between consecutive digits |
| `finishOnKey` | string | `#` | Key to submit input (digit, `#`, `*`, `none`) |
| `retries` | integer | `1` | Retry attempts if no input |
| `redirect` | boolean | `true` | Redirect to action URL |
| `playBeep` | boolean | `false` | Play beep after nested elements |
| `validDigits` | string | `1234567890*#` | Allowed digits |
| `invalidDigitsSound` | URL | - | Audio for invalid digit |
| `log` | boolean | `true` | Log 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)

```xml theme={null}
<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:

```python theme={null}
# 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:

```xml theme={null}
<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:

```xml theme={null}
<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:

```xml theme={null}
<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):

```xml theme={null}
<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:

| Parameter | Description |
| - | - |
| `Digits` | The digits entered (excluding `finishOnKey`) |

Plus all standard [request parameters](https://plivo.com/docs/voice/xml/overview.md#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

```xml theme={null}
<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>
```

```python Python theme={null}
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())
```

```javascript Node.js theme={null}
const plivo = require('plivo');

const response = plivo.Response();
const getInput = response.addGetInput({
    action: 'https://example.com/handle-input/',
    inputType: 'dtmf speech'
});
getInput.addSpeak('How can I help you today?');
response.addSpeak("We didn't receive any input.");
console.log(response.toXML());
```

```ruby Ruby theme={null}
require 'plivo'

response = Plivo::XML::Response.new
get_input = response.addGetInput(
    action: 'https://example.com/handle-input/',
    inputType: 'dtmf speech'
)
get_input.addSpeak('How can I help you today?')
response.addSpeak("We didn't receive any input.")
puts Plivo::XML::PlivoXML.new(response).to_xml
```

```php PHP theme={null}
<?php
require 'vendor/autoload.php';
use Plivo\XML\Response;

$response = new Response();
$get_input = $response->addGetInput([
    'action' => 'https://example.com/handle-input/',
    'inputType' => 'dtmf speech'
]);
$get_input->addSpeak('How can I help you today?');
$response->addSpeak("We didn't receive any input.");
echo $response->toXML();
```

```java Java theme={null}
import com.plivo.api.xml.*;

Response response = new Response()
    .children(
        new GetInput()
            .action("https://example.com/handle-input/")
            .inputType("dtmf speech")
            .children(new Speak("How can I help you today?")),
        new Speak("We didn't receive any input.")
    );
System.out.println(response.toXmlString());
```

```csharp .NET theme={null}
using Plivo.XML;

var response = new Response();
var getInput = new GetInput(new Dictionary<string, string>() {
    {"action", "https://example.com/handle-input/"},
    {"inputType", "dtmf speech"}
});
getInput.AddSpeak("How can I help you today?");
response.Add(getInput);
response.AddSpeak("We didn't receive any input.");
Console.WriteLine(response.ToString());
```

```go Go theme={null}
package main

import "github.com/plivo/plivo-go/v7/xml"

func main() {
    response := xml.ResponseElement{
        Contents: []interface{}{
            new(xml.GetInputElement).
                SetAction("https://example.com/handle-input/").
                SetInputType("dtmf speech").
                SetContents([]interface{}{
                    new(xml.SpeakElement).AddSpeak("How can I help you today?"),
                }),
            new(xml.SpeakElement).AddSpeak("We didn't receive any input."),
        },
    }
    print(response.String())
}
```

### GetInput Attributes

#### Core Settings

| Attribute | Type | Default | Description |
| - | - | - | - |
| `action` | URL | *required* | URL to receive the input |
| `method` | string | `POST` | HTTP method (`GET`, `POST`) |
| `inputType` | string | - | Input type: `dtmf`, `speech`, `dtmf speech` |
| `redirect` | boolean | `true` | Redirect to action URL after input |
| `log` | boolean | `true` | Log input (disable for sensitive data) |

#### Timing

| Attribute | Type | Default | Description |
| - | - | - | - |
| `executionTimeout` | integer | `15` | Max seconds to wait for input (5-60) |
| `digitEndTimeout` | string | `auto` | Seconds between digits (2-10, or `auto`) |
| `speechEndTimeout` | string | `auto` | Seconds of silence to end speech (2-10, or `auto`) |
| `startInputTimeout` | integer | - | Seconds to wait for the caller to begin providing input. Distinct from `executionTimeout` (total time), `digitEndTimeout` (between digits), and `speechEndTimeout` (end of speech) |
| `retries` | integer | `1` | Number of times to retry input collection if no valid input is received |

#### DTMF Settings

| Attribute | Type | Default | Description |
| - | - | - | - |
| `numDigits` | integer | `32` | Maximum digits to collect (1-32) |
| `finishOnKey` | string | `#` | Key to submit input (digit, `#`, `*`, `none`) |

#### Speech Settings

| Attribute | Type | Default | Description |
| - | - | - | - |
| `language` | string | `en-US` | Speech recognition language |
| `speechModel` | string | `default` | ASR model: `default`, `command_and_search`, `phone_call` |
| `hints` | string | - | Comma-separated phrases to boost recognition |
| `profanityFilter` | boolean | `false` | Filter profane words |

#### Callbacks

| Attribute | Type | Default | Description |
| - | - | - | - |
| `interimSpeechResultsCallback` | URL | - | URL for real-time speech results |
| `interimSpeechResultsCallbackMethod` | string | `POST` | HTTP method for interim callback |

### Input Types

#### DTMF Only

Collect only digit presses:

```xml theme={null}
<GetInput action="/handle-input/" inputType="dtmf" numDigits="4">
    <Speak>Enter your 4-digit PIN.</Speak>
</GetInput>
```

#### Speech Only

Collect only speech input:

```xml theme={null}
<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):

```xml theme={null}
<GetInput action="/handle-input/" inputType="dtmf speech">
    <Speak>Say your request or press 1 for help.</Speak>
</GetInput>
```

### Speech Recognition Models

| Model | Best For |
| - | - |
| `default` | General long-form audio |
| `command_and_search` | Short commands and voice search |
| `phone_call` | Phone call audio (varied quality) |

```xml theme={null}
<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:

```xml theme={null}
<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:

```xml theme={null}
<GetInput action="/final-result/"
          inputType="speech"
          interimSpeechResultsCallback="https://example.com/interim/">
    <Speak>Please describe your issue.</Speak>
</GetInput>
```

#### Interim Callback Parameters

| Parameter | Description |
| - | - |
| `StableSpeech` | Confident transcription so far |
| `UnstableSpeech` | Current guess (may change) |
| `Stability` | Confidence score (0.0-1.0) |
| `SequenceNumber` | Order of callbacks |

### Supported Languages

Common languages include:

| Language | Code |
| - | - |
| English (US) | `en-US` |
| English (UK) | `en-GB` |
| English (Australia) | `en-AU` |
| Spanish (US) | `es-US` |
| Spanish (Spain) | `es-ES` |
| French | `fr-FR` |
| German | `de-DE` |
| Italian | `it-IT` |
| Portuguese (Brazil) | `pt-BR` |
| Japanese | `ja-JP` |
| Chinese (Mandarin) | `zh-CN` |

### GetInput Action URL Parameters

When input is collected:

| Parameter | Description |
| - | - |
| `InputType` | `dtmf` or `speech` |
| `Digits` | Digits entered (empty if speech) |
| `Speech` | Transcribed text (empty if DTMF) |
| `SpeechConfidenceScore` | Confidence (0.0-1.0) |
| `BilledAmount` | Transcription cost |

Plus all standard [request parameters](https://plivo.com/docs/voice/xml/overview.md#request-parameters).

### Handling Input on Your Server

```python theme={null}
# 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.

***

## Related

* [Audio Output](https://plivo.com/docs/voice/xml/audio-output.md) - Speak, Play, DTMF
* [Call Routing](https://plivo.com/docs/voice/xml/routing.md) - Dial, Redirect, Hangup, Wait
