The FreeSWITCH XML dialplan is the primary mechanism for deciding what happens to a call after it arrives. It evaluates an ordered list of extensions in the active context, tests each extension’s conditions against the channel’s current state (caller ID, destination number, time of day, channel variables, and more), and then executes a list of applications when a match is found. The dialplan is deliberately simple — a pure data-driven ruleset expressed in XML — which makes it both easy to audit and straightforward to generate programmatically.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/signalwire/freeswitch/llms.txt
Use this file to discover all available pages before exploring further.
Dialplan Structure
The XML dialplan follows a strict four-level hierarchy: contexts contain extensions, extensions contain conditions, and conditions contain actions (and optionally anti-actions).- A context is an isolated routing table. Only callers placed into that context will evaluate its extensions.
- An extension is a named rule block. Extensions are evaluated top-to-bottom within the context.
- A condition tests a channel field against a regular expression. An extension can have multiple conditions; by default all must match before actions execute.
- Actions are dialplan application calls executed in order when all conditions are satisfied.
Contexts
FreeSWITCH ships with two default contexts, both defined inconf/vanilla/dialplan/:
- default
- public
The
default context handles calls from authenticated users — SIP phones that have registered with valid credentials, or calls transferred here from the public context. It is the context most extensions and features are placed in.default cannot be matched by a caller in public unless the caller is explicitly transferred across contexts using the transfer application.
Conditions
A condition tests the value of a field — a channel variable or caller-profile attribute — against a regular expression using PCRE. Named capture groups ($1, $2, …) populated by the regex are available to actions within the same condition.
Common field values:
| Field | Description |
|---|---|
destination_number | The dialed number (after normalization) |
caller_id_number | The calling party’s number |
caller_id_name | The calling party’s name |
network_addr | Source IP address of the call |
${variable_name} | Any channel variable (wrapped in ${}) |
wday | Day of the week (1=Sunday … 7=Saturday) |
hour | Hour of the day (0–23) |
mday | Day of the month (1–31) |
mon | Month (1–12) |
break attribute on a <condition> controls evaluation flow when the condition fails:
break value | Meaning |
|---|---|
on-false (default) | Stop evaluating this extension if the condition fails |
on-true | Stop evaluating this extension if the condition succeeds |
always | Stop evaluating this extension regardless of outcome |
never | Always continue evaluating subsequent conditions |
Actions and Anti-Actions
When all conditions in an extension match, each<action> tag is executed in document order. Each action specifies an application (a loaded function from a module like mod_dptools) and optional data passed to it.
false. They are declared with the <anti-action> tag and placed inside the same <condition> block as actions. A common use is to set a default value when a time-of-day condition does not match:
Channel Variables
Channel variables are key-value pairs stored on each call leg. They communicate state between dialplan steps and between modules. Theset application writes a variable; the ${variable} syntax reads it back anywhere in the dialplan.
set survive for the duration of the call leg. The export application propagates a variable to the B-leg when a bridge is created. Use unset to remove a variable.
- set (A-leg only)
- export (A and B legs)
- unset
Redial and Hash Examples
The vanilla dialplan shows real-world usage of channel variable substitution with the built-inhash API:
Inline Dialplan
For one-shot originate commands from the API or ESL, FreeSWITCH supports an inline dialplan that lets you specify a comma-separated list ofapp:data pairs directly in the originate string — no XML required. Prefix the extension list with & or use the dp: scheme.