Your First Asterisk Dialplan
By Prabath Thalangama· October 24, 2026· 4 min read
#asterisk#voip#dialplan
Introduction¶
Asterisk routes calls by executing a dialplan — priority-ordered steps
grouped into contexts. Endpoints (phones, trunks) are defined separately
(these days in pjsip.conf). This is a minimal but real setup.
Endpoints (pjsip.conf)¶
[transport-udp]
type = transport
protocol = udp
bind = 0.0.0.0:5060
; --- an internal phone, extension 1001 ---
[1001]
type = endpoint
context = internal
disallow = all
allow = ulaw,alaw
auth = 1001-auth
aors = 1001
[1001-auth]
type = auth
auth_type = userpass
username = 1001
password = a-strong-secret
[1001]
type = aor
max_contacts = 1
; --- a SIP trunk to an ITSP ---
[trunk]
type = endpoint
context = from-trunk
disallow = all
allow = ulaw,alaw
outbound_auth = trunk-auth
aors = trunk
from_user = 0111234567
from_domain = sip.itsp.example
[trunk-auth]
type = auth
auth_type = userpass
username = 0111234567
password = trunk-secret
[trunk]
type = aor
contact = sip:sip.itsp.example:5060
[trunk-identify]
type = identify
endpoint = trunk
match = sip.itsp.example
Dialplan (extensions.conf)¶
[globals]
TRUNK = PJSIP/trunk
[internal]
; internal extensions 1000-1099
exten => _10XX,1,NoOp(Call from ${CALLERID(num)} to ${EXTEN})
same => n,Dial(PJSIP/${EXTEN},20)
same => n,Goto(voicemail,${EXTEN},1)
; voicemail retrieval
exten => *97,1,VoiceMailMain(${CALLERID(num)}@default)
; outbound: 0 + national number, or 00 + international
exten => _0.,1,NoOp(Outbound ${EXTEN})
same => n,Set(CALLERID(num)=0111234567)
same => n,Dial(${TRUNK}/${EXTEN},60)
same => n,Hangup()
; the IVR / main menu
exten => 100,1,Answer()
same => n,Background(custom/welcome) ; "Press 1 for sales, 2 for support"
same => n,WaitExten(5)
exten => 1,1,Dial(PJSIP/1001,20)
exten => 2,1,Dial(PJSIP/1002,20)
exten => i,1,Playback(pbx-invalid) ; invalid input
same => n,Goto(100,1)
exten => t,1,Playback(vm-goodbye) ; timeout
same => n,Hangup()
[voicemail]
exten => _10XX,1,VoiceMail(${EXTEN}@default,u) ; u = play "unavailable" greeting
same => n,Hangup()
[from-trunk]
; inbound DID -> IVR
exten => 0111234567,1,Goto(internal,100,1)
exten => _X.,1,Goto(internal,100,1)
The concepts¶
- Context (
[internal]) — a namespace. An endpoint'scontext=is where its calls start. This is your security boundary:from-trunkmust not be able to reach the outbound-dial extensions, or you have toll fraud. - Extension (
exten =>) — a dialled string or pattern. Patterns:_prefix,X=0-9,Z=1-9,N=2-9,.=one-or-more,!=zero-or-more._10XXmatches 1000–1099. - Priority — steps run in order:
1, thenn(next), thennagain. Labels:same => n(retry),...+Goto(retry). - Application —
Dial,Playback,Background,VoiceMail,Hangup,Set,Goto,NoOp.Dial(PJSIP/1001,20)rings for 20s. - Special extensions:
i(invalid),t(response timeout),s(start, when no extension was given),h(hangup handler),T(absolute timeout).
Reloading and testing¶
asterisk -rx "dialplan reload"
asterisk -rx "pjsip reload"
asterisk -rx "dialplan show internal"
asterisk -rx "pjsip show endpoints"
Verification and troubleshooting¶
asterisk -rvvvvv # console with verbosity
asterisk -rx "pjsip set logger on" # SIP trace
asterisk -rx "core show channels"
asterisk -rx "dialplan show 1001@internal"
- Phone won't register —
pjsip show endpoint 1001(checkauth/aorslinkage), wrong password, NAT (rewrite_contact/rtp_symmetric/external_media_addressfor the trunk), or 5060 blocked. - Call connects, no audio / one-way — RTP, not SIP. NAT: set
external_media_address,external_signaling_address,local_neton the transport; open the RTP port range (rtp.conf). - "All circuits are busy" on outbound — trunk not registered /
identifynot matching, wrongcontexton the trunk endpoint, or the dialplan pattern didn't match (dialplan showthe exact number). - Inbound DID rings nowhere —
from-trunkcontext has no matchingextenfor the DID the ITSP sends (they may send it with/without country code, or as the SIP user).NoOp(${EXTEN})to see what actually arrives. - Toll fraud risk — an endpoint or the
from-trunkcontext can reach_0.outbound. Keep untrusted contexts free of trunk-dialing extensions;allowguest=no. - IVR: DTMF not detected — DTMF mode mismatch (
dtmf_mode = rfc4733on the endpoint), orBackgroundvsRead; tryRead()for reliable digit collection. dialplan reloaddidn't apply — a syntax error aborted the parse;dialplan showstill shows the old plan. Check the console for the error line.
Related tools and reading¶
- On-site: Port Checker (5060), Ping test.
- Related posts: SIP registration and INVITE flow, SIP trunk basics for sysadmins.
Related tools
Stuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.More in Telecom Systems
Telecom Systems· 4 min read
SMSC Basics for Sysadmins
The SMSC is the store-and-forward hub for text messages. Here's the message paths (MO, MT, AO, AT), how retries work, and a Kannel config to get started.
October 24, 2026Telecom Systems· 5 min read
eSIM and Remote SIM Provisioning
An eSIM is a reprogrammable chip (eUICC) that holds downloadable operator profiles. Here's the GSMA RSP architecture — SM-DP+, SM-DS, LPA — and the profile lifecycle.
October 24, 2026Telecom Systems· 3 min read
SIP Trunk Basics for Sysadmins
A sysadmin's view of SIP trunking — signalling vs media, the ports involved, and why one-way audio is almost always NAT.
October 24, 2026