VoIP.info Guide

Asterisk dialplan: contexts, patterns and loaded-call evidence

Build a restricted Asterisk 22 call path, then prove its context, match, priorities and runtime behavior separately.

Reviewed 2026-10-19Asterisk 22 LTSIntermediateDocumentation based · not lab tested

Start with the channel's real context

The dialplan organizes actions into contexts. A channel driver sends a new channel to a named context, and Asterisk looks for the requested extension from there. An extension is a named sequence of actions rather than necessarily a physical phone, while priorities determine execution order.

Treat the endpoint or trunk context as an authorization boundary. A carrier-facing channel should not automatically inherit internal, premium, international, feature-code or emergency destinations. The file text, endpoint configuration, loaded context and context shown on the actual channel remain separate evidence.

A call follows a dialplan context
An incoming channel enters a context, matches an extension and then runs applications in priority order. A permitted destination can be another endpoint, a trunk or voicemail.

Contexts form a call-permission boundary. Keep untrusted inbound routes separate from privileged outbound patterns.

Keep the first path exact and bounded

The fragment below exposes two exact internal destinations and ends each path explicitly. It assumes the named PJSIP endpoints already exist. The 20-second timeout is an illustrative choice, not a universal policy, and the fragment creates no trunk, emergency or outside-calling route.

Asterisk requires priority 1 and then follows the next priority. The n form is resolved from the preceding priority, but it does not replace inspection of the loaded sequence. An unlisted number failing in this restricted context is expected behavior rather than proof that registration or the PBX failed.

/etc/asterisk/extensions.conf — internal lab only
[lab-internal]
exten => 2101,1,NoOp(Restricted internal call to 2101)
 same => n,Dial(PJSIP/2101,20)
 same => n,Hangup()
exten => 2102,1,NoOp(Restricted internal call to 2102)
 same => n,Dial(PJSIP/2102,20)
 same => n,Hangup()

Understand exact, pattern and include search

Within a context, Asterisk searches explicit extensions before pattern matches, then includes and switches. Pattern extensions begin with an underscore. X, Z and N represent different digit sets; a character set such as [2-5] is narrower still. Asterisk sorts competing patterns by specificity rather than by the order in which they appear in the file.

The period wildcard matches one or more characters, while exclamation can match zero or more and can declare a match complete immediately. Both can match more than decimal digits. Do not use a broad catch-all as a substitute for normalized, authorized destinations, especially where an included context can expose a trunk or feature.

Prevent priority fall-through across matches

Asterisk searches for the next best match at each priority. If an exact extension has priority 1 but no priority 2, a less-specific matching pattern with priority 2 can continue the channel unexpectedly. Overlapping extensions in included contexts can create the same class of surprise.

End a completed branch explicitly, normally with Hangup(), unless continued execution is intentional and documented. Draw included-context relationships, inspect overlapping exact and pattern matches, and give every conditional jump a real target. A successful GotoIf() evaluation is not evidence that its destination exists or that the later call completed.

Prove the loaded match before a live call

Use a supported dialplan reload, then inspect dialplan show lab-internal and the exact lookup dialplan show 2101@lab-internal. The latter is important when patterns or includes could also match. Confirm the running endpoint or trunk enters the intended context; registration success does not establish that call-origin context.

Inspect application help on the running build before copying version-sensitive options. Dial() attempts one or more channels and may continue at the next priority when no requested channel can be called or its timeout expires. Loaded syntax, selected extension, created outbound channel, remote response, bridge and media are separate acceptance stages.

Change, test and roll back one boundary

Record the previous file, the reload result and the loaded before-and-after dialplan. Test one allowed exact number, one denied number, every affected pattern edge, no-answer, busy and unavailable outcomes, then verify normal hangup and resource cleanup. If the change adds an outside route, test authorization and number normalization separately from trunk reachability.

Keep the previous configuration and a rollback command before reloading. A parsed dialplan is not proof of a successful call, and one completed call is not evidence that every overlapping pattern, included context, endpoint class or failure branch is safe. No PBX, dialplan, endpoint, route, call or media path was tested for this guide.

Preserve the Local-channel lifecycle when re-entering dialplan

A Local/extension@context destination creates two internal channel halves and normally optimizes out after answer. Use the Local-channel lifecycle guide to decide whether the layer is necessary, which half executes the requested context, which variables or Dial() options must survive and whether /n is justified. A loaded context does not by itself prove the retained feature, bridge or post-optimization data owner.

Load hints in the intended context

A hint is a special dialplan priority whose extension, context and mapped providers must be confirmed in the running dialplan. The device-state and hints guide separates that mapping and its aggregate state from the PJSIP subscription and handset display.

Use a bounded Gosub instead of duplicating a branch

For reusable dialplan logic, the Gosub guide adds explicit arguments, stack frames, Return() and channel ownership. A loaded target and a returned frame remain narrower evidence than a completed call.

Keep post-bridge targets attached to one channel

The after-bridge guide maps the configured target, next bridge, owner survival and first executed priority instead of treating bridge completion as a whole-call dialplan return.

Keep TALK_DETECT arguments and ownership explicit

