Modular Dialplan Organization

Configuration Asterisk 18+ -- Last reviewed 2026-08-22 dialplan configuration include organization best-practices Found this useful? Upvote it. ×

Modular Dialplan Organization

As a dialplanThe core call-routing configuration of Asterisk, written mostly in extensions.conf as contexts, extensions, and priorities that decide how every call is handled. Full definition → grows beyond a few dozen extensions, maintaining everything in a single extensions.conf becomes unmanageable. The #include directive lets you split the dialplanThe core call-routing configuration of Asterisk, written mostly in extensions.conf as contexts, extensions, and priorities that decide how every call is handled. Full definition → across multiple focused files.

File Structure

/etc/asterisk/
  extensions.conf           <- Master file, includes everything
  extensions_main.conf      <- Include hub
  extensions_phones.conf    <- User group contexts
  extensions_services.conf  <- Utility/service extensions
  extensions_cos.conf       <- Class of Service route contexts

Master File (extensions.conf)

[general]
static = yes
writeprotect = no
clearglobalvars = yes

[globals]
TRUNK = PJSIP/trunk-endpoint
RINGTIME = 20

#include extensions_main.conf

Include Hub (extensions_main.conf)

; This file included by extensions.conf
; It includes all the sub-files in the right order

#include extensions_phones.conf
#include extensions_services.conf
#include extensions_cos.conf

Service Extensions (extensions_services.conf)

[services]

; Speaking clock
exten => *86,1,Answer()
 same => n,Playback(silence/1)
 same => n,SayUnixTime()
 same => n,Hangup()

; Echo test
exten => *87,1,Answer()
 same => n,Echo()
 same => n,Hangup()

; Record and playback test
exten => *88,1,Answer()
 same => n,Playback(silence/1)
 same => n,Playback(beep)
 same => n,Record(test_${CALLERID(num)}:wav)
 same => n,Wait(1)
 same => n,Playback(test_${CALLERID(num)})
 same => n,Hangup()

Phone Contexts (extensions_phones.conf)

[office]
include => services
include => internal
include => pstn-local
include => pstn-long-distance
include => catchall

[lobby]
include => services
include => internal
include => catchall

Route Contexts (extensions_cos.conf)

[internal]
exten => _1XXX,1,Dial(PJSIP/${EXTEN},${RINGTIME})

[pstn-local]
exten => _9NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})

[pstn-long-distance]
exten => _91NXXNXXXXXX,1,Dial(${TRUNK}/${EXTEN:1})

[catchall]
exten => _X.,1,Playback(an-error-has-occurred)
 same => n,Congestion()

How it works

  1. #include filename: A preprocessor directive that inserts the contents of the named file at that point. It runs at parse time, so the result is as if everything were in one file. Paths are relative to /etc/asterisk/.
  2. Include order matters: Files are parsed top-to-bottom. If a 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. is referenced by include => before the file defining it is #include'd, the dialplan will still work because include => is resolved at runtime, not parse time. However, keeping #include order logical aids readability.
  3. #include vs include =>: These are completely different. #include is a file-level preprocessor directive that pulls in another config file. include => is a dialplan directive that makes one context search another context for extensionA dialplan entry that matches a dialed number or pattern within a context and triggers a sequence of prioritized steps. matches.
  4. [globals] section: Define shared variables (trunkA connection between Asterisk and another PBX or an ITSP/carrier, used to send and receive external calls. name, ring timeout, etc.) once in extensions.conf. All contexts across all included files can reference ${TRUNK} and ${RINGTIME}.
  5. static = yes: Prevents the dialplan from being modified at runtime via AMIAsterisk Manager Interface. A TCP socket API for monitoring events and issuing actions in Asterisk, commonly used by click-to-dial integrations and dashboards. or pbx_config. This is the safest setting for file-based dialplans.

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