From ef63cb2b8a230965eaa99fcf7e208f05e2ee5340 Mon Sep 17 00:00:00 2001 From: Vapi Tasker Date: Mon, 26 Jan 2026 07:19:25 +0000 Subject: [PATCH] docs: add warm transfer examples for control URL The documentation previously only showed blind transfer examples for dynamic transferring via control URL. This update adds comprehensive warm transfer documentation showing how to use transferPlan with various modes when using the control URL for programmatic transfers. Updated files: - call-features.mdx: Added warm transfer section with examples for all transfer modes (say-message, say-summary, wait-for-operator, TwiML) - call-dynamic-transfers.mdx: Updated code examples to demonstrate warm transfers with transferPlan in the webhook server implementations Co-Authored-By: Claude --- fern/calls/call-dynamic-transfers.mdx | 47 ++++++++++-- fern/calls/call-features.mdx | 106 ++++++++++++++++++++++++-- 2 files changed, 142 insertions(+), 11 deletions(-) diff --git a/fern/calls/call-dynamic-transfers.mdx b/fern/calls/call-dynamic-transfers.mdx index 15e62661..15fb8abb 100644 --- a/fern/calls/call-dynamic-transfers.mdx +++ b/fern/calls/call-dynamic-transfers.mdx @@ -339,18 +339,29 @@ sequenceDiagram console.log(`Transfer request: ${department} - ${reason} (${urgency})`); // Determine destination based on department + // Include transferPlan for warm transfers with context let destination; if (department === 'support') { destination = { type: "number", - number: "+1234567890" + number: "+1234567890", + transferPlan: { + mode: "warm-transfer-say-message", + message: `Incoming call about: ${reason}. Priority: ${urgency}.` + } }; } else if (department === 'sales') { destination = { type: "number", - number: "+1987654321" + number: "+1987654321", + transferPlan: { + mode: "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message", + message: `Hi, I have a customer interested in our products. Reason: ${reason}.`, + timeout: 30 + } }; } else { + // Default to blind transfer for general inquiries destination = { type: "number", number: "+1555555555" @@ -413,22 +424,33 @@ sequenceDiagram print(f"Transfer request: {department} - {reason} ({urgency})") # Determine destination based on department + # Include transferPlan for warm transfers with context if department == 'support': destination = { "type": "number", - "number": "+1234567890" + "number": "+1234567890", + "transferPlan": { + "mode": "warm-transfer-say-message", + "message": f"Incoming call about: {reason}. Priority: {urgency}." + } } elif department == 'sales': destination = { "type": "number", - "number": "+1987654321" + "number": "+1987654321", + "transferPlan": { + "mode": "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message", + "message": f"Hi, I have a customer interested in our products. Reason: {reason}.", + "timeout": 30 + } } else: + # Default to blind transfer for general inquiries destination = { "type": "number", "number": "+1555555555" } - + # Execute transfer via Live Call Control async with httpx.AsyncClient() as client: await client.post( @@ -452,7 +474,7 @@ sequenceDiagram **SIP transfers:** To transfer to a SIP endpoint, use `"type": "sip"` with `"sipUri"` instead: - + ```json { "type": "transfer", @@ -464,6 +486,19 @@ sequenceDiagram } ``` + + + **Warm transfer modes:** The examples above show warm transfers using `transferPlan`. Available modes include: + - `blind-transfer` - Immediate transfer (default when no `transferPlan` is specified) + - `warm-transfer-say-message` - Say a custom message to the operator + - `warm-transfer-say-summary` - Say an AI-generated conversation summary + - `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message` - Wait for operator response before delivering message + - `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary` - Wait for operator response before delivering summary + - `warm-transfer-twiml` - Execute custom TwiML instructions + - `warm-transfer-experimental` - Use a transfer assistant for intelligent handoffs + + See [Live Call Control](/calls/call-features#5-transfer-call) and [Assistant-based warm transfer](/calls/assistant-based-warm-transfer) for more details. + diff --git a/fern/calls/call-features.mdx b/fern/calls/call-features.mdx index fed5b8a6..73ad1a86 100644 --- a/fern/calls/call-features.mdx +++ b/fern/calls/call-features.mdx @@ -114,11 +114,14 @@ curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/742 ``` ### 5. Transfer Call -Transfer the call to a different destination. +Transfer the call to a different destination. Transfers support both blind (immediate) and warm (with context) modes. + +#### Blind Transfer (Default) +Immediately transfer the call without any context to the receiving party. ```bash -curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' --H 'content-type: application/json' +curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' +-H 'content-type: application/json' --data-raw '{ "type": "transfer", "destination": { @@ -132,8 +135,8 @@ curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/742 You can also transfer to a SIP URI: ```bash -curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' --H 'content-type: application/json' +curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' +-H 'content-type: application/json' --data-raw '{ "type": "transfer", "destination": { @@ -144,6 +147,99 @@ curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/742 }' ``` +#### Warm Transfer +Provide context to the receiving party before connecting the customer. Use the `transferPlan` property to configure warm transfer behavior. + +**Say a message before connecting:** + +```bash +curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' +-H 'content-type: application/json' +--data-raw '{ + "type": "transfer", + "destination": { + "type": "number", + "number": "+1234567890", + "transferPlan": { + "mode": "warm-transfer-say-message", + "message": "Incoming call from a customer asking about billing issues." + } + }, + "content": "Please hold while I transfer you." +}' +``` + +**Provide an AI-generated summary:** + +```bash +curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' +-H 'content-type: application/json' +--data-raw '{ + "type": "transfer", + "destination": { + "type": "number", + "number": "+1234567890", + "transferPlan": { + "mode": "warm-transfer-say-summary" + } + }, + "content": "Transferring you now." +}' +``` + +**Wait for operator to speak first:** + +```bash +curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' +-H 'content-type: application/json' +--data-raw '{ + "type": "transfer", + "destination": { + "type": "number", + "number": "+1234567890", + "transferPlan": { + "mode": "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message", + "message": "Hi, I have a customer on the line who needs help with their order.", + "timeout": 30 + } + }, + "content": "Connecting you to our support team." +}' +``` + +**Use TwiML for custom announcements:** + +```bash +curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control' +-H 'content-type: application/json' +--data-raw '{ + "type": "transfer", + "destination": { + "type": "number", + "number": "+1234567890", + "transferPlan": { + "mode": "warm-transfer-twiml", + "twiml": "Incoming transfer from support AI.Customer issue: billing question." + } + }, + "content": "Please hold for transfer." +}' +``` + + +Warm transfer modes require Twilio, Vapi phone numbers, or SIP trunks. They do not support Telnyx or Vonage. + + +**Available transfer plan modes:** +- `blind-transfer` - Immediate transfer (default) +- `blind-transfer-add-summary-to-sip-header` - Add summary to SIP headers +- `warm-transfer-say-message` - Say a custom message to the operator +- `warm-transfer-say-summary` - Say an AI-generated summary +- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message` - Wait for operator, then say message +- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary` - Wait for operator, then say summary +- `warm-transfer-twiml` - Execute TwiML instructions +- `warm-transfer-experimental` - Use a transfer assistant for intelligent handoffs (see [Assistant-based warm transfer](/calls/assistant-based-warm-transfer)) + ### 6. Handoff Call Handoff the call to a different assistant.