Skip to main content
Warm transfer hands a live SIP call to a human agent, such as a supervisor, after briefing them on the call. Instead of connecting the caller to the human directly, a transfer agent joins the human in a separate room, summarizes the conversation, and only then connects the caller. The human picks up already knowing who is calling and why.

How Warm Transfer Works

  1. The caller asks to speak to a person, and the agent calls session.warm_transfer() from a function tool.
  2. An LLM summarizes the conversation so far.
  3. The caller is put on hold, and a separate consultation room is created.
  4. The human agent is dialed over SIP into the consultation room.
  5. A transfer agent in that room briefs the human agent on the caller.
  6. The caller is switched into the call with the human agent, and the agent leaves.
  • Recording: when recording is enabled, only the conversations with an agent are recorded: the caller with your agent, and the transfer agent briefing the human agent. The conversation between the caller and the human agent after they are connected is not recorded.
  • Sessions: the call between the caller and your agent, and the briefing between the transfer agent and the human agent, are stored as separate sessions.

Prerequisites

The human agent is dialed through a SIP routing rule. Create one on the dashboard for the transfer, and leave its Agent ID (agentId) field empty, so the call goes to the human agent rather than being dispatched to an AI agent. See Routing Rules. Warm transfer runs on a live SIP call, so start the session from an inbound or outbound phone call.

Trigger a Warm Transfer

Call session.warm_transfer() from a function tool so the agent decides when to escalate. It waits for the whole transfer, which can take minutes, so raise the agent’s tool_timeout_seconds (30 seconds by default) to cover it.
sip_call_from must be a number the routing rule is authorized to send. Otherwise the carrier may reject or drop the call, and the human agent never joins.

Listen for Phase Events

Register a handler with session.on_warm_transfer() to follow the transfer. With no phase it receives every phase; pass a phase to receive only that one. The handler gets a dict with phase, data, timestamp, and consultation_room_id.
The phases, in order:

Customize the Briefing

Only destination is required. The other WarmTransferConfig fields tune the briefing:
main.py

Result

session.warm_transfer() returns a WarmTransferResult: A transfer that fails, for example because nobody answers, returns with success set to false instead of raising. If no result arrives in time, warm_transfer() raises a timeout error. By default it waits supervisor_join_timeout + briefing_timeout plus 60 seconds; pass timeout to change that.
See Handoff vs Transfer for the difference between warm transfer, call transfer, and agent handoff.

What’s Next

Call Transfer

Forward a call to another number without a briefing.

DTMF Events

Capture caller key presses.

References