TriggersonCallHoldstable

On hold

Fires when an agent puts the caller on hold (the softphone Hold button). Its chain supplies what the held caller hears (a Play music or Say node) and can…

What it does

Fires when an agent puts the caller on hold from their softphone (the Hold button, on any host). There is no holdCall flow node anymore — hold is something an agent does mid-call, not something a flow does. The caller's leg stays parked in the call's conference room; this trigger's chain is what the held caller actually hears.

Concretely: the conference's waitHook calls back into the caller's own active flow and runs its onCallHold chain. Whatever say / playAudio / pause verbs the chain produces are what plays to the held caller, on a loop, until the hold ends; a terminal hangup at the end of the chain is stripped (it can't hang up a leg that's merely on hold). No onCallHold trigger in the flow — or a chain that produces nothing playable — falls back to silence, not an error.

Because the chain also runs any side-effects on the way (a Slack ping, a setVar, an agentNotify), it's a natural place to combine "what the caller hears" with "what happens elsewhere" in one chain.

When to use it

  • Play hold music or a "please hold" message to a caller an agent has parked — the chain's say / playAudio / pause verbs ARE the caller's audio while they're held
  • Send a Slack ping to #ops when a customer is placed on hold so the team can keep an eye on long waits
  • Stamp vars.heldAt with a timestamp, then read it after onCallUnhold to compute hold duration
  • Fire a webhook to your own dashboard so a live agent view can highlight calls currently parked

Configuration

_label and _note are author-only metadata; this trigger has no runtime configuration of its own.

Fires when an agent puts the caller on hold (the softphone Hold button). Its chain supplies what the held caller hears (a Play music or Say node) and can kick off side-tasks such as a Slack ping.

FieldLabelTypeRequiredDefaultNotes
_labelTrigger labeltextOptional—
_noteInternal notetextareaOptional—

Outgoing events: triggered

Examples

Hold music plus a Slack ping

The chain does double duty: the playAudio node's audio is what the held caller hears, and the apiCall off to the side notifies the team — the caller never hears that call.

{
  "id": "hold-trigger",
  "type": "onCallHold",
  "config": { "_label": "Hold audio + notify ops" },
  "on": { "triggered": "hold-audio" }
}
[onCallHold] ──► [playAudio sys:music/default-hold, loop=forever]
            │                                        (this IS the caller's audio)
            └──► [apiCall POST hooks.slack.com/...
                  body: { text: "Caller {{event.from}} is on hold" }] ──► [end]

Just a spoken message, no side-effects

{
  "id": "hold-trigger",
  "type": "onCallHold",
  "config": {},
  "on": { "triggered": "hold-message" }
}
{
  "id": "hold-message",
  "type": "say",
  "config": { "prompt": { "kind": "text", "text": "Please hold, we'll be right with you." } },
  "on": { "next": "end" }
}

Gotchas

  • Fires from the softphone, not from a flow node. There is no holdCall node anymore — an agent puts the caller on hold from their softphone UI, and that's what triggers this chain. A flow can't put a caller on hold itself.
  • Only say / playAudio / pause verbs reach the caller. The conference waitHook filters the chain's output to those three and drops everything else, including a terminal hangup — don't rely on the chain to end the call.
  • An empty or missing chain is silent, not broken. If the flow has no onCallHold trigger, or the chain's filtered output is empty, the held caller hears nothing (a bare pause) rather than an error tone.
  • The chain runs again for as long as the hold lasts. The media plane calls the waitHook repeatedly while the leg is held, so don't assume it runs exactly once per hold.
  • Side-chain runs in an isolated state branch. It shares the call's vars but can't move the main flow's cursor.
  • Implemented by the conference waitHook (GET|POST /hooks/conf-wait in rust/bins/heyquad-walker/src/webhooks.rs), which resolves and walks the caller's own flow's onCallHold chain.

See also