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 — invokes the
connect_to_live_agentfunction - Resolve transfer number — reads
transfer_numberfrom template configurations - Set Redis flag — stores a transfer flag so status callbacks can distinguish transfers from normal hangups
- Provider handoff — executes the provider-specific transfer mechanism
- AI disconnects — the AI agent exits the call
- Customer + Agent — the customer continues with the live agent
Template configuration
{
"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": {}
}
]
}| Setting | Value |
|---|---|
transfer_number | Destination phone number for the live agent (required). |
lead.outbound_number_id | The 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 name | connect_to_live_agent |
| Scope | Global built-in — available across all nodes. |
| Redis flag TTL | 300 seconds (5 minutes). |
Provider-Specific flows
Twilio — Conference API
- Customer’s active call moved into a conference room
- Transfer target dialed into the same conference
- AI agent disconnects from the conference
- Customer and agent continue in the conference room
No Audio Gap
The Conference API ensures near-zero audio interruption during handoff.
Plivo — calls.transfer()
/plivo/dial-up <Response>
<Dial callerId="{outbound_number}">
<Number>{transfer_number}</Number>
</Dial>
</Response>Exotel — Applet Bridge
/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
| Aspect | Twilio | Plivo | Exotel |
|---|---|---|---|
| Mechanism | Conference API | calls.transfer() + webhook | Applet + webhook |
| Response format | N/A (API-based) | XML (<Dial><Number>) | Plain text |
| AI disconnect timing | After agent joins | After transfer initiated | Before bridge |
| Audio gap | Minimal | Brief | Noticeable |
Redis transfer flag
transfer_key = f"transfer:{lead_id}"
await redis.set(transfer_key, transfer_number, ex=300) # 5-minute TTLSuccess & 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.