enqueuestableAdd to call queue
Registers the caller in a queue and starts the dispatcher. The flow advances immediately — compose what the caller hears (hold music, announcements, max w…
What it does
Parks the caller in a named queue and starts the queue dispatcher. A row
is written to queue_entries, the SLA timer starts, and the configured
queue strategy (ring_all, longest_idle, round_robin, etc.) begins
offering the call to eligible queue members. Crucially, this node is
non-blocking — it stamps state.queueId and state.queueEntryId
onto the run, then auto-advances along its outgoing transition (preferring
on['enqueued'], falling back to the first wired edge) so you can compose
the on-hold experience yourself with downstream playAudio, say, and
wait nodes.
While the flow is sitting on those downstream nodes, two interrupt
events can yank it back: call.bridged fires on whichever node is
current when an agent picks up, and call.hangup fires when the caller
gives up. If every offered leg in a round hangs up without an answer,
the dispatcher automatically re-offers the entry to a fresh selection
of agents — the call stays in the queue until either someone answers,
the caller hangs up, or your downstream wait node fires its fallback
transition (typically to voicemail).
When to use it
- Park inbound support calls in a queue while skill-based routing picks the right agent — pair with hold music and periodic position announcements downstream
- Build a max-wait-then-voicemail pattern:
enqueue→playAudio(loop) →wait 600→voicemail. Thewaitis interrupted automatically when an agent bridges - Run a turnkey hold experience by calling the system queue flow via
runFlowimmediately after this node — it handles announcements, position estimates, and timeout fallback for you - Implement an overflow tier: try
requestAgentfor a named team first, thenenqueueinto a broader department queue when the named team doesn't pick up - Stage VIP callers into a high-priority queue based on a
branchorsetVardecision earlier in the flow
Configuration
Registers the caller in a queue and starts the dispatcher. The flow advances immediately — compose what the caller hears (hold music, announcements, max wait) with the next nodes. Pair with playAudio (loop) and wait nodes downstream, or call the system queue flow via runFlow for a turnkey experience. SKILL-BASED ROUTING: name a queue per skill (e.g. sales_en, support_tier2), make each agent a member of the queues for their skills, then route inbound calls to the right queue. For static routing pick the queue below; for dynamic routing leave it blank and set the "Dynamic queue" field to a template that resolves from an IVR digit or a contact attribute (e.g. {{vars.skill}} or {{vars.gatheredDigits}}_queue). Proficiency on the queue membership orders agents within a queue.
| Field | Label | Type | Required | Default | Notes |
|---|---|---|---|---|---|
queueName | Queue | queue | Optional | "" | Static routing: pick from your saved queues. Manage queues under Settings → Queues. Leave blank if you are routing dynamically with the "Dynamic queue" field below. |
queueNameTemplate | Dynamic queue (advanced) | text | Optional | {{vars.skill}} | Skill-based routing: a queue-name template that resolves at call time. Overrides the static Queue above when set. Use {{vars.X}} (from a gatherDigits/setVar node — e.g. {{vars.gatheredDigits}} or {{vars.skill}}), {{caller.X}}, or {{config.X}}. Combine literals with a variable to map a digit to a per-skill queue, e.g. {{vars.gatheredDigits}}_queue. The queue must exist and the agent must be a member of it. |
priority | Priority override | number | Optional | 0 | Higher wins when this caller competes with another for the same agent; ties break by longest wait. Leave blank to use the queue's default priority. |
Outgoing events: call.bridged, call.hangup
Examples
Enqueue, then play hold music with a max wait
Auto-advances on enqueued to the hold-music loop. The wait node
fires wait.elapsed after ten minutes if no agent has picked up by
then — at which point the flow rolls to voicemail.
{
"id": "queue-support",
"type": "enqueue",
"config": { "queueName": "support" },
"on": { "enqueued": "hold-music", "call.bridged": "end", "call.hangup": "end" }
}
{
"id": "hold-music",
"type": "playAudio",
"config": {
"audioUrl": "https://cdn.example.com/hold.mp3",
"loop": "forever"
},
"on": { "call.bridged": "end", "call.hangup": "voicemail" }
}
Use the system queue flow for the full hold experience
If you don't want to hand-build the announcements and position estimates, delegate the wait to the bundled queue flow.
{
"id": "queue-sales",
"type": "enqueue",
"config": { "queueName": "sales" },
"on": { "enqueued": "queue-experience", "call.hangup": "end" }
}
Gotchas
enqueuedoes not block. The flow advances the moment the entry is written; it does NOT wait for an agent to pick up. Wire downstream nodes (hold music, wait, announcements) explicitly. A bareenqueue → endflow will end the call immediately and cancel the queue entry on hangup.call.bridgedandcall.hangupinterrupt whatever node is current. When an agent answers while the caller is parked on a downstreamwaitorplayAudio, the bridge event re-routes from that node'son['call.bridged']— not from the enqueue node's. Make sure every downstream hold-experience node has the bridge edge wired to a sensible target (usuallyend).- Re-offering after an agent no-answer keeps the entry alive.
When all offered legs hang up without picking up, the dispatcher
automatically re-runs the queue strategy and offers to a fresh set
of agents. The caller stays in the queue — the only way out is a
successful bridge, the caller hanging up, or your own
wait/ fallback wiring. state.queueEntryIdis your bookkeeping handle. It's stamped by this node and consumed bymarkQueueEntryBridgedon bridge (which cancels the SLA timer and bumps the agent'slast_call_at). Don't rename or clear it from a customScript.- An empty
queueNameis a silent skip. The node logs a warning and falls through without registering anything. The flow keeps running with no queue context — which often looks like "the call bypassed the queue for some reason." Always validate the field.
