Asterisk course

Create an Automated Attendant in Asterisk

Build a basic Asterisk automated attendant that plays prompts, accepts DTMF choices, routes callers to SIP endpoints, and handles timeouts.

An automated attendant is a phone menu that answers a call, plays recorded instructions, accepts keypad input, and routes the caller to a destination. It is also commonly called an IVR, or Interactive Voice Response system.

In this lesson, callers dial extension 800 and hear a greeting followed by a menu:

  • Press 1 for sales.
  • Press 2 for marketing.
  • Press 0 for the operator.
  • Make no selection within four seconds to follow the timeout route to the operator.

The destinations in the example are SIP endpoints named alice, bob, and george. Replace them with the endpoint names used in your installation.

Prerequisites

  • A working Asterisk installation and access to the Asterisk CLI.
  • Basic knowledge of dialplans, contexts, extensions, and priorities.
  • Registered and reachable SIP endpoints.
  • Greeting and menu recordings stored where Asterisk can find them.
  • An inbound or internal route that can reach the automated-attendant context.
  • Basic understanding of DTMF, the keypad signaling used by callers to select menu options.

Automated attendant call flow

A caller reaches the attendant by dialing extension 800. Asterisk executes the priorities assigned to extension 800, plays the greeting, plays the menu, waits for DTMF input, and then matches the entered digit against extensions in the active context.

Caller action or eventDialplan applicationResulting behaviorNext destination

Caller dials the IVR number — dialplan entry — Asterisk enters extension 800 — Greeting

Greeting playback — Playback() — Plays the introductory recording — Menu prompt

Menu prompt playback — Background() — Plays the menu while accepting DTMF — WaitExten() or a matching digit extension

Digit 1 — Verbose(), Dial() — Logs the selection and calls sales — SIP/alice

Digit 2 — Verbose(), Dial() — Logs the selection and calls marketing — SIP/bob

Digit 0 — Verbose(), Dial() — Logs the selection and calls the operator — SIP/george

No input before timeout — t extension and Goto() — Logs the timeout and applies the fallback policy — Operator

Define the dialplan context

A dialplan is Asterisk's call-routing logic, commonly stored in extensions.conf. A context is a named scope containing extensions and their priorities. A call can normally match only the extensions available in its current context.

Create an automated-attendant context in extensions.conf. The following example defines the entry extension, three menu choices, and a timeout handler:

[automated-attendant]
exten => 800,1,Playback(our-greeting)
 same => n,Background(main-menu)
 same => n,WaitExten(4)
 same => n,Goto(0,1)

exten => 1,1,Verbose(2,Caller selected sales)
 same => n,Dial(SIP/alice)

exten => 2,1,Verbose(2,Caller selected marketing)
 same => n,Dial(SIP/bob)

exten => 0,1,Verbose(2,Caller selected operator)
 same => n,Dial(SIP/george)

exten => t,1,Verbose(1,Caller ${CALLERID(all)} timed out)
 same => n,Goto(0,1)

The section header [automated-attendant] creates the context. The line beginning with exten => 800,1 creates the dialable IVR entry extension. A caller must be placed into this context, or explicitly transferred to it, for these routes to be available.

Make sure your inbound route, trunk context, phone context, or another dialplan entry point can reach this context. Merely writing a context in extensions.conf does not automatically make extension 800 reachable from every call.

Understand extension priorities

An extension is a dialable number or pattern, but in an IVR it can also be a single menu digit such as 1, 2, or 0. A priority is the execution order of applications within an extension.

For extension 800, priority 1 runs Playback(), the next priority runs Background(), and the following priority runs WaitExten(). The syntax same => n means “use the next automatically numbered priority for the current extension.” This avoids manually writing priority numbers as the dialplan grows.

The numeric choices are separate extensions in the same context. For example, pressing 1 causes Asterisk to execute extension 1 beginning at priority 1. The choice is not an argument passed to extension 800; it is a new dialplan match.

Recordings and prompt playback

Use two distinct recordings: one for the introductory greeting and another for the menu instructions. For example, our-greeting might say, “Thank you for calling our company,” while main-menu might say, “Press 1 for sales, 2 for marketing, or 0 for the operator.”

Playback() plays a recording as a non-interruptible introduction for this purpose. It is appropriate when callers should hear the greeting before the menu begins.

Background() plays the menu prompt while allowing the caller to enter DTMF. This makes it possible for a caller to press a valid option while the menu recording is still playing.

Prompt arguments are usually written as names without filename extensions, such as Playback(our-greeting) and Background(main-menu). Asterisk searches its configured sound-file locations and selects a suitable supported format. The names must correspond to recordings actually installed in the sounds directory. Do not assume that a file copied to an arbitrary directory will be found.

Wait for caller input

WaitExten(4) waits up to four seconds for the caller to enter an extension selection. Asterisk then matches the received DTMF digits against extensions in the current context.

Because the menu advertises 1, 2, and 0, those extensions must exist in the active context. If they are missing, Asterisk cannot route those choices even if the caller's DTMF reaches the server correctly.

The menu prompt and the wait operation have different roles. Background() allows input during the recording; WaitExten() provides an additional defined period for input after the prompt or after the caller stops entering digits.

Route menu selections

Each menu branch uses Verbose() before Dial(). Verbose() writes a diagnostic message to the Asterisk console or log at a selected verbosity level. These messages help distinguish a DTMF matching problem from an endpoint or network problem.

