sid keeps
addressing it before, during, and after, so every recording, transcript,
and analytics row keyed on that sid stays one continuous story.
There are three moves you’ll actually make:
| Handoff | What happens | Mechanism |
|---|---|---|
| AI → human | The bot escalates; a human takes over the live audio. | Re-attach the bridge to a human agent or queue |
| Human → AI | A human hands back to an AI agent (deflection, after-hours, ACW). | Re-attach the bridge to an AI agent |
| Transfer off-net | Forward the caller to an external number or PBX. | SIP REFER from the gateway |
Everything hangs off one sid
A call is a SIP dialog with two legs — caller and agent — held together by a B2BUA (back-to-back user agent) in the SIP gateway. Thesid names that
dialog. When you hand off, only the agent leg is re-pointed; the caller
leg never moves, so from the caller’s perspective the audio path is
uninterrupted.
sid survives, the call events pipeline emits a
TRANSFER_INITIATED (or REFER_RECEIVED) transition rather than an END,
and downstream folds the call into multiple segments under one sid —
split by whether an AI or a human handled each stretch. That’s what powers a
correct ”12s with the bot, 4m18s with a human” breakdown instead of two
unrelated calls. See
Sessions, calls, tracks & streams
for the object model and
Call traces for the segment
rows.
AI → human
The bot decides it needs a person — an intent it can’t satisfy, a compliance trigger, an explicit “let me talk to someone”. You transfer the live call to a human. Two flavors:- To a skill queue — route the caller into the ACD (skill-queue router), which rings an available human agent and bridges them in on accept. Use this when any qualified agent will do.
- To a specific human — transfer to a named agent, a browser softphone, or a phone number. Use this for warm escalations to a known owner.
- TypeScript
- Python
Warm handoff / screen-pop. The product thesis for regulated verticals is
that the AI does intent, qualification, auth, and compliance capture first,
then a context bundle screen-pops to the human before audio cuts in. The
routing and accept legs are shipped today; the rich context payload that
travels with the transfer is assembled at your application layer — you build the
context bundle, there is no turnkey field for it yet.
Human → AI
The reverse move re-attaches an AI agent to a live call — deflect a queued caller to a self-service bot, drop into an after-hours agent, or run automated wrap-up. It’s the sametransfer({ agent }) call; you just name an AI agent
instead of a human queue. The bridge re-points in place and the sid is
unchanged, so a call can bounce bot → human → bot and still be one record.
Transfer off-net via SIP REFER
When you transfer to a phone number (a PSTN destination or another PBX), the gateway performs a SIPREFER — the standard way to ask the far end to
re-target its call leg. You don’t construct the REFER yourself; passing to
is enough, and a bare string is shorthand for { to }.
- TypeScript
- Python
REFER_RECEIVED lifecycle transition
on the same sid. Rule of thumb: to → SIP REFER (off-net); agent →
in-place re-attach (on our media plane). Either way the original sid
keeps addressing the call.
Bot ⇄ human re-attach, step by step
Hold the sid
You get a
sid from calls.originate() (outbound) or the inbound call
webhook. It is the only identifier you need for every later step —
transfer, hang up, fetch recordings, read analytics.Decide the target
Human queue (
agent: "human-support"), a specific human, an AI agent, or
an off-net number (to). Exactly one of agent / to per transfer.Transfer
Call
transfer(...). The caller leg stays put; the agent leg re-points.
The caller hears continuous audio (optionally hold media while the queue
rings).Honest status
- AI → human transfer — shipped. Routing into the queue and human accept work end to end (a prior transfer-teardown crash is fixed).
- Human → AI re-attach — shipped, same
transfer({ agent })primitive. - sid preservation across handoffs — shipped; segments fold under one
sidby handler. - Human-agent two-way audio (browser softphone). The agent’s mic uplink is live; the downlink leg (the human hearing the caller over the media-over- QUIC track) is still being hardened — the caller-audio origin publish needs to be bridged into the relay fan-out. If you’re standing up browser softphone agents right now, validate the return audio path in staging. Real SIP deskphone agents are not affected.
- Warm screen-pop context payload — application-level today (see the Note above), not a turnkey feature.
Related
AI-to-Human Handoff
The telephony-plane view of escalation and accept.
PBX & ACD
How the skill-queue router rings and claims human agents.
Support agent with handoff
A full inbound bot that escalates to a human, end to end.
Transfer to a human
Copy-paste transfer snippet.
Call lifecycle
Every event a call emits, including transfers.
Sessions, calls, tracks & streams
Why the sid is the one identifier that matters.