# Gather

The `<Gather>` verb collects DTMF digits, speech or both from the caller, then sends the result to your `action` URL. Use it for menus, PIN entry and any prompt that branches on caller input.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `action` | string (uri) | None | URL to send the result to. When absent, the next verb in the document runs once gathering ends. |
| `method` | string | `POST` | HTTP method used to request `action`. `GET` or `POST`. |
| `input` | string | `dtmf` | Input to accept: `dtmf`, `speech`, or `dtmf speech` (both, in any order). With both, Signals listens for digits and speech at the same time and the first input to complete wins: digits produce `Digits`, a finished transcription produces `SpeechResult`. |
| `timeout` | integer | `5` | Seconds to wait for input before gathering ends with no result. For speech, `speechTimeout` sets the end-of-speech silence window instead. |
| `numDigits` | integer | None | Maximum number of digits to collect. Gathering ends as soon as this many are entered, without waiting for `finishOnKey` or `timeout`. When omitted, up to 128 digits are collected. |
| `finishOnKey` | string | `#` | Key that ends input. A single character: a digit, `*` or `#`. Set to an empty string to disable it. |
| `actionOnEmptyResult` | boolean | `false` | Whether to request `action` when gathering ends with no digits or speech. When `false`, an empty result moves on to the next verb instead. |
| `language` | string | `en-US` | Speech recognition language, as a BCP-47 tag such as `en-US`. Applies only when `input` includes `speech`. |
| `hints` | string | None | Comma-separated words or phrases likely to appear in the caller's speech, to improve recognition. Applies only when `input` includes `speech`. |
| `speechTimeout` | string | None | Seconds of silence after the caller stops speaking before recognition ends, bounded by `timeout`. Set to `auto` to end as soon as the caller stops talking. A number must be a positive integer. When `speechModel` is set, `speechTimeout` must be a number: `auto` and the default are rejected. |
| `speechModel` | string | None | Speech recognition model to use. Requires `speechTimeout` to be a positive integer. |
| `partialResultCallback` | string (uri) | None | URL that receives interim transcripts while the caller is still talking. Applies only when `input` includes `speech`. |
| `partialResultCallbackMethod` | string | `POST` | HTTP method used to request `partialResultCallback`. `GET` or `POST`. |
| `profanityFilter` | boolean | None | Whether to mask profanity in transcripts. Applies only when `input` includes `speech`. |

## Nesting

`<Gather>` may contain `<Say>`, `<Play>` and `<Pause>` as prompts, played while Signals waits for input. A digit pressed during a prompt stops it and skips any remaining prompts; that digit becomes the first digit of the result.

## Action parameters

`<Gather>` sends different parameters to `action` depending on what it collected:

| Name | Type | Description |
|------|------|-------------|
| `Digits` | string | Digits collected. Sent when `input` includes `dtmf` and the caller entered at least one digit. |
| `SpeechResult` | string | Transcribed speech. Sent when `input` includes `speech` and recognition produced a result. |
| `Confidence` | float | Confidence score for `SpeechResult`, from 0 to 1. Sent with `SpeechResult`. |

### Streaming partial results

When `partialResultCallback` is set and `input` includes `speech`, Signals posts each interim transcript to that URL as recognition progresses, in addition to the final result sent to `action`:

| Name | Type | Description |
|------|------|-------------|
| `AccountSid` | string | Your Voice Account SID. |
| `CallSid` | string | Unique identifier for the call. |
| `UnstableSpeechResult` | string | The interim transcript so far. |
| `Confidence` | float | Confidence score for `UnstableSpeechResult`, from 0 to 1. |

:::note
Interim results are not final. Signals does not wait for a response from `partialResultCallback`, and `UnstableSpeechResult` may change before gathering completes.
:::

## Examples

A DTMF menu with two options:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather action="/handle-menu" numDigits="1" timeout="10">
    <Say>For sales, press 1. For support, press 2.</Say>
  </Gather>
  <Say>We did not receive your selection. Goodbye.</Say>
  <Hangup/>
</Response>
```

The `/handle-menu` action handler, complete and runnable:

<CodeTabs syncKey="lang">

```javascript title="Node.js"
const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: false }));

app.post("/handle-menu", (req, res) => {
  const messages = {
    1: "You selected sales. An agent will call you back shortly.",
    2: "You selected support. An agent will call you back shortly.",
  };
  const message = messages[req.body.Digits] || "That is not a valid option. Goodbye.";

  res.type("text/xml").send(`<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>${message}</Say>
  <Hangup/>
</Response>`);
});

app.listen(3000);
```

```python title="Python"
from flask import Flask, Response, request

app = Flask(__name__)

MESSAGES = {
    "1": "You selected sales. An agent will call you back shortly.",
    "2": "You selected support. An agent will call you back shortly.",
}

@app.route("/handle-menu", methods=["POST"])
def handle_menu():
    message = MESSAGES.get(request.form.get("Digits"), "That is not a valid option. Goodbye.")
    oneml = f"""<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>{message}</Say>
  <Hangup/>
</Response>"""

    return Response(oneml, mimetype="text/xml")

if __name__ == "__main__":
    app.run(port=3000)
```

</CodeTabs>

A speech gather with recognition hints:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather input="speech" action="/handle-destination" language="en-US" hints="Lagos, Abuja, Port Harcourt" speechTimeout="auto">
    <Say>Which city are you flying to?</Say>
  </Gather>
</Response>
```

The `/handle-destination` handler reads `SpeechResult` and `Confidence` the same way the menu handler reads `Digits`, from `req.body` (Express) or `request.form` (Flask).

Requesting `action` even when the caller enters nothing:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather action="/handle-pin" actionOnEmptyResult="true" numDigits="4" timeout="5">
    <Say>Enter your four-digit PIN.</Say>
  </Gather>
</Response>
```

With `actionOnEmptyResult="true"`, Signals requests `/handle-pin` even if the caller never enters a digit, so your server can react to silence, for example by repeating the prompt. When the caller enters nothing, `Digits` is absent from the request.

## See also

- [Say](/programmable-voice/oneml/say)
- [Play](/programmable-voice/oneml/play)
- [Record](/programmable-voice/oneml/record)
- [OneML overview](/programmable-voice/oneml/overview)