Key pressedDepartment or purposeDialplan extensionTarget endpointDiagnostic message

1 — Sales — 1aliceCaller selected sales

2 — Marketing — 2bobCaller selected marketing

0 — Operator — 0georgeCaller selected operator

Timeout — Fallback operator — tgeorge — Caller ID and timeout message

Dial(SIP/alice) calls the SIP endpoint named alice. The exact technology and endpoint syntax depends on the channel driver and configuration. A PJSIP deployment, for example, normally uses PJSIP endpoint syntax instead of the example's SIP syntax. Replace the target with a valid endpoint for your system.

Handle no-input timeouts

The special t extension is used when a caller times out while Asterisk is waiting for an extension selection. In the example, it logs the combined caller ID value using ${CALLERID(all)}, then sends the call to extension 0 at priority 1.

CALLERID(all) is a channel variable containing combined caller-ID name and number information. It is useful in timeout and troubleshooting messages, although its content depends on the call and provider.

Goto(0,1) moves dialplan execution to extension 0, priority 1, in the current context. That sends a timed-out caller through the operator branch. The explicit Goto(0,1) following WaitExten(4) also provides a fallback if execution continues after the wait rather than being transferred directly to the special timeout extension.

Timeout policy should be deliberate. Sending every timeout back to the menu can create an endless loop, especially if the operator is unavailable and the call returns to the IVR. A production design might allow one retry, then send the caller to an operator, voicemail, or a hangup route. If you intentionally restart the menu, use an explicit target such as Goto(automated-attendant,800,1) and add a retry limit or another exit condition.

Applications used in this attendant

ApplicationRole in the attendantImportant parameter or behavior

Playback() — Plays the greeting — Normally used for a non-interruptible introduction.

Background() — Plays the menu — Accepts matching DTMF extensions while the prompt plays.

WaitExten() — Waits for a selection — Use a defined interval such as four seconds.

Verbose() — Writes diagnostics — The first argument controls the verbosity level.

Dial() — Calls a destination — The channel and endpoint identifier must match the deployment.

Goto() — Transfers dialplan processing — Can target an extension, priority, or context.

Dialplan logic walkthrough

  1. The caller dials 800. Asterisk must have a route that reaches the automated-attendant context.
  2. Priority 1 of extension 800 runs Playback(our-greeting).
  3. The next priority runs Background(main-menu). The caller hears the menu and can enter a digit.
  4. WaitExten(4) waits for input for up to four seconds.
  5. If the caller presses 1, Asterisk matches extension 1, logs the selection, and dials alice.
  6. If the caller presses 2, Asterisk matches extension 2, logs the selection, and dials bob.
  7. If the caller presses 0, Asterisk matches extension 0, logs the selection, and dials george.
  8. If no selection is made, the special t extension handles the timeout and sends the caller to the operator branch.

The main IVR extension, numeric choices, and special timeout extension are related by the current context. They do not need to share the same extension number, but they must be available in the context where Asterisk is matching the caller's input. To use a destination in another context, use an explicit context-qualified Goto() target.

Save, reload, and verify

After saving extensions.conf, connect to the Asterisk CLI and inspect the loaded dialplan:

asterisk -rvvv
dialplan show automated-attendant
dialplan reload

Use dialplan show automated-attendant to confirm that extension 800, extensions 1, 2, and 0, and the t extension are present. Reload after changes, then inspect the console while placing test calls.

Testing checklist

  1. Call extension 800 from a registered endpoint.
  2. Confirm that the greeting is audible and finishes as expected.
  3. Confirm that the menu recording is audible and identifies every advertised choice.
  4. Press 1 and verify that the console reports the sales message and that alice rings.
  5. Press 2 and verify that bob rings.
  6. Press 0 and verify that george rings.
  7. Make no selection for at least four seconds and verify the timeout log and operator route.
  8. Test DTMF while the Background() prompt is playing.
  9. Review Verbose() output to determine whether failures occur during digit matching or endpoint dialing.

Troubleshooting

No greeting or menu audio

  • Check that the recordings exist in an Asterisk sound directory and use a supported audio format.
  • Verify that our-greeting and main-menu match the recording names. Prompt arguments normally omit the filename extension.
  • Use the CLI to look for sound-file errors.
  • Run dialplan show automated-attendant and confirm that the call reaches extension 800 in the expected context.

Pressing 1, 2, or 0 does not route

  • Check CLI output for received DTMF.
  • Confirm that Background() is used for the menu and that WaitExten() follows it.
  • Verify that extensions 1, 2, and 0 exist in the same active context.
  • Check DTMF settings on the endpoint, trunk, or channel configuration.

The caller immediately reaches the operator

  • Confirm that the wait interval is long enough for testing.
  • Trace the priorities in the CLI to determine whether the timeout route is being selected.
  • Validate every extension and priority used by Goto().

The selected phone does not ring

  • Check that the endpoint is registered, reachable, and named correctly.
  • Test dialing the endpoint directly from a working extension.
  • Use the Verbose() message to confirm that the correct IVR branch was reached.
  • Verify that the Dial() technology matches your installation.

Timeouts repeat unexpectedly

  • Map every Goto() destination and the dialplan path after Dial() returns.
  • Check whether an unavailable operator sends the call back into the IVR.
  • Choose an explicit policy: retry once, transfer to an operator, send to voicemail, or hang up.
  • Test several consecutive timeouts to ensure the call has a clear exit condition.