Skip to main content

Dial Plans

Build visual call routing flows with dial plans.

Overview​

A dial plan defines how incoming calls are routed through a series of steps, represented as a flowchart. Each step in the flowchart is called a node. Nodes check conditions (like business hours) or ring extensions, then route to the next step based on the outcome.

Think of it like a flowchart you'd draw on a whiteboard:

Text
┌───────────┐
│ Start │
└─────┬─────┘
│
▼
┌─────────────┐ open ┌───────────────┐
│ Check Hours │────────────▶│ Reception │
│ [Schedule] │ │ [InternalDial]│
└──────┬──────┘ └───────┬───────┘
│ │
│ closed timeout
│ │
└───────────┬────────────────┘
│
▼
┌───────────┐
│ Voicemail │
└───────────┘

In this example:

  1. Every call starts at the "Check Hours" schedule node
  2. If the schedule is open, the call rings the reception extension
  3. If reception doesn't answer (timeout), or if the schedule is closed, the call routes to voicemail

Node Types​

Schedule Node​

Routes calls based on whether a schedule is currently open, closed, or on holiday.

Exits:

  • open — Schedule is currently within business hours
  • closed — Schedule is outside business hours
  • holiday — Current date falls within a holiday range

Internal Dial Node​

Dials a user or nested dial plan and routes based on the outcome.

Configuration:

  • target_id — ID of the user, ring group, or dial plan to dial
  • timeout — How long to ring before giving up (0-300 seconds, default 30)

Exits:

  • next — Ring timed out or user was busy (call continues to next node)
  • (answered) — If answered, the dial plan ends and the call is connected

Creating a Dial Plan​

JavaScript
const dialPlan = await dialstack.dialPlans.create(
{
name: 'Main Line Routing',
entry_node: 'check_hours',
nodes: [
{
id: 'check_hours',
type: 'schedule',
config: {
schedule_id: 'sched_01h2xcejqtf2nbrexx3vqjhp50',
open: 'reception',
closed: 'voicemail',
holiday: 'voicemail',
},
},
{
id: 'reception',
type: 'internal_dial',
config: {
target_id: 'user_01h2xcejqtf2nbrexx3vqjhp45',
timeout: 30,
next: 'voicemail',
},
},
{
id: 'voicemail',
type: 'internal_dial',
config: {
target_id: 'user_01h2xcejqtf2nbrexx3vqjhp99',
},
},
],
},
{ dialstackAccount: 'acct_01h2xcejqtf2nbrexx3vqjhp41' }
);

Key Concepts​

Entry Node​

The entry_node specifies which node executes first. Think of it as where the "Start" arrow points in your flowchart.

Exit Targets​

Each node type has specific exits that route to other nodes. Set an exit to null (or omit it) to terminate the call at that point.

Node IDs​

Node IDs are strings you define (like "check_hours" or "reception"). They must be unique within a dial plan and are used to wire nodes together.

Visual Position​

Nodes can include optional position coordinates (x, y) for rendering in a visual editor. If omitted, nodes are auto-positioned.

Examples​

After-Hours Voicemail​

Route calls to voicemail when closed:

Text
Start → Check Hours [Schedule] → (open) → Ring Group [Internal Dial]
→ (closed/holiday) → Voicemail
JSON
{
"name": "After-Hours Voicemail",
"entry_node": "check_hours",
"nodes": [
{
"id": "check_hours",
"type": "schedule",
"config": {
"schedule_id": "sched_...",
"open": "ring_group",
"closed": "voicemail",
"holiday": "voicemail"
}
},
{
"id": "ring_group",
"type": "internal_dial",
"config": {
"target_id": "user_...",
"next": "voicemail"
}
},
{
"id": "voicemail",
"type": "internal_dial",
"config": {
"target_id": "user_..."
}
}
]
}

Multi-Level Routing​

Chain multiple schedule checks:

Text
Start → Check Emergency [Schedule] → (open) → Emergency Line [Internal Dial]
→ (closed/holiday) → Check Hours [Schedule] → (open) → Reception [Internal Dial]
→ (closed/holiday) → Voicemail
JSON
{
"name": "Multi-Level Routing",
"entry_node": "check_emergency",
"nodes": [
{
"id": "check_emergency",
"type": "schedule",
"config": {
"schedule_id": "sched_emergency_...",
"open": "emergency_line",
"closed": "check_hours",
"holiday": "check_hours"
}
},
{
"id": "emergency_line",
"type": "internal_dial",
"config": {
"target_id": "user_emergency_..."
}
},
{
"id": "check_hours",
"type": "schedule",
"config": {
"schedule_id": "sched_business_...",
"open": "reception",
"closed": "voicemail",
"holiday": "voicemail"
}
},
{
"id": "reception",
"type": "internal_dial",
"config": {
"target_id": "user_reception_...",
"next": "voicemail"
}
},
{
"id": "voicemail",
"type": "internal_dial",
"config": {
"target_id": "user_voicemail_..."
}
}
]
}

Fallback Chain​

Try multiple users before voicemail:

Text
Start → Reception [Internal Dial] → (timeout 30s) → Manager [Internal Dial] → (timeout 20s) → Voicemail
JSON
{
"name": "Fallback Chain",
"entry_node": "reception",
"nodes": [
{
"id": "reception",
"type": "internal_dial",
"config": {
"target_id": "user_reception_...",
"timeout": 30,
"next": "manager"
}
},
{
"id": "manager",
"type": "internal_dial",
"config": {
"target_id": "user_manager_...",
"timeout": 20,
"next": "voicemail"
}
},
{
"id": "voicemail",
"type": "internal_dial",
"config": {
"target_id": "user_voicemail_..."
}
}
]
}

API Reference​

  • Dial Plans — Create, update, and delete dial plans
  • Schedules — Define business hours for schedule nodes