> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.telekesher.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.telekesher.dev/_mcp/server.

# DTMF events

DTMF events are fired when callers press keys on their phone keypad. These include individual key-press events and aggregated digit collection results from the `play_and_get_digits` command.

## dtmf.received

Fired when the caller presses a DTMF key during the call. This event fires independently of any command — individual key presses are reported as they occur during playback, recording, or any other call state.

**Payload schema**

| Field          | Type    | Description                                                                                                                                        |
| -------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event`        | string  | Always `"dtmf.received"`. **Required**                                                                                                             |
| `session_uuid` | string  | Unique session identifier. **Required**                                                                                                            |
| `digit`        | string  | Single DTMF character: `0`-`9`, `A`-`D`, `*`, or `#`. **Required**                                                                                 |
| `duration_ms`  | integer | Key press duration in milliseconds. **Required**                                                                                                   |
| `timestamp`    | string  | RFC 3339 / ISO 8601 UTC timestamp at which the event was emitted (e.g. `"2025-06-06T08:53:24.123Z"`). Present on every webhook event. **Required** |

```json
{
  "event": "dtmf.received",
  "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "digit": "5",
  "duration_ms": 120,
  "timestamp": "2025-06-06T08:53:24.123Z"
}
```

Valid `digit` values are `0`–`9`, `A`–`D`, `*`, and `#`. A letter-digit example:

```json
{
  "event": "dtmf.received",
  "session_uuid": "acW68-...",
  "digit": "A",
  "duration_ms": 100,
  "timestamp": "2025-06-06T08:53:24.500Z"
}
```

## digits.collected

Fired once when a `play_and_get_digits` command finishes its single prompt-and-collect cycle. It aggregates the key presses into a single result with a `status` describing the outcome. The command never retries on its own — your app inspects `status` and decides whether to re-prompt. See [Play prompt and collect DTMF digits](/api/collect-keypad-input/collect).

Individual [`dtmf.received`](#dtmfreceived) events also fire during digit collection. Use [`digits.collected`](#digitscollected) for the final aggregated result and [`dtmf.received`](#dtmfreceived) events if you need per-key feedback as each digit arrives.

**Event filtering.** [`dtmf.received`](#dtmfreceived) and [`digits.collected`](#digitscollected) are independent webhook events. By default both are delivered.

**Payload schema**

| Field            | Type   | Description                                                                                                                                                |
| ---------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event`          | string | Always `"digits.collected"`. **Required**                                                                                                                  |
| `session_uuid`   | string | Unique session identifier. **Required**                                                                                                                    |
| `operation_uuid` | string | The `operation_uuid` echoed from the 202 ack of the `play_and_get_digits` request. **Required**                                                            |
| `digits`         | string | The collected DTMF digit string. May be empty on timeout. **Required**                                                                                     |
| `terminator`     | string | The DTMF key that terminated collection (`0`-`9`, `A`-`D`, `*`, `#`) or empty on timeout. **Required**                                                     |
| `status`         | string | Outcome of the prompt-and-collect cycle. One of: `success`, `no_input`, `partial_then_timeout`, `invalid`, `failure`, `cancelled`, `unknown`. **Required** |
| `timestamp`      | string | RFC 3339 / ISO 8601 UTC timestamp at which the event was emitted (e.g. `"2025-06-06T08:53:24.123Z"`). Present on every webhook event. **Required**         |

### Collection Statuses

| Status                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success`              | At least `min_digits` digits were collected and any configured validation passed. Collection may have ended by a terminator key, by reaching `max_digits`, or by the `between_digits_timeout_ms` timer expiring once at least `min_digits` digits had already been entered — all are successes; the digits are delivered either way. With `min_digits: 0`, a caller who presses only a terminator key submits an empty entry: `status` is `success`, `digits` is empty, and `terminator` carries the key that ended collection. |
| `no_input`             | The caller entered no digits at all. `digits` is empty.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `partial_then_timeout` | The caller entered some digits but fewer than `min_digits`, then stopped pressing keys and the inter-digit timer (`between_digits_timeout_ms`) expired before reaching `min_digits`. `digits` holds the partial input.                                                                                                                                                                                                                                                                                                          |
| `invalid`              | Digits were collected but failed the configured `validation.regex`. `digits` holds what was entered.                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `failure`              | The collection failed before any outcome could be classified — the caller hung up before or during the prompt or collection, the call had not yet been answered, or the prompt file could not be played. The `digits` field is usually empty, but may contain partial input that was collected before the failure.                                                                                                                                                                                                              |
| `cancelled`            | The collection was cancelled by the [cancel play\_and\_get\_digits endpoint](/api/collect-keypad-input/cancel). If the command was already running when the `DELETE` arrived, `digits` holds whatever partial input had been collected so far (which may be empty if the caller had not yet pressed a key). If the command was still queued behind another command and had not started, `digits` is always empty.                                                                                                               |
| `unknown`              | An unexpected outcome. Log it and investigate; do not retry the command.                                                                                                                                                                                                                                                                                                                                                                                                                                                        |

Example — success:

```json
{
  "event": "digits.collected",
  "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "operation_uuid": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
  "digits": "1234",
  "terminator": "#",
  "status": "success",
  "timestamp": "2025-06-06T08:53:24.123Z"
}
```

Example — no input:

```json
{
  "event": "digits.collected",
  "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "operation_uuid": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
  "digits": "",
  "terminator": "",
  "status": "no_input",
  "timestamp": "2025-06-06T08:53:24.123Z"
}
```

Example — failure with partial digits:

```json
{
  "event": "digits.collected",
  "session_uuid": "acW68-...",
  "operation_uuid": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
  "digits": "12",
  "terminator": "",
  "status": "failure",
  "timestamp": "2025-06-06T08:53:24.123Z"
}
```

Example — cancelled:

```json
{
  "event": "digits.collected",
  "session_uuid": "acW68-...",
  "operation_uuid": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
  "digits": "",
  "terminator": "",
  "status": "cancelled",
  "timestamp": "2025-06-06T08:53:24.123Z"
}
```

## Triggered by

These events are produced by the following triggers:

* [`dtmf.received`](#dtmfreceived) — automatic: fires on every DTMF key press during active calls.
* [`digits.collected`](#digitscollected) — [play\_and\_get\_digits](/api/collect-keypad-input/collect) command.