How-to

Warm transfer

Seamlessly hand off active conversations from AI to live human agents across Twilio, Plivo, and Exotel.

How warm transfer works

Warm transfer allows the AI agent to connect the customer to a live human agent mid-conversation. The built-in connect_to_live_agent handler orchestrates the entire flow.

LLM Triggers Transfer
Resolve Transfer Number
Set Redis Flag
Provider Handoff
AI Disconnects
Customer + Agent
  1. LLM triggers transfer — invokes the connect_to_live_agent function
  2. Resolve transfer number — reads transfer_number from template configurations
  3. Set Redis flag — stores a transfer flag so status callbacks can distinguish transfers from normal hangups
  4. Provider handoff — executes the provider-specific transfer mechanism
  5. AI disconnects — the AI agent exits the call
  6. Customer + Agent — the customer continues with the live agent

Template configuration

template-transfer-config.json
json
{
  "configurations": {
    "transfer_number": "+1234567890"
  },
  "global_builtin_functions": [
    {
      "name": "connect_to_live_agent",
      "description": "Transfer the customer to a live human agent when they request to speak with a person.",
      "parameters": {}
    }
  ]
}
SettingValue
transfer_numberDestination phone number for the live agent (required).
lead.outbound_number_idThe caller number the AI is calling from (required on the lead). Missing this causes the transfer function to return missing_outbound_number_id and the AI keeps talking.
Function nameconnect_to_live_agent
ScopeGlobal built-in — available across all nodes.
Redis flag TTL300 seconds (5 minutes).

Provider-Specific flows

Twilio — Conference API

Customer Placed in Conference
Live Agent Dialed In
AI Disconnects
Customer + Agent Continue
  1. Customer’s active call moved into a conference room
  2. Transfer target dialed into the same conference
  3. AI agent disconnects from the conference
  4. Customer and agent continue in the conference room

No Audio Gap

The Conference API ensures near-zero audio interruption during handoff.

Plivo — calls.transfer()

calls.transfer() → /dial-up
Webhook Returns Dial XML
Customer Bridged to Agent
AI Disconnects
POST /plivo/dial-up
plivo-dial-response.xml
xml
<Response>
  <Dial callerId="{outbound_number}">
    <Number>{transfer_number}</Number>
  </Dial>
</Response>

Exotel — Applet Bridge

AI Disconnects
Applet Calls /dial-up
Returns Plain-Text Number
Exotel Native Bridge
POST /exotel/dial-up

Exotel: AI Disconnects First

In the Exotel flow, the AI disconnects before the customer is bridged. There is a brief hold period while the applet completes the bridge.

Provider comparison

AspectTwilioPlivoExotel
MechanismConference APIcalls.transfer() + webhookApplet + webhook
Response formatN/A (API-based)XML (<Dial><Number>)Plain text
AI disconnect timingAfter agent joinsAfter transfer initiatedBefore bridge
Audio gapMinimalBriefNoticeable

Redis transfer flag

transfer_flag.py
python
transfer_key = f"transfer:{lead_id}"
await redis.set(transfer_key, transfer_number, ex=300)  # 5-minute TTL

Success & failure handling

On Success

  • end_conversation() is called to cleanly terminate the AI session
  • Lead status is updated with the transfer outcome
  • Redis transfer flag is cleared

On Failure

  • An error message is returned to the AI agent
  • The conversation continues — the AI resumes talking to the customer
  • The AI can inform the customer and offer alternatives

Resilient Conversations

Failed transfers never end the call. The AI agent resumes automatically and can retry the transfer, offer a callback, or continue normally.

Missing Transfer Number

If transfer_number is not set in the template’s configurations, the connect_to_live_agent function will return an error and the transfer will not be attempted.

Next steps

Was this helpful?