Skip to content
Call controlunholdCallstable

Resume call

Stops the hold music started by an earlier "Place caller on hold" step and clears the on-hold flag. Auto-advances to the next step.

What it does

Takes the caller off hold. The node stops whatever audio is playing on the caller leg, closes the most recent open row in call_holds (stamping its endedAt and computing durationSecs), and clears the on-hold state flag. The flow auto-advances to the next node immediately — there's no hold-specific event to wait for.

Use this any time you've called Hold call earlier in the flow and the work that prompted the hold is done. The caller hears the music stop and silence (until a subsequent say, bridge, or playback brings audio back). If no open hold row exists when this runs (the caller wasn't actually on hold), the close is a no-op and the playback-stop is harmless — so it's safe as a defensive resume.

When to use it

  • Right after a customScript lookup completes, before bridging the caller to an agent
  • After a successful transfer that's about to bridge — stop the music so the caller hears the agent's hello
  • At the top of a recovery branch when re-entering the main flow from a hold-and-resume sub-flow
  • As a defensive cleanup before terminal nodes if your flow has multiple hold paths and you want a single "definitely-not-on-hold" point

Configuration

The node has no configuration fields — it just resumes.

Stops the hold music started by an earlier "Place caller on hold" step and clears the on-hold flag. Auto-advances to the next step.

This node has no configurable fields.

Examples

Resume after a CRM lookup

Closes out an earlier holdCall once the lookup is done, then continues to a personalized greeting.

{
  "id": "resume-after-lookup",
  "type": "unholdCall",
  "config": {},
  "on": { "call.hangup": "end" }
}

The flow auto-advances after the music stops. Like holdCall, the worker takes the first transition in on for forward progress.

Gotchas

  • Auto-advance picks the first transition. The worker uses Object.values(node.on)[0] to find the next node. Keep on small — if you wire multiple edges, only the first one (in object order) is followed on entry.
  • playback_stop is unconditional. The worker stops all playback on the caller leg, not just the hold music. If you've layered a say or playAudio on top of hold music (rare, but possible), this cuts both. Sequence carefully.
  • No open hold row is fine. If unholdCall runs without a matching holdCall upstream, the close is a no-op (logged at warn level). The state flag still flips to false, which is what you want for defensive resumes.
  • Fires onCallUnhold synchronously before auto-advance. Symmetric with holdCall firing onCallHold: the worker calls runTriggerChains('onCallUnhold') after the playback stop and the call_holds close, but before picking the next node. Side-chains on that trigger see vars._onHold === false and run in an isolated state branch, so they can post webhooks or update CRMs without affecting the main flow's position.
  • Caller-initiated hangup during hold. If the caller hangs up while on hold, the worker's hangup path closes any open hold row automatically — you don't need to chase a manual unholdCall first.