onFlowStartstableOn flow start
Runs once at the very beginning of every call, before anything else. Use it as the first node so the flow has a clear starting point. Drop a second copy a…
What it does
Marks the entry point of a flow. Every call begins by entering the flow's
designated start node, and that node is almost always an On flow start —
it gives the flow a single, named place to declare its parameters and to
attach the very first downstream chain. Nothing has happened yet when this
fires: the carrier has just routed the call to your number, the caller has
not been answered, and no audio is in scope. From here you typically wire
into an answer node, then your IVR.
A second copy of On flow start can be placed anywhere on the canvas as a
side-chain — the worker fires every onFlowStart node in the flow at run
start, in isolated state branches that don't move the main flow's cursor.
That makes it the natural home for analytics pings, CRM "call started"
webhooks, or Slack notifications that should run for every inbound call
without polluting the voice path. The start-node copy also declares the
flow's parameters, which are the typed inputs other flows pass when
invoking this one via Run sub-flow. Each declared parameter becomes
{{config.<key>}} inside the flow body.
When to use it
- Anchor the start of every new flow — it's the default node in a fresh canvas.
- Fire a one-time analytics or CRM webhook the moment a call lands, in a side-chain that runs in parallel with your IVR.
- Declare reusable inputs (
queueId,language,afterHoursMessage) on a shared flow that other flows invoke viarunFlow. - Send a Slack ping for every call to a specific number while the main flow greets the caller — the side-chain runs independently and can't stall the voice path.
Configuration
The only field that affects runtime behavior is parameters on the start
node. _label and _note are author-only metadata for the canvas.
Runs once at the very beginning of every call, before anything else. Use it as the first node so the flow has a clear starting point. Drop a second copy anywhere on the canvas to fire side-tasks (analytics, CRM logging, Slack pings) the moment a call comes in — those run independently from the main flow. Declare flow parameters here to make this flow reusable from a Run sub-flow node.
| Field | Label | Type | Required | Default | Notes |
|---|---|---|---|---|---|
_label | Trigger label | text | Optional | — | Friendly name shown in the canvas and run logs. Optional. |
_note | Internal note | textarea | Optional | — | Notes for your team. Never spoken to the caller. |
parameters | Flow parameters | flowParameters | Optional | — | Inputs callers pass when they invoke this flow via Run sub-flow. Each parameter becomes {{config.<key>}} inside the flow. If a caller doesn't pass a value, the default is used. Required parameters fail the parent's runFlow node when missing. Only the parameters declared on the flow's start node are read at runtime. |
Outgoing events: triggered
Examples
Reusable greeting flow with parameters
A shared "after hours" sub-flow that the parent invokes with a custom
message. The start node declares one required string parameter, which the
downstream say node reads via {{config.message}}.
{
"id": "start",
"type": "onFlowStart",
"config": {
"_label": "After-hours greeting (sub-flow)",
"parameters": [
{
"key": "message",
"label": "Spoken message",
"type": "string",
"required": true,
"default": "We're closed. Please call back during business hours."
}
]
},
"on": { "triggered": "speak-message" }
}
Side-chain analytics ping
A second onFlowStart placed off to the side, firing an HTTP call to an
analytics endpoint while the main flow runs the IVR.
[onFlowStart "main"] ──► [answer] ──► [say greeting] ──► ...
[onFlowStart "ping"] ──► [httpCall analytics] ──► [end]
The "ping" chain runs in an isolated state branch — its currentNodeId
moves are restored after it completes, so it can't accidentally redirect
the main flow.
Gotchas
- Only the start node's parameters are read. A side-chain copy of
onFlowStartplaced elsewhere on the canvas is fine for analytics, but anyparametersdeclared on it are ignored at runtime —resolveFlowParametersreads only the flow's designated start node. If your parameters aren't being applied, confirm the node is wired as the flow'sstart. - Side-chains run in isolated state branches. The worker snapshots
state.currentNodeIdbefore entering each non-startonFlowStartand restores it afterward, so the side-chain can't move the main flow. It also shares the samevarsobject —setVarmutations from a side-chain will be visible to the main flow, which is occasionally useful and occasionally a footgun. - Fires before
answer. The trigger runs before the start node is entered, so the call is still in the pre-answer state. Don't try tosayorplayAudiofrom inside anonFlowStartside-chain — the carrier rejects audio commands until the call is answered. UseonCallAnsweredfor that. - Required parameters that are missing only warn at top-level. When the
flow is invoked from a phone binding, the worker still runs
resolveFlowParameterson entry (so declared defaults + type coercion apply identically to the runFlow path), but missing required parameters log a warning and let the call proceed — the operator can't recover by hanging up at the binding layer once the carrier has already routed the call. When invoked viarunFlow, missing required parameters take the parent'sonErrorpath instead.
