Build / Transfers
Handing a call to a human
A transfer is the moment your agent is judged. Done well, the human arrives already knowing what happened and the caller never repeats themselves.
Warm vs cold
Warm recommended
The human is dialled into the call. The agent waits for them to answer, briefs them while the caller listens, then leaves. Nobody is put on hold and nothing is repeated.
Cold
The caller is handed off to another number and the agent’s call ends. Faster, but the human picks up with no context — use it for pure routing, like sending someone to a department line.
What a warm transfer sounds like
The lines around your briefing are fixed on purpose — a transfer is the one moment that should never be improvised.
Write the briefing for the ear
The briefing is spoken out loud, word for word, to both the caller and the person joining. It is not a log line. Ticket ids, call ids and raw status codes get read aloud exactly as written, so keep it to what a colleague would actually say — and use variables to make it specific.
Hey {{ oncall_name }} — I've got {{ caller_name }} from {{ site }} on the line
reporting a {{ severity }} issue. {{ summary }}. The ticket is open and flagged.
They can fill you in on the details — take it from here.Read it out loud before you ship it. If you would not say it to a colleague, do not make the agent say it. “VENUE Sev-1 escalation — call vl-client-74cc…” is a log line; “Hey Marcus, I’ve got someone from Keystone Arena reporting a Sev 1” is a handoff.
Requirements
A phone destination
E.164 format — +14155550100. No spaces, dashes or brackets.
Someone who answers
A warm transfer waits for a real answer before briefing. If nobody picks up, the call falls back rather than briefing an empty line — so route to a rota or a desk line, not a single mobile.
A caller on a phone line
Web and Playground callers have no phone leg, so there is nothing to transfer. The agent explains that and closes cleanly instead of dropping into silence. Test transfers with a real call.
In a flow
Add a Transfer to human step, set Transfer to, choose Warm, and write the briefing. Put the transfer after the steps that gather context and open the record — the whole point is that the human arrives informed, and the graph is what guarantees the order.
In the SDK code
await ctx.handoff('+14155550100', {
reason: 'sev-1 escalation',
mode: 'warm',
briefing: `Hey Marcus — I have someone from ${site} on the line
reporting an outage. Ticket ${ticketId} is open.`
});Let the transfer own the talking — don’t speak your own “transferring you now” line before calling it, or the caller hears the same thing twice.
Every step is recorded. Open the call afterwards and the transcript shows the transfer inline — dialling, answered, briefed, agent left — so you can see exactly where a handoff went wrong without guessing.