Skip to content
TriggersonFlowStartstable

On 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 via runFlow.
  • 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.

FieldLabelTypeRequiredDefaultNotes
_labelTrigger labeltextOptionalFriendly name shown in the canvas and run logs. Optional.
_noteInternal notetextareaOptionalNotes for your team. Never spoken to the caller.
parametersFlow parametersflowParametersOptionalInputs 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 onFlowStart placed elsewhere on the canvas is fine for analytics, but any parameters declared on it are ignored at runtime — resolveFlowParameters reads only the flow's designated start node. If your parameters aren't being applied, confirm the node is wired as the flow's start.
  • Side-chains run in isolated state branches. The worker snapshots state.currentNodeId before entering each non-start onFlowStart and restores it afterward, so the side-chain can't move the main flow. It also shares the same vars object — setVar mutations 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 to say or playAudio from inside an onFlowStart side-chain — the carrier rejects audio commands until the call is answered. Use onCallAnswered for that.
  • Required parameters that are missing only warn at top-level. When the flow is invoked from a phone binding, the worker still runs resolveFlowParameters on 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 via runFlow, missing required parameters take the parent's onError path instead.