Skip to main content

Step types

There are twelve step types. Every step shares three keys:

KeyMeaning
idA label used in logs and in the editor. Defaults to the step type.
typeRequired. One of the twelve below.
whenA time condition gating the step.
TypeCovered hereAlso see
play dial moh hangup gotoin full
ivrthe stepIVR menus
queuethe stepCall queues
voicemail voicemail_checkthe stepVoicemail
dnd forward recordthe stepFeature codes

play

Answers the call if it is not answered yet, then plays a WAV file to completion.

- id: greeting
type: play
file: ../sounds/welcome.wav
FieldRequiredNotes
fileyesPath to an 8 kHz mono 16-bit PCM WAV, relative to the tenant directory.

Files are validated and cached in memory at startup, so a bad file fails fast instead of mid-call. See Audio files.

Playback always continues to the next step.

dial

Rings a destination and bridges the first leg that answers.

- id: follow-me
type: dial
timeout: 30s
moh: default
target:
kind: followme
stages:
- targets: ["101"]
timeout: 15s
- targets: ["100", "external:0612345678"]
timeout: 25s
FieldRequiredDefaultNotes
targetyesWhat to ring. See the kinds below.
timeoutno30sHow long to ring. For followme, the fallback for stages without their own.
mohnoringbackMusic-on-hold class the caller hears instead of ringback.

If nobody answers, execution continues with the next step. If somebody answers, the legs are bridged and the plan ends there.

target.kind: endpoint

One extension of this tenant, or a tenant: reference.

target:
kind: endpoint
endpoint: "101"

Every device registered to that extension rings in parallel; first answer wins. The value must be an account extension of the tenant, external:<number>, or tenant:<name>/<extension> when inter-tenant calling is enabled.

target.kind: ring_group

A named group, defined by a RingGroup document of the same tenant.

target:
kind: ring_group
group: support

See Ring groups and follow-me.

target.kind: followme

Sequential stages; each stage rings all of its targets in parallel.

target:
kind: followme
stages:
- targets: ["101"]
timeout: 15s
- targets: ["100", "external:0612345678"]
timeout: 25s

At least one stage is required, and each stage needs at least one target. A stage without a timeout falls back to the step's timeout, then to 30s.

target.kind: external

A number placed through the outbound routes.

target:
kind: external
number: "+31612345678"

Target references

Anywhere a list of targets is accepted — endpoint, ring group targets, follow-me stage targets — these three forms are valid:

FormMeaning
"101"An account extension of this tenant.
external:0612345678A number routed through the outbound routes.
tenant:globex/900An extension of another tenant, if allowed.

A reference that resolves to nothing at call time — an extension with no registered device, for instance — is skipped rather than failing the step. If every target in a stage resolves to nothing, that stage rings nobody and the next one starts.

moh

Plays a music-on-hold class in a loop until the caller hangs up.

- id: hold
type: moh
moh: jazz
FieldRequiredDefaultNotes
mohnodefaultClass name, resolved in the tenant then globally.

Because it only returns when the call ends, moh is effectively a terminal step; anything after it is unreachable.

hangup

Ends the call.

- id: done
type: hangup

No fields. A plan that runs off its last step hangs the caller up anyway, so hangup is for ending a plan early — and for making the intent obvious at the bottom of a file.

- id: block-weekends
type: hangup
when:
days: [sat, sun]

goto

Hands the call to another dialplan of the same tenant. It does not come back.

- id: to-main
type: goto
extension: "700"
FieldRequiredNotes
extensionyesA dialplan extension of this tenant. Checked at startup.

Jumps are checked when the PBX starts: a plan that points at itself, or a ring of plans pointing at each other, refuses to load rather than spinning on the first call that reaches it.

tenant acme: dialplan loop 700 → 800 → 700

A call may enter at most 20 plans in total, which bounds what a caller can reach through menu choices.

ivr

Plays one of the tenant's menus and follows the key the caller pressed.

- id: menu
type: ivr
menu: main
FieldRequiredNotes
menuyesThe metadata.name of an IVRMenu of this tenant. Checked at startup.

A caller who makes no valid choice falls through to the next step. Full behaviour, and the three destination types that do not work, are on IVR menus.

queue

Parks the caller in one of the tenant's queues.

- id: wait
type: queue
queue: support
timeout: 3m
moh: jazz
FieldRequiredDefaultNotes
queueyesA key of the tenant's queues. Checked at startup.
timeoutnothe queue's maxWaitBounds this plan's wait. Can only shorten the queue's own limit.
mohnothe queue's mohMusic class for this plan.

Nobody answering before the wait runs out continues to the next step. See Call queues.

voicemail

Plays a greeting, plays a beep, and records a message. Then hangs up.

- id: box
type: voicemail
FieldRequiredDefaultNotes
mailboxnothis plan's own extensionA key of the tenant's mailboxes. Checked at startup.
greetingnothe mailbox's greeting, then the shipped promptsA WAV to play instead.

voicemail_check

Asks for a PIN and plays a mailbox back.

- id: check
type: voicemail_check
FieldRequiredDefaultNotes
mailboxnothe authenticated caller's own boxNaming one lets a trunk call reach it.

With no mailbox the step refuses a call that did not authenticate — a call from a trunk proved nothing about who placed it. See Voicemail.

record

Arms or disarms recording for this call.

- id: rec
type: record
action: start
confirm: ../sounds/recording-on.wav
FieldRequiredValues
actionyesstart, stop, toggle
confirmnoA WAV played after the change.

It arms rather than opens: the file is created when the call is bridged, so put the step in front of the dial it applies to.

dnd

Sets do-not-disturb for the endpoint that placed the call.

- id: dnd
type: dnd
action: on
confirm: ../sounds/dnd-on.wav
FieldRequiredValues
actionyeson, off, toggle
confirmnoA WAV played once the change has been made.

forward

Sets or clears call forwarding for the endpoint that placed the call.

- id: set
type: forward
action: set
mode: always
collect: true
prompt: ../sounds/enter-number.wav
confirm: ../sounds/forward-set.wav
FieldRequiredValues
actionyesset, clear
modeyesalways, noanswerbusy is refused at startup
collectfor settrue. There is nowhere else the destination could come from.
promptnoAsks for the destination.
confirmnoPlayed once the change has been made.

Both dnd and forward refuse a call that is not from an authenticated endpoint, and only ever change the state of the caller, never of the number that was dialled. See Feature codes.

Music on hold classes

moh on a dial step and the moh step both take a class name:

kind: System
spec:
moh:
default: ../sounds/moh/default.wav
classes:
jazz: ../sounds/moh/jazz.wav
---
kind: Tenant
metadata: { name: acme }
spec:
domains: [acme.pbx.example.com]
moh:
classes:
jazz: ../sounds/moh/acme-jazz.wav # overrides the global jazz

The class default resolves to the tenant's moh.default, then the global one. Validation refuses a class no tenant and no global definition provides — and refuses default when neither level defines it.