Capturing DTMF Input with Read()

IVR -- Last reviewed 2026-08-22 dtmf ivr dialplan read input extensions pin saydigits Found this useful? Upvote it. ×

Capturing DTMF Input with Read()

Read() plays a sound prompt and waits for the caller to enter DTMFDual-Tone Multi-Frequency, the touch-tone signals phones send for digit input during a call, used by IVRs and feature codes. digits, storing the result in a channelA single call leg passing through Asterisk. Channels represent connections to endpoints and are what dialplan applications act on. variable. This is the foundation of PIN entry, extensionA dialplan entry that matches a dialed number or pattern within a context and triggers a sequence of prioritized steps. lookups, account number input, and any IVR that needs numeric data from the caller.

Basic Example

[ivr]
exten => s,1,Answer()
 same => n,Wait(1)
 same => n,Read(DIGITS,enter-ext-of-person,4)
 same => n,Playback(you-entered)
 same => n,SayDigits(${DIGITS})
 same => n,Hangup()

PIN Verification

[pin-entry]
exten => s,1,Answer()
 same => n,Read(PIN,agent-pass,6)
 same => n,GotoIf($["${PIN}" = "123456"]?valid:invalid)
 same => n(valid),Playback(auth-thankyou)
 same => n,Goto(internal,s,1)
 same => n(invalid),Playback(vm-incorrect)
 same => n,Goto(s,1)

Extension Lookup

[dial-by-extension]
exten => s,1,Answer()
 same => n,Read(EXT,enter-ext-of-person,4,,,5)
 same => n,GotoIf($["${EXT}" = ""]?timeout)
 same => n,Dial(PJSIP/${EXT},20)
 same => n,Hangup()
 same => n(timeout),Playback(vm-goodbye)
 same => n,Hangup()

How it works

  1. Read(variable,filename,maxdigits,options,attempts,timeout): Plays the sound file and waits for DTMF input. Digits are collected until maxdigits is reached or the caller presses #. The result is stored in variable.
  2. maxdigits: Limits how many digits are accepted. For a 4-digit extension, use 4. For open-ended input, omit this parameter and the caller terminates with #.
  3. timeout: The last parameter is the timeout in seconds. If the caller doesn't press any key within this time, Read() returns with an empty variable. Default is 10 seconds if not specified.
  4. Sound files: enter-ext-of-person and you-entered are built-in Asterisk sound files. They're searched in /var/lib/asterisk/sounds/<language>/. Use Playback() before Read() if you need to play additional contextA named section of the dialplan that groups extensions. Calls enter a specific context and can only reach extensions visible from it, making contexts the basic unit of call routing and security..
  5. Empty input: Always check for empty input with GotoIf($["${DIGITS}" = ""]?label) to handle timeouts and callers who don't enter anything.

Tips

User Notes

Know a tip or gotcha for this topic? Share it below and help others.

Contribute a note

Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.

Moderated before publishing. Email never shown.
Related Snippets