Skip to content
VoicegatherDigitsstable

Collect digits

Plays a prompt and waits for the caller to press buttons on their phone. Multi-digit input is supported — set Min/Max digits and an end-of-input key (e.g.…

What it does

Plays a prompt and collects digits the caller presses on their phone keypad. The prompt can be TTS or an audio file, and the digit window opens as soon as Telnyx finishes the prompt — so a caller who knows what they want can press over the prompt without waiting. Multi-digit input is supported via Min digits, Max digits, and an optional End-of-input key (typically #) for variable-length entries like a PIN or a bet amount.

When the gather completes, captured digits land in vars.gatheredDigits and Telnyx's reason (valid | timeout | invalid_digits | cancelled) in vars.gatheredReason. The node has three outgoing edges: call.gather.ended for a successful entry, call.gather.timeout when no digit was pressed before the wait expired, and call.gather.invalid when the caller pressed something outside the allowed digits. The worker synthesizes the timeout/invalid events from the gather reason and prefers them when wired; if you only wire call.gather.ended, all three reasons fall back to it for back-compat with older flows. The node also supports cases on itself, so a one-of-many menu can branch directly out of the gather without a separate branch node.

When to use it

  • IVR menu: "Press 1 for sales, 2 for support" — branch via cases on vars.gatheredDigits
  • Account / PIN entry — set Min/Max digits and a # end-of-input key
  • Two-tier menu: gather a digit, route via cases, then gather a second digit on a sub-menu node
  • Capture a one-time confirmation press ("Press any key to continue") with min/max both set to 1
  • Variable-length entry (bet amount, account number) where the caller presses # to submit

Configuration

Plays a prompt and waits for the caller to press buttons on their phone. Multi-digit input is supported — set Min/Max digits and an end-of-input key (e.g. #) for variable-length entries like a bet amount or PIN. The digits land in vars.gatheredDigits and Telnyx's reason ('valid' | 'timeout' | 'invalid_digits' | 'cancelled') in vars.gatheredReason. Three outgoing edges: call.gather.ended fires on a successful entry; call.gather.timeout fires when no digit was pressed before the wait expired; call.gather.invalid fires when the caller pressed something outside the Allowed digits. Wire just call.gather.ended if you don't care about the cause — the timeout/invalid edges fall back to it when not wired.

FieldLabelTypeRequiredDefaultNotes
promptPromptpromptRequired{"kind":"text","text":""}TTS or audio file. The caller hears it, then has the digit-collection window to press buttons.
validDigitsAllowed digitstextOptional12Digits the caller is allowed to press. Leave blank to allow all 0–9, *, #.
minimumDigitsMin digits to collectnumberOptional1
maximumDigitsMax digits to collectnumberOptional1
timeoutMillisInitial wait (ms)numberOptional5000How long to wait for the first digit before timing out.
interDigitTimeoutMillisTime between digits (ms)numberOptional2000Used when collecting multiple digits — how long to wait between presses before considering the entry complete.
terminatingDigitEnd-of-input keytextOptional#Digit the caller can press to submit early.

Outgoing events: call.gather.ended, call.gather.timeout, call.gather.invalid, call.hangup

Examples

Basic main menu

A single-digit menu that branches to one of three routes via cases on vars.gatheredDigits.

{
  "id": "main-menu",
  "type": "gatherDigits",
  "config": {
    "prompt": {
      "kind": "text",
      "text": "Press 1 for sales, 2 for support, 3 for billing.",
      "voice": "female",
      "language": "en-US"
    },
    "validDigits": "123",
    "minimumDigits": 1,
    "maximumDigits": 1,
    "timeoutMillis": 5000
  },
  "cases": [
    { "when": "vars.gatheredDigits == '1'", "next": "route-sales" },
    { "when": "vars.gatheredDigits == '2'", "next": "route-support" },
    { "when": "vars.gatheredDigits == '3'", "next": "route-billing" }
  ],
  "on": {
    "call.gather.timeout": "no-input-fallback",
    "call.gather.invalid": "invalid-fallback",
    "call.hangup": "end"
  }
}

The cases run on call.gather.ended (the success path). Timeouts and invalid presses route to dedicated fallback nodes via the synthesized edges.

Multi-digit PIN with submit key

A four-to-six-digit PIN with # as the submit key. Captures the entry into vars.gatheredDigits and advances on success.

{
  "id": "pin-entry",
  "type": "gatherDigits",
  "config": {
    "prompt": { "kind": "text", "text": "Enter your PIN, then press pound." },
    "validDigits": "0123456789",
    "minimumDigits": 4,
    "maximumDigits": 6,
    "timeoutMillis": 8000,
    "interDigitTimeoutMillis": 3000,
    "terminatingDigit": "#"
  },
  "on": {
    "call.gather.ended": "validate-pin",
    "call.gather.timeout": "pin-timeout",
    "call.gather.invalid": "pin-timeout",
    "call.hangup": "end"
  }
}

The interDigitTimeoutMillis controls the gap between presses — Telnyx considers the entry done after that interval expires (or when the caller presses #).

Gotchas

  • Reason events are synthesized from vars.gatheredReason. Telnyx fires only call.gather.ended. The worker reads the reason field and synthesizes call.gather.timeout (no digits + reason contains "timeout") or call.gather.invalid (reason contains "invalid"), then tries the synthesized event before falling back to call.gather.ended. Wire whichever edges you want to handle distinctly; unwired ones collapse to call.gather.ended.
  • An audio prompt fires call.playback.ended, not call.speak.ended. The worker auto-translates call.playback.endedcall.gather.ended on this node so you don't need parallel edges. Wire only the gather events.
  • Cases are evaluated only on the success event. Cases on this node run when the gather succeeds (effectively call.gather.ended). Timeout and invalid go through the dedicated edges — don't try to write a case for "no digits" by checking vars.gatheredDigits == ''. Use call.gather.timeout.
  • validDigits is a whitelist of allowed presses, not a regex. It's a string like "12345". Anything outside fires call.gather.invalid. There's no built-in regex match — for fancy validation, gather then pass vars.gatheredDigits through a customScript.
  • No prompt at all is legal but rarely what you want. If the prompt is empty, Telnyx opens the gather window with silence. The caller hears nothing and either presses something or times out. Use a real prompt; if you truly want a silent gather, use a say with a brief beep or no-op prompt before the node.