Skip to content

Commit ef63cb2

Browse files
Vapi Taskerclaude
andcommitted
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 <noreply@anthropic.com>
1 parent 00966bc commit ef63cb2

2 files changed

Lines changed: 142 additions & 11 deletions

File tree

fern/calls/call-dynamic-transfers.mdx

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,18 +339,29 @@ sequenceDiagram
339339
console.log(`Transfer request: ${department} - ${reason} (${urgency})`);
340340

341341
// Determine destination based on department
342+
// Include transferPlan for warm transfers with context
342343
let destination;
343344
if (department === 'support') {
344345
destination = {
345346
type: "number",
346-
number: "+1234567890"
347+
number: "+1234567890",
348+
transferPlan: {
349+
mode: "warm-transfer-say-message",
350+
message: `Incoming call about: ${reason}. Priority: ${urgency}.`
351+
}
347352
};
348353
} else if (department === 'sales') {
349354
destination = {
350355
type: "number",
351-
number: "+1987654321"
356+
number: "+1987654321",
357+
transferPlan: {
358+
mode: "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message",
359+
message: `Hi, I have a customer interested in our products. Reason: ${reason}.`,
360+
timeout: 30
361+
}
352362
};
353363
} else {
364+
// Default to blind transfer for general inquiries
354365
destination = {
355366
type: "number",
356367
number: "+1555555555"
@@ -413,22 +424,33 @@ sequenceDiagram
413424
print(f"Transfer request: {department} - {reason} ({urgency})")
414425

415426
# Determine destination based on department
427+
# Include transferPlan for warm transfers with context
416428
if department == 'support':
417429
destination = {
418430
"type": "number",
419-
"number": "+1234567890"
431+
"number": "+1234567890",
432+
"transferPlan": {
433+
"mode": "warm-transfer-say-message",
434+
"message": f"Incoming call about: {reason}. Priority: {urgency}."
435+
}
420436
}
421437
elif department == 'sales':
422438
destination = {
423439
"type": "number",
424-
"number": "+1987654321"
440+
"number": "+1987654321",
441+
"transferPlan": {
442+
"mode": "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message",
443+
"message": f"Hi, I have a customer interested in our products. Reason: {reason}.",
444+
"timeout": 30
445+
}
425446
}
426447
else:
448+
# Default to blind transfer for general inquiries
427449
destination = {
428450
"type": "number",
429451
"number": "+1555555555"
430452
}
431-
453+
432454
# Execute transfer via Live Call Control
433455
async with httpx.AsyncClient() as client:
434456
await client.post(
@@ -452,7 +474,7 @@ sequenceDiagram
452474

453475
<Note>
454476
**SIP transfers:** To transfer to a SIP endpoint, use `"type": "sip"` with `"sipUri"` instead:
455-
477+
456478
```json
457479
{
458480
"type": "transfer",
@@ -464,6 +486,19 @@ sequenceDiagram
464486
}
465487
```
466488
</Note>
489+
490+
<Tip>
491+
**Warm transfer modes:** The examples above show warm transfers using `transferPlan`. Available modes include:
492+
- `blind-transfer` - Immediate transfer (default when no `transferPlan` is specified)
493+
- `warm-transfer-say-message` - Say a custom message to the operator
494+
- `warm-transfer-say-summary` - Say an AI-generated conversation summary
495+
- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message` - Wait for operator response before delivering message
496+
- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary` - Wait for operator response before delivering summary
497+
- `warm-transfer-twiml` - Execute custom TwiML instructions
498+
- `warm-transfer-experimental` - Use a transfer assistant for intelligent handoffs
499+
500+
See [Live Call Control](/calls/call-features#5-transfer-call) and [Assistant-based warm transfer](/calls/assistant-based-warm-transfer) for more details.
501+
</Tip>
467502
</Step>
468503

469504
<Step title="Test your dynamic transfer system">

fern/calls/call-features.mdx

Lines changed: 101 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,14 @@ curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/742
114114
```
115115

116116
### 5. Transfer Call
117-
Transfer the call to a different destination.
117+
Transfer the call to a different destination. Transfers support both blind (immediate) and warm (with context) modes.
118+
119+
#### Blind Transfer (Default)
120+
Immediately transfer the call without any context to the receiving party.
118121

119122
```bash
120-
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
121-
-H 'content-type: application/json'
123+
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
124+
-H 'content-type: application/json'
122125
--data-raw '{
123126
"type": "transfer",
124127
"destination": {
@@ -132,8 +135,8 @@ curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/742
132135
You can also transfer to a SIP URI:
133136

134137
```bash
135-
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
136-
-H 'content-type: application/json'
138+
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
139+
-H 'content-type: application/json'
137140
--data-raw '{
138141
"type": "transfer",
139142
"destination": {
@@ -144,6 +147,99 @@ curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/742
144147
}'
145148
```
146149

150+
#### Warm Transfer
151+
Provide context to the receiving party before connecting the customer. Use the `transferPlan` property to configure warm transfer behavior.
152+
153+
**Say a message before connecting:**
154+
155+
```bash
156+
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
157+
-H 'content-type: application/json'
158+
--data-raw '{
159+
"type": "transfer",
160+
"destination": {
161+
"type": "number",
162+
"number": "+1234567890",
163+
"transferPlan": {
164+
"mode": "warm-transfer-say-message",
165+
"message": "Incoming call from a customer asking about billing issues."
166+
}
167+
},
168+
"content": "Please hold while I transfer you."
169+
}'
170+
```
171+
172+
**Provide an AI-generated summary:**
173+
174+
```bash
175+
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
176+
-H 'content-type: application/json'
177+
--data-raw '{
178+
"type": "transfer",
179+
"destination": {
180+
"type": "number",
181+
"number": "+1234567890",
182+
"transferPlan": {
183+
"mode": "warm-transfer-say-summary"
184+
}
185+
},
186+
"content": "Transferring you now."
187+
}'
188+
```
189+
190+
**Wait for operator to speak first:**
191+
192+
```bash
193+
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
194+
-H 'content-type: application/json'
195+
--data-raw '{
196+
"type": "transfer",
197+
"destination": {
198+
"type": "number",
199+
"number": "+1234567890",
200+
"transferPlan": {
201+
"mode": "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message",
202+
"message": "Hi, I have a customer on the line who needs help with their order.",
203+
"timeout": 30
204+
}
205+
},
206+
"content": "Connecting you to our support team."
207+
}'
208+
```
209+
210+
**Use TwiML for custom announcements:**
211+
212+
```bash
213+
curl -X POST 'https://aws-us-west-2-production1-phone-call-websocket.vapi.ai/7420f27a-30fd-4f49-a995-5549ae7cc00d/control'
214+
-H 'content-type: application/json'
215+
--data-raw '{
216+
"type": "transfer",
217+
"destination": {
218+
"type": "number",
219+
"number": "+1234567890",
220+
"transferPlan": {
221+
"mode": "warm-transfer-twiml",
222+
"twiml": "<Say voice=\"alice\" language=\"en-US\">Incoming transfer from support AI.</Say><Pause length=\"1\"/><Say>Customer issue: billing question.</Say>"
223+
}
224+
},
225+
"content": "Please hold for transfer."
226+
}'
227+
```
228+
229+
<Note>
230+
Warm transfer modes require Twilio, Vapi phone numbers, or SIP trunks. They do not support Telnyx or Vonage.
231+
</Note>
232+
233+
**Available transfer plan modes:**
234+
- `blind-transfer` - Immediate transfer (default)
235+
- `blind-transfer-add-summary-to-sip-header` - Add summary to SIP headers
236+
- `warm-transfer-say-message` - Say a custom message to the operator
237+
- `warm-transfer-say-summary` - Say an AI-generated summary
238+
- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message` - Wait for operator, then say message
239+
- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary` - Wait for operator, then say summary
240+
- `warm-transfer-twiml` - Execute TwiML instructions
241+
- `warm-transfer-experimental` - Use a transfer assistant for intelligent handoffs (see [Assistant-based warm transfer](/calls/assistant-based-warm-transfer))
242+
147243
### 6. Handoff Call
148244
Handoff the call to a different assistant.
149245

0 commit comments

Comments
 (0)