Use the TALK_DETECT guide to keep the channel owner, silence milliseconds, talking magnitude and removal point visible in dialplan review.

Make channel-group admission explicit

A channel-group guard needs an exact group, category, channel owner, assignment point, comparison and at-limit destination. The number is local channel state rather than proof of trunk capacity.

Make menu context, match order and timeouts explicit

For an interruptible menu, the BackGround and WaitExten guide records the destination context, explicit extensions, patterns, includes, i and t branches, digit timeout and response timeout rather than treating every keypress as a direct jump.

Treat generated contact strings as dialplan evidence

When ringing multiple PJSIP registrations, record the generated contact dial string, the branch used when it is empty and the actual channels created by Dial().

Run media-offer changes after callee creation

For one outbound PJSIP leg, use the PJSIP_MEDIA_OFFER guide to distinguish lowercase callee pre-dial handling from uppercase caller handling and to preserve the emitted SDP.

Make URI parsing an explicit dialplan boundary

The PJSIP_PARSE_URI guide distinguishes literal-value and variable-name calls, selector-specific absence values and the later authorization or routing branch.

Attach hold interception before the device signal

The HOLD_INTERCEPT guide treats set and remove as write-only, channel-scoped lifecycle actions and preserves a recovery path when the event consumer is unavailable.

Bind each fax session option to the application channel

Use the res_fax guide to keep FAXOPT() writes on the channel that executes ReceiveFAX() or SendFAX() and to preserve the application result before routing continues.

Store RTCP fields with their channel identity

Use the RTCP statistics guide before exporting CHANNEL(rtcp,...) values so the exact PJSIP owner, stream, direction and collection time remain attached to every field.

Preserve response scope when returning from a callee handler

The response-header diagnostic separates reading the 200 response on the callee from carrying one approved value into later caller dialplan.

Handle multi-contact function results without losing identity

The PJSIP AoR/contact guide preserves the comma-separated identifier list before one contact field is selected in dialplan.

Query the endpoint owned by the current PJSIP leg

The PJSIP endpoint inspection guide uses CHANNEL(endpoint) before reading one configuration field and keeps caller and callee ownership separate.

Run the DTMF override on the channel that sends it

The PJSIP_DTMF_MODE workflow uses explicit leg ownership and callee pre-dial timing instead of assuming a caller-side write reaches every outbound channel.

Set transfer ownership before Stasis on the REFER leg

Use the PJSIP_TRANSFER_HANDLING workflow to place a write on the exact PJSIP channel before it enters the ARI application.

Run outbound From-parameter writes on the callee pre-dial leg

The PJSIP_HEADER_PARAM workflow uses lowercase b() to reach each new outbound channel before its INVITE.

Use PJSIPNotify only on a supported maintenance release

The PJSIPNotify application guide covers its version floor, named and inline content, current-dialog behavior and arbitrary-URI dependency.

Place inherited header state before child-channel creation

The PJSIP inheritable-header workflow shows why caller timing, lowercase b() callee mutation and fork-specific evidence matter.

Run media refresh logic on the exact PJSIP channel

The session-refresh guide explains why Local channels, transfers and bridge legs cannot share one implicit refresh state.

Bind header discovery to the current request and channel

The PJSIP header-list diagnostic records the INVITE, channel, prefix and selected instance before changing routing logic.

Place PJSIPHangup before answer and expect termination

The PJSIPHangup workflow shows why an implicit answer or wrong channel defeats the intended response and why priorities after the application are not a continuation branch.

Read outbound PJSIP context on the callee leg

Use a callee pre-dial handler when outbound channel values must be observed before the INVITE. The channel-context diagnostic distinguishes lowercase b() from caller-side B().

Treat MESSAGE state and MessageSend execution as separate steps

The PJSIP MessageSend guide follows MESSAGE() fields, optional MESSAGE_DATA() and MessageSend() handler status without turning one successful application return into delivery.

Make log-group assignment part of the loaded execution path

Use the LOG_GROUP diagnostic to prove the exact channel and priority that writes the group before changing logger state.

Distinguish removed Macro semantics from current Gosub execution

The FreePBX 17 macro-to-Gosub guide records how explicit targets, saved return addresses, frame-local variables and return values replace site-owned Macro assumptions.

Bind frame tracing to the executed channel and priority

Use the frame-trace guide to prove the channel and dialplan point that owns an internal trace, then restore any temporary diagnostic state.

Bound shared-state critical sections

Use the LOCK, TRYLOCK and UNLOCK guide when concurrent channels must update one shared invariant, and keep slow call handling outside the mutex.

Distinguish blank AstDB values from absent keys

The AstDB guide combines DB(), DB_EXISTS(), DB_DELETE() and DB_KEYS() without turning one blank read into proof that the key never existed.

Treat time selection as one loaded-priority decision

Use the Asterisk time-routing guide to distinguish GotoIfTime, ExecIfTime, IFTIME, omitted-label fall-through and the resolved downstream target.

Treat variable scope as part of the loaded call path

Use the Asterisk variable-scope guide to place each write before or after child creation and to distinguish a linked call from a shared variable store.

Make failure control flow visible in each context

Use the exception and application-failure guide to distinguish local i, t and T handling, the current context’s e extension and explicit status branching.

Choose the least powerful dynamic dialplan primitive

Use the lookup and evaluated-subroutine guide to prove an exact target before choosing EVAL_EXTEN() or EVAL_SUB().

Apply JITTERBUFFER before the intended media stage

Use the jitter-buffer policy guide to identify the live channel and direction before setting fixed, adaptive or disabled behavior.

Treat an ODBC lookup as a synchronous branch dependency

The func_odbc guide defines argument, result, timeout and fallback contracts before a database value controls the next dialplan priority.

Give every database write an explicit completion path

The ODBC transaction guide maps accepted, rejected, zero-row, timeout, hangup and uncertain-completion branches before a write enters production.

Create one periodic hook and retain its ID

The periodic-hook guide treats the read form as state creation and the returned ID as the handle for later on or off control.

Bound blocking media waits and branch on their exact contract

The WaitForSilence and WaitForNoise guide separates application duration, iteration count, timeout and immediate status handling.

Defer and bound polled conditions explicitly

The WaitForCondition guide shows why replacement syntax, explicit truth comparison, timeout and interval are part of the loaded dialplan contract.

Keep epoch targets and duration limits type-safe

The WaitUntil guide separates an absolute Unix epoch from seconds-based channel and digit-collection timeouts.

Make Dial ownership and return behavior explicit

The Dial guide distinguishes caller-channel results, callee-channel handlers, bridge exit and the option that authorizes post-call continuation.

Use Originate as a channel-creation boundary

The Originate application guide makes the app and exten argument forms, timeout, wait mode, destination channel and immediate status explicit.

Use Bridge only after the peer channel exists

The Bridge application guide contrasts joining two existing channels with Dial creating an outbound leg.

Keep holding handles distinct from bridge identities

The BridgeWait and BridgeAdd guide follows loaded arguments into holding membership and later bridge addition.

Keep AMI Bridge separate from dialplan Bridge

The AMI bridge-control guide preserves the manager action and dialplan application as different contracts despite their shared name.

Validate every AMI transfer destination as dialplan input

The AMI transfer-control guide keeps context, extension and Redirect priority explicit for each requested leg.

Keep attended-transfer recovery outside destination guesswork

The AMI cancel-and-recovery guide treats abort, callback timing and final topology as explicit state.

Choose whether a Local channel may leave the path

The AMI Local optimization guide covers modifier ownership and state that can disappear with the Local halves.

Relate live dialplan position to a timestamped channel snapshot

The AMI channel snapshots guide keeps context, extension, priority and application state distinct from later call completion.

Emit bounded, versioned UserEvent data

The AMI UserEvent guide documents event naming, the dialplan body format and consumer-safe correlation.

Keep DEVICE_STATE writes inside the Custom provider boundary

The AMI device-state guide distinguishes dialplan-owned Custom: writes from remote-node synchronization and provider reads.

Keep CustomPresence ownership explicit

The AMI presence-state guide confines PRESENCE_STATE() writes to CustomPresence: and records the writer, reset policy and consumer.

Keep extension-state context and hint mapping explicit

The AMI extension-state guide preserves the loaded context, extension and device mapping instead of inferring them from a display label.

Separate loaded dialplan from its durable owner

The AMI runtime dialplan guide treats a manager mutation as loaded-state change, not undocumented proof of source persistence.

Preserve profile writes and CONFBRIDGE_RESULT in channel order

The ConfBridge profiles guide treats dynamic profile templates, option writes, application entry and the later result as ordered dialplan evidence.

Make structured state observable

Use the HASH and ARRAY guide to keep writer, channel, exact key, snapshot time, delimiter shape and later branch independently observable.

Make dynamic dial membership a visible contract

Use the DIALGROUP guide to record the list owner, operation, exact readback and fallback before interpreting a call result.

Make remote lookups an explicit dialplan dependency

Use the Asterisk CURL guide to document the approved destination, effective options, response contract and safe fallback.

Treat filtering and validation as different operations

Use the input-validation guide to reject an unexpected FILTER transformation before a changed value enters routing.

Keep target existence separate from route selection

Use the DIALPLAN_EXISTS migration guide before replacing a deprecated check or assuming a positive result selects one pattern.

Keep bridge features outside normal dialplan flow

Use the custom dynamic features guide before mapping an application that expects PBX-core flow.

Watch the explanation

Asterisk Tutorial 06 - Asterisk Dialplan Introduction [english]pascom GmbH · 11:55 · Legacy

Starts with an extension-not-found error, then builds a small context and follows its priorities in the Asterisk console. A concrete introduction to how an incoming channel finds dialplan instructions.

Read applicability and editorial notes →
Watch this video here

Historical 2014 tutorial. Contexts and priorities remain relevant; the chan_sip endpoint commands do not apply to Asterisk 22. Review used the available transcript and primary references; audio and screen readability remain unverified.

The player loads only when you choose Watch here. Playback uses YouTube’s privacy-enhanced embed; YouTube processes playback data.

Sources & applicability

Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.

Examples require adaptation to your topology. No live PBX or hardware testing is claimed.