diff --git a/fern/calls/call-dynamic-transfers.mdx b/fern/calls/call-dynamic-transfers.mdx
index 15e62661c..15fb8abb9 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 fed5b8a6a..73ad1a863 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.