Skip to content
TriedDocs
Reliability and latency

Debug transfers

How cold, warm and agentic transfers work, the events and reasons they record, and how to fix transfers that fail, ring out or never bridge.

Transfers are made by the agent's transfer_call tool. When one goes wrong, the call record tells you which step failed: the transcript has a transfer item for each step, the call has a transfer_destination, and the disconnection_reason says how the call ended.

Transfer types#

Type transfer_option.type What happens
Cold, new call (default) cold_transfer, cold_transfer_mode: sip_invite The runtime dials the destination into the same room. The caller hears ringback, the legs bridge, the agent leaves
Cold, SIP REFER cold_transfer, cold_transfer_mode: sip_refer Tried asks the carrier to redirect the caller with SIP REFER
Warm warm_transfer The caller hears hold music. The runtime dials the transferee, waits for a human, whispers a private handoff to them, then bridges and plays the public handoff
Agentic warm agentic_warm_transfer A second agent (the transfer agent) talks to the transferee, then bridges or cancels
Transfer options in the transfer tool

Events#

Each transfer records items with role: "transfer" in transcript_with_tool_calls, and sends webhooks for the events listed in the agent's webhook_events:

Event Meaning
transfer_started The agent called the tool. Records the destination and type
transfer_bridged The caller and the destination are connected. The call ends with call_transfer
transfer_cancelled The transfer failed. Records a reason. The agent stays on the call
transfer_ended The bridged legs hung up

Tried does not charge for the transferred leg. It runs on your own trunk, so your carrier bills it.

Failure reasons#

When a transfer is cancelled, the agent gets Transfer failed (<reason>). as the tool result and can tell the caller. Common reasons:

Reason Meaning What to do
caller_not_sip The caller is not on a phone line (for example a web call) Transfers need a phone call. The builder's Test Audio panel notes that call transfer is not supported in web calls
busy The destination returned SIP 486 or 600 Try another destination, or tell the caller to try later
no_answer 480, 408 or 487, or the ring timed out Raise transfer_ring_duration_ms (5,000 to 300,000 ms) on the transfer option
invalid_destination 404 Check the number is E.164 with a country code, or the SIP URI
declined 603 The destination rejected the call
human_not_detected Warm transfer: no human answered within agent_detection_timeout_ms Raise the timeout for destinations with long queues, or set opt_out_human_detection
failed Any other SIP error Check the SIP trace below
error: ... An exception in the runtime, with its message Check the destination and the trunk

Transfer failed: no destination. means the destination was empty: a static number that renders to nothing because of a missing dynamic variable, or an inferred destination the model could not fill.

Checklist#

The destination#

  • Static destinations accept {{dynamic_variables}}. Check the variable is set on every call that can transfer.
  • With an inferred destination, the model chooses the number from your prompt. Give it a clear list of numbers and when to use each.
  • An extension on the destination is sent as DTMF after the destination answers.

The trunk#

  • Transfers dial out on the number's outbound trunk, like outbound calls. If outbound calls from that number fail, transfers will too. See Debug outbound calls.
  • sip_refer needs your carrier or PBX to accept REFER. If it does not, use sip_invite (the default) or warm transfer, which place a new call.
  • show_transferee_as_caller presents the caller's number to the destination. Some carriers reject calls whose caller ID is not a number you own. Turn it off if transfers fail only when it is on.

Warm transfers#

  • Destinations that answer with an IVR or a queue message can look like a machine. Use the transfer option's ivr_option to navigate, raise agent_detection_timeout_ms, or set opt_out_human_detection.
  • on_hold_music sets what the caller hears: none, relaxing, uplifting, ringtone, or a custom asset.
  • enable_bridge_audio_cue plays a cue when the legs connect.

Agentic warm transfers#

  • The transfer agent (transfer_agent.agent_id) must exist in the workspace.
  • transfer_timeout_ms (10,000 to 600,000) with action_on_timeout (bridge_transfer or cancel_transfer) decides what happens if the transfer agent does not finish.

Read the SIP trace#

For phone calls, GET /v2/get-call-sip-trace/:call_id returns the SIP log lines captured for the call when the operator has set TRIED_SIP_LOG_PATH for livekit-sip. Look for the response code on the INVITE or REFER to the destination. Per-call packet capture is a deployment step and returns 404 until capture is set up.

Test without a phone#

The runtime's simulated transport records transfers (destination and whether they are warm or cold) without dialling. Use tests and simulations to check that the agent transfers at the right moment before you try it on a real line.