Asterisk course

Asterisk Dialplan Extensions: Syntax, Priorities, Applications, and Contexts

Learn how Asterisk extensions work in extensions.conf, including syntax, priorities, applications, contexts, pattern matching, call flow, and troubleshooting.

An Asterisk extension is a sequence of dialplan instructions that controls how Asterisk handles a call. Despite its name, an extension is not necessarily a physical telephone. It may be a number, feature code, incoming-call destination, pattern, or named dialplan entry.

A call enters a context, Asterisk matches an extension in that context, and the matching extension executes its priorities in order. Each priority invokes an Asterisk application, such as Answer(), Playback(), Dial(), or Hangup().

What an Asterisk Extension Does

The dialplan is the set of routing and call-processing instructions followed by Asterisk. An extension is one named or numbered sequence within that dialplan.

For example, extension 200 might answer a call, play an announcement, and hang up. Extension 201 might call a PJSIP endpoint. A feature code such as *98 might invoke a service, while a pattern might match a whole family of outbound numbers.

  • An extension can represent a numeric internal destination.
  • It can represent a service code or feature.
  • It can be the target for an incoming trunk call.
  • It can match a range of dialed values through a pattern.
  • It can be a named entry point used by dialplan logic.

Each extension contains ordered priorities. A priority is one step in the sequence, and each step calls an application with optional arguments.

Where Extensions Are Configured

Static dialplan definitions are traditionally stored in /etc/asterisk/extensions.conf. Definitions are organized under context sections, such as [internal] or [training].

[training]
exten => 200,1,Answer()
same => n,Playback(hello-world)
same => n,Hangup()

Higher-level PBX systems may generate or manage the dialplan. In a managed installation, direct edits to extensions.conf may be overwritten or ignored. Identify the authoritative customization method before changing production routing.

Extension Definition Syntax

The standard form is:

exten => extension_name,priority,application(arguments)

Component | Example | Purpose | Notes

exten keyword | exten | Starts an extension definition. | It tells Asterisk that the line defines a dialplan extension.

Extension name | 200 | Identifies the dialed value or entry point. | It may be numeric, named, special, or a pattern.

Priority | 1 or n | Determines execution order. | Priority 1 is normally the entry point.

Application | Playback | Performs an action. | The application may change call state, route the call, play media, or end execution.

Application arguments | hello-world | Supplies values to the application. | Multiple arguments are usually comma-separated and their order matters.

The => separator separates the exten keyword from the extension name and its instructions. Whitespace is flexible, but consistent alignment and use of same => make a dialplan easier to read.

A context header is different from an extension definition. A header such as [internal] names a group of extensions; it does not itself execute an application.

Extension Names, Special Entries, and Patterns

The extension-name field commonly contains an internal number such as 200. It may also contain a service code, label, or special entry point.

Form | Meaning | Typical use

Numeric extension | A number such as 200. | Internal users or direct destinations.

Named extension | A nonnumeric name. | Service entries or readable dialplan targets.

s | Start or default entry point. | Calls entering without a usable called number, such as some menus.

i | Invalid input. | Digits do not match an available menu entry.

t | Timeout. | The caller provides no input before the collection timeout.

h | Hangup handling. | Cleanup or logging after the channel hangs up.

e | Exception handling. | Handling certain exceptional call-flow conditions where supported.

Numeric priority | Explicit step number. | Precise ordering or compatibility with older dialplans.

n priority | Next sequential priority. | Adding steps without renumbering later lines.

Named label | Readable branch target. | Labels make conditional and transferred flow easier to maintain.

Pattern extension | A matching rule beginning with _. | Routing a family of numbers.

A leading underscore marks a pattern extension. In _3XXX, X matches a digit from 0 through 9, so the pattern matches four-digit values beginning with 3.

[internal]
exten => _3XXX,1,NoOp(Matched internal pattern: ${EXTEN})
same => n,Dial(PJSIP/${EXTEN},20)
same => n,Hangup()

Exact matching is preferred when one specific destination is intended. Patterns are useful for number ranges, but broad patterns can accidentally expose destinations or outbound routes.

Priorities and Execution Order

A priority determines when an application runs within a matched extension. The usual entry point is priority 1.

[training]
exten => 200,1,Answer()
same => n,Playback(hello-world)
same => n,Hangup()

These steps execute as priority 1, priority 2, and priority 3. The n value means “the next priority,” allowing Asterisk to calculate the sequential number.

Priorities belong to a particular extension in a particular context. Priority 2 of 200 is unrelated to priority 2 of 201, and an extension with the same name in another context has a separate sequence.

Named priorities or labels provide readable branch targets where supported. A label can identify a meaningful location such as failed rather than requiring a fragile hard-coded number. Execution can reach a label with a transfer such as Goto(failed), or with a fully qualified destination such as Goto(context,extension,failed).

When execution reaches the end of the available priorities, the call normally terminates unless an application has already transferred execution, bridged the call, or otherwise ended the channel. Do not assume that every application leaves the call in the same state.

Applications and Arguments

An Asterisk application is a callable action performed by a dialplan step. An application’s arguments configure its behavior. Argument order is significant, so consult the documentation for the Asterisk version and application in use.

Application | Primary purpose | Typical next-step consideration

Answer() | Answers the channel. | Continue with media or call processing.

Playback() | Plays a sound file. | Continue, collect input, or terminate after playback.

Dial() | Attempts to call one or more destinations. | Provide post-dial handling for failure, busy, or no answer.

VoiceMail() | Sends a caller to a voicemail mailbox. | Usually terminate or provide an alternate route afterward.

Goto() | Transfers execution to another context, extension, or priority. | Ensure the destination exists and does not create an unintended loop.

GotoIf() | Makes a conditional transfer. | Verify both true and false destinations.

NoOp() | Writes an informational message without changing call flow. | Useful for diagnostics and documenting decisions.

Hangup() | Ends the channel. | Place it after intentional terminal behavior.

Applications may affect call state, collect digits, play media, route calls, invoke external logic, or terminate a channel. An application can also return control to the next priority, transfer control elsewhere, or prevent later priorities from running.

Basic Internal Extension

[training]
exten => 200,1,Answer()
same => n,Playback(hello-world)
same => n,Hangup()

When a call matches 200 in the training context, Asterisk answers it, plays the built-in hello-world prompt, and hangs up.

Calling a PJSIP Endpoint

[internal]
exten => 201,1,NoOp(Calling endpoint 201)
same => n,Dial(PJSIP/201,20)
same => n,NoOp(Dial result: ${DIALSTATUS})
same => n,Playback(vm-nobodyavail)
same => n,Hangup()

Dial(PJSIP/201,20) attempts to call endpoint 201 for up to 20 seconds. If the call is not answered, Dial() may return control to the next priority. The DIALSTATUS variable can help distinguish outcomes such as unavailable, busy, or no answer.

Production logic should intentionally handle those outcomes, for example by sending a busy caller to voicemail, offering an alternate destination, or playing an unavailable announcement.

Feature Code

[internal-services]
exten => *98,1,NoOp(Feature code requested)
same => n,Playback(vm-enter-num-to-call)
same => n,Hangup()

A feature code is an extension name used for behavior rather than a physical phone. Its meaning is defined entirely by the dialplan.

Contexts and Routing Permissions

A context is a named collection of extensions. Contexts form dialplan boundaries and are central to routing permissions. A channel receives its context through channel, endpoint, trunk, or provider configuration.

The same extension number can safely have different behavior in different contexts:

[internal-users]
exten => 100,1,Dial(PJSIP/100,20)
same => n,Hangup()

[inbound-trunk]
exten => 100,1,Playback(company-directory)
same => n,Hangup()

An internal caller in internal-users and an inbound trunk caller in inbound-trunk can both dial 100, but Asterisk selects the definition in the channel’s current context.

An include makes extensions from another context available for matching:

[office-users]
include => internal-services

Applications such as Goto() can explicitly transfer execution to another extension or context. Includes affect what can be matched; they do not mean that every call automatically changes context.

Context type | Typical call sources | Allowed destinations | Security considerations

Internal users | Registered phones and trusted endpoints. | Internal numbers and approved services. | Restrict external routes according to user permissions.

Inbound trunk calls | Carriers and external callers. | Reception, IVR, queues, and explicitly permitted services. | Do not expose unrestricted outbound dialing.

Outbound-routing context | Authorized internal calls. | Approved trunk patterns. | Protect against toll fraud and overly broad patterns.

IVR context | Callers interacting with menus. | Menu destinations and limited services. | Handle invalid input and timeouts without unsafe escape paths.

Emergency calling context | Authorized users placing emergency calls. | Emergency routes and required notifications. | Preserve accurate caller identity and location information.

Call Matching and the Execution Lifecycle

  1. An incoming channel or dialing party supplies a called value, or the call enters a default entry point.
  2. Asterisk determines the channel’s context.
  3. Asterisk performs exact extension matching and, when appropriate, pattern matching.
  4. The selected extension begins at its entry priority, normally priority 1.
  5. Applications execute in priority order.
  6. An application may continue normally, transfer execution, bridge the call, collect digits, or terminate the channel.
  7. The call completes, is transferred, or ends when no further execution remains.

The called number normally selects the initial extension. Later routing decisions may use caller identity, the ${EXTEN} value, channel variables, time conditions, authentication state, or the result of another application.

Dialplan Flow Control

Goto() transfers execution to another priority, extension, or context. A fully qualified form identifies all three locations:

same => n,Goto(internal-services,*98,1)

GotoIf() provides conditional routing. A condition can inspect a channel variable or application result:

same => n,NoOp(Dial result is ${DIALSTATUS})
same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavailable)
same => n(busy),Playback(tt-weasels)
same => n,Hangup()
same => n(unavailable),VoiceMail(201@default)
same => n,Hangup()

The exact condition and media choices should be adapted to the application and Asterisk version. The important design principle is to provide intentional destinations for each meaningful outcome.

Dial() commonly returns control to the next priority when the called party is not connected or when an option causes it to return. Always provide post-Dial() behavior instead of assuming the caller will receive useful handling automatically.

Special Entries for Invalid Input and Timeouts

Menu and digit-collection logic commonly uses i for invalid input and t for timeout. These entries can play feedback and return the caller to a menu, but loops should have a limit or an intentional exit.

[ivr]
exten => s,1,Answer()
same => n,Playback(main-menu)
same => n,WaitExten(5)
exten => i,1,Playback(pbx-invalid)
same => n,Goto(s,1)
exten => t,1,Playback(vm-goodbye)
same => n,Hangup()

For more menu-specific design, see invalid entries and timeouts and automated attendant design.

Testing and Validation

Make small changes, reload them, inspect the loaded dialplan, and test one call path at a time.

asterisk -rvvv
core set verbose 5
dialplan reload
dialplan show
a core show channels

The command above includes an accidental-looking prefix in the last line if copied literally; use the correct CLI command shown here:

core show channels

dialplan show displays the active dialplan. Depending on the Asterisk version, you can narrow inspection by specifying a context or extension, for example dialplan show 200@internal.

Verbose console output helps identify the selected context, matched extension, current priority, application arguments, transfers, and termination conditions. Begin with a harmless Playback() or Echo() test before deploying outbound routing or external logic.

Use comments, descriptive context names, labels, and consistent formatting. Keep changes under safe change management, and verify the active configuration after every reload.

Troubleshooting Dialplan Extensions

Symptom | Likely cause | How to verify | Typical fix

Extension not found | The extension is absent, digits do not match, or the dialplan is stale. | Check verbose output and dialplan show. | Correct the definition or pattern and reload.

Wrong context | The channel or endpoint has an unexpected context. | Inspect channel or endpoint configuration and console output. | Assign the intended context and reload relevant configuration.

Priority missing | A later step is absent or numbering is incorrect. | Review loaded priorities and the last executed step. | Add the step or use n for sequential flow.

Application unavailable | The required application module is not loaded or installed. | Inspect the CLI error and loaded modules. | Install or load the module and verify its availability.

Argument error | Arguments are missing, incorrectly ordered, or unsupported. | Read the application error and check version-specific documentation. | Correct the argument syntax.

Dial falls through after failure | No post-Dial() priority exists or the result is ignored. | Log ${DIALSTATUS} with NoOp(). | Add busy, unavailable, and no-answer handling.

Changes are not active | The wrong file was edited, a generator overwrote it, or reload failed. | Inspect the active dialplan and reload output. | Edit the authoritative source, reload, and verify.

Common Failure Scenarios

If a caller receives an extension-not-found message, identify the context assigned to the channel, verify the dialed digits against the exact or pattern extension, and confirm that the dialplan was reloaded.

If execution stops after the first action, inspect the last executed priority. The next priority may be missing, an explicit number may be duplicated, or the previous application may have transferred or terminated the call.

If an inbound caller can reach prohibited destinations, inspect the inbound context, its includes, and all reachable pattern extensions. Move the trunk to a restricted context and allow only the required destinations.

Exam-Relevant Notes

  • An extension is a dialplan sequence, not necessarily a physical phone.
  • A context contains extensions and acts as a routing and permission boundary.
  • Priority controls execution order; priority 1 is normally the entry point.
  • n means the next sequential priority.
  • Applications perform actions; arguments configure those actions and are order-sensitive.
  • A leading underscore identifies a pattern extension.
  • s, i, t, h, and e are special extension names with distinct call-flow roles.
  • Dial() may return to a following priority, so post-dial handling is important.
  • DIALSTATUS is commonly used to inspect the result of a Dial() attempt.
  • Includes expose extensions from another context, so review them as part of the security model.

Related Asterisk Topics

Continue with what a dialplan is, Asterisk contexts, and dialplan priorities. Application-specific references include Answer(), Playback(), Dial(), Goto(), and Hangup(). For channel data used in routing decisions, see predefined channel variables.