Asterisk PJSIP: Provider Outbound Call (Latest Versions)
Updated guide for modern Asterisk (PJSIP era): provider outbound call with real configs, common mistakes, and troubleshooting steps.
Outbound calling through a SIP provider is one of the most business-critical parts of any Asterisk deployment.
Even when inbound calls work perfectly, outbound failures are common due to:
- Dialplan routing mistakes
- Caller ID rejection by provider
- Codec negotiation problems
- NAT or firewall blocking RTP media
- Provider policy limits or number formatting errors
This guide explains the complete outbound call path using modern PJSIP trunks and shows how to debug every real-world failure scenario.
Outbound Call Flow (Real Telecom Mental Model)
- An extension, IVR, or dialer triggers a Dial() command
- Asterisk selects the correct PJSIP endpoint (trunk)
- Asterisk sends SIP INVITE to the provider
- Provider validates:
- Source IP or registration
- Caller ID permissions
- Dialed number format
- Provider connects the call to PSTN/mobile network
- RTP audio flows between Asterisk and provider gateway
Failure can occur at any layer of this chain.
Basic Outbound Dialplan Pattern
A clean outbound design always:
- Logs the call attempt
- Normalizes number format
- Sets correct caller ID
- Handles provider failure gracefully
[outbound]
exten => _X.,1,NoOp(Outbound attempt: ${EXTEN} from ${CALLERID(all)})
; Normalize number if needed (example: ensure country code)
same => n,Set(DIALNUM=${EXTEN})
; Set approved caller ID (must be allowed by provider)
same => n,Set(CALLERID(num)=1800123456)
; Place outbound call
same => n,Dial(PJSIP/provider-endpoint/${DIALNUM},60)
; If call fails, log cause
same => n,NoOp(Dial status: ${DIALSTATUS} Hangup cause: ${HANGUPCAUSE})
same => n,Hangup()
PJSIP Endpoint Requirements for Outbound Calls
Your provider endpoint must allow outbound media and signaling stability:
[provider-endpoint]
type=endpoint
transport=transport-udp
disallow=all
allow=ulaw,alaw
aors=provider-aor
outbound_auth=provider-auth ; only for registration-based trunks
; NAT/media stability
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
Incorrect codec or NAT settings are a major cause of silent audio.
Number Formatting Problems (Most Common Real Failure)
Providers expect specific dial formats such as:
+919876543210(E.164)00919876543210(international prefix)9876543210(national format)
If the number format is wrong, providers may return:
- 404 Not Found
- 484 Address Incomplete
- 403 Forbidden
Always confirm the required dial format with your provider.
Caller ID Rejection (Very Common in Production)
Providers often restrict which caller IDs you can present.
Symptoms:
- Outbound call fails instantly
- SIP response shows 403 Forbidden
Fix:
- Use a provider-approved DID
- Set it in dialplan or endpoint
from_user
Codec Negotiation Failures
If provider supports only PCMU/PCMA but endpoint allows Opus/GSM, the call may fail with:
- 488 Not Acceptable Here
- Immediate call drop after answer
Restrict codecs explicitly:
disallow=all
allow=ulaw,alaw
NAT and RTP Audio Issues in Outbound Calls
Real-world symptom:
- Call connects successfully
- But one-way or no audio occurs
Root cause is usually:
- Firewall blocking RTP ports
- Incorrect external_media_address
Required firewall rules:
sudo ufw allow 5060/udp
sudo ufw allow 10000:20000/udp
Debugging Outbound Failures Step-by-Step
1. Enable SIP logging
pjsip set logger on
Look for provider response codes:
- 403 → caller ID or permission issue
- 404/484 → wrong number format
- 488 → codec mismatch
- No response → firewall/NAT/network
2. Confirm RTP flow
rtp set debug on
3. Capture packets if unclear
sudo tcpdump -i any -s 0 -w outbound.pcap udp port 5060 or udp portrange 10000-20000
Analyze in Wireshark to confirm SIP + RTP behavior.
Handling Provider Failures Gracefully
Production dialplans should always handle failure paths:
same => n,GotoIf($["${DIALSTATUS}"="BUSY"]?busy)
same => n,GotoIf($["${DIALSTATUS}"="NOANSWER"]?noanswer)
same => n,GotoIf($["${DIALSTATUS}"="CONGESTION"]?congestion)
same => n(busy),Playback(line-busy)
same => n,Hangup()
same => n(noanswer),Playback(vm-nobodyavail)
same => n,Hangup()
same => n(congestion),Playback(all-circuits-busy-now)
same => n,Hangup()
Production Checklist for Reliable Outbound Calling
- Correct number normalization format
- Provider-approved caller ID configured
- Allowed codecs match provider
- Firewall allows SIP + RTP
- NAT external IP configured properly
- SIP logging + tcpdump workflow documented
Key Takeaway
Outbound calling reliability depends on understanding the full telecom chain:
- Dialplan logic
- Provider policies
- Codec compatibility
- Network/NAT behavior
When you debug outbound calls layer-by-layer instead of guessing, even complex provider failures become predictable and solvable.
Want to see API-driven CRM + Telecom workflows in action? Try the WhatsApp bot or explore the demos.
Comments (0)
Be the first to comment.