Skip to content
Dialer & Setup

Asterisk Dialplan Basics for Outbound Calling Operations

Understanding what FreePBX generates under the hood lets you debug routing failures, add custom logic, and scale outbound campaigns without hitting GUI limitations.

1. What the Dialplan Actually Is

FreePBX is a GUI that writes Asterisk dialplan files. Every trunk, route, extension, and ring group you configure in the FreePBX web interface generates entries in /etc/asterisk/extensions_additional.conf and related include files. When you click Apply Config, FreePBX regenerates these files and reloads the Asterisk dialplan.

The dialplan is structured as a set of contexts, each containing extensions. An extension is a pattern that matches a dialed number, paired with a priority sequence of applications to execute. The core loop for outbound calling is:

  1. An agent or dialer dials a number
  2. Asterisk matches the dialed number against extensions in the from-internal context
  3. The matching extension sends the call through an outbound route
  4. The route selects a trunk and calls Dial(PJSIP/unlimcall-us/${EXTEN})

Everything else — caller ID selection, dial timeout, post-call recording — happens in that priority chain.

2. Reading a FreePBX-Generated Outbound Route

After configuring an outbound route in FreePBX and applying config, examine what was generated:

`` asterisk -rx "dialplan show from-internal" ``

Find your outbound route entries. A typical US domestic route looks like:

``` '_1NXXNXXXXXX' => 1. NoOp(Outbound route: unlimcall-outbound) [from-internal]

  1. Set(OUTRT=unlimcall-outbound)
  2. Set(__MOHCLASS=default)
  3. Gosub(sub-set-cid,s,1(1,NXXNXXXXXX,))
  4. Gosub(sub-record-check,s,1(out,${EXTEN},dontcare))
  5. Macro(user-callerid,LIMIT,EXTERNAL,)
  6. Goto(from-trunk-dial-awayl,${EXTEN},1)

```

The Goto(from-trunk-dial-awayl,...) is where FreePBX hands off to the trunk dialing logic. Understanding this chain lets you inject custom steps — for example, setting a header for carrier-side analytics — without breaking FreePBX's generated logic.

3. Custom Extensions for Outbound Logic

FreePBX provides a safe override file: /etc/asterisk/extensions_custom.conf. Entries here survive fwconsole reload and are not overwritten when FreePBX regenerates config. Use this file for outbound logic that the GUI cannot express.

Example: Set a custom SIP header per campaign number prefix:

`` [from-internal-custom] exten => _1212NXXXXXX,1,NoOp(NYC campaign dial) same => n,SIPAddHeader(X-Campaign-ID: nyc-q1) same => n,Goto(from-internal,${EXTEN},1) ``

This intercepts dials to 212 area code numbers, adds a custom header (useful for analytics or carrier-side reporting), then passes back to the standard FreePBX context for normal routing.

Example: Time-of-day restriction for outbound (respecting called party time zone):

`` [from-internal-custom] exten => _1NXXNXXXXXX,1,NoOp(Time zone check) same => n,Set(LOCALTIME=${STRFTIME(${EPOCH},America/New_York,%H%M)}) same => n,GotoIf($[${LOCALTIME} < 0800]?blocked:${EXTEN},1) same => n,GotoIf($[${LOCALTIME} > 2100]?blocked:${EXTEN},1) same => n,Goto(from-internal,${EXTEN},1) same => n(blocked),Playback(cannot-complete-call) same => n,Hangup(21) ``

This simple dialplan gate blocks outbound calls outside 8:00 AM – 9:00 PM Eastern. For multi-timezone campaigns, extend the logic with area code to time zone mapping. This is a technical aid — not legal compliance advice.

4. The Dial Application and Timeout Handling

FreePBX's trunk dialing ultimately calls the Dial application:

`` Dial(PJSIP/unlimcall-us/${EXTEN},30,tTkKg) ``

The parameters:

  • 30 — ring timeout in seconds before Asterisk gives up and tries the next trunk
  • t — allow the called party to transfer the call (usually disabled for outbound centers)
  • T — allow the calling party (agent) to transfer
  • k/K — park feature code enable
  • g — continue dialplan execution if the called party hangs up (necessary for post-call AGI/recording triggers)

For predictive dialers, the timeout is critical: too long and your abandon rate rises as the dialer over-connects; too short and you drop calls on slow-answer lines. 25–30 seconds is the standard for US domestic. International calls often benefit from 35–40 seconds due to variable signaling delay across carrier boundaries.

5. AGI and ARI for Dialer Integration

If your outbound campaign uses a dialer that communicates with Asterisk via AGI or ARI rather than through the standard dialplan:

AGI (Asterisk Gateway Interface): a script executed mid-dialplan that reads/writes to Asterisk over stdin/stdout. Used for real-time decision logic (which number to dial next, which caller ID to present).

ARI (Asterisk REST Interface): a REST + WebSocket API that gives your dialer full control over channel origination, bridge creation, and media. VICIdial, GoAutoDial, and custom dialers built on ARI can originate calls directly: POST /ari/channels with the trunk endpoint and destination number.

For ARI, ensure your /etc/asterisk/ari.conf allows connections from your dialer's IP and that your Stasis application is registered before calls are originated.

6. Logging and Debugging Outbound Calls

For active debugging of outbound dial failures:

`` asterisk -rx "core set verbose 5" asterisk -rx "pjsip set logger on" ``

Then attempt the outbound call. The verbose log shows each dialplan step; the PJSIP logger shows the full SIP message exchange including SDP offers, 183 Session Progress, and final response codes.

Common outbound failure codes: 403 (IP not allowlisted on the carrier side), 404 (number not routable), 480 (destination unavailable), 503 (trunk overloaded or unreachable). Each has a distinct resolution path.

Takeaways

The Asterisk dialplan is not a black box — it is a readable, extensible configuration file that FreePBX writes on your behalf. Understanding its structure lets you add campaign logic, time restrictions, and carrier-side headers without fighting the GUI. For outbound call centers on a flat-rate network, the dialplan is where operational sophistication lives.

Flat-Rate Outbound Means Test More, Optimize Faster

When there is no per-minute cost, you can dial freely during dialplan debugging and campaign setup. UnlimCall seats at $99/month in US/CA. Activate at /pricing/.