You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -24,16 +24,23 @@ Dynamic call transfers enable intelligent routing by determining transfer destin
24
24
25
25
## How It Works
26
26
27
-
Dynamic transfers operate by leaving the destination unspecified initially, then using webhooks to determine the appropriate destination when needed.
27
+
Dynamic transfers support two patterns. Choose one per your architecture:
28
28
29
-
**Transfer flow:**
30
-
1.**Trigger** - Voice agent determines a transfer is needed based on conversation
31
-
2.**Webhook** - Vapi sends `transfer-destination-request` to your server with call context
32
-
3.**Decision** - Your server analyzes context and external data to determine routing
33
-
4.**Response** - Server returns destination details and transfer configuration
34
-
5.**Transfer** - Vapi executes the transfer to the determined destination
29
+
1)**Assistant-supplied destination (no webhook)**
30
+
- The transfer tool includes custom parameters (e.g., `phoneNumber`).
31
+
- The assistant determines the destination (via reasoning or tools) and calls the transfer tool with that parameter.
32
+
- Vapi executes the transfer directly. The `transfer-destination-request` webhook is not sent.
35
33
36
-
**Available context:** Your webhook receives conversation transcript, extracted variables, customer information, function parameters, and call metadata.
34
+
2)**Server-supplied destination (webhook)**
35
+
- The transfer tool has an empty `destinations` array and no destination parameter is provided by the assistant.
36
+
- Vapi sends a `transfer-destination-request` to your server.
37
+
- Your server decides the destination and responds with it.
38
+
39
+
**Available context to servers (webhook pattern):** Your webhook receives conversation transcript, extracted variables, function parameters (if any), and call metadata.
40
+
41
+
<Tip>
42
+
Parameters for transfer tools are fully customizable. You can name and structure them however you like to guide routing (for example `phoneNumber`, `department`, `reason`, `urgency`, etc.).
43
+
</Tip>
37
44
38
45
---
39
46
@@ -46,85 +53,142 @@ Dynamic transfers operate by leaving the destination unspecified initially, then
46
53
- Navigate to **Tools** in your dashboard
47
54
- Click **Create Tool**
48
55
- Select **Transfer Call** as the tool type
49
-
- **Important**: Leave the destinations array empty - this creates a dynamic transfer tool
56
+
- **Important**: Leave the destinations array empty — this enables dynamic routing
50
57
- Set function name: `dynamicTransfer`
51
-
- Add description explaining when this tool should be used
58
+
- Add a description describing when this tool should be used
59
+
- Decide your pattern:
60
+
- If the assistant will provide the destination: add a custom parameter like `phoneNumber`
61
+
- If your server will provide the destination: omit destination params and add any context params you want (e.g., `reason`, `urgency`)
52
62
</Tab>
53
63
<Tabtitle="TypeScript (Server SDK)">
54
64
```typescript
55
65
import {VapiClient} from "@vapi-ai/server-sdk";
56
66
57
67
const vapi = new VapiClient({token: process.env.VAPI_API_KEY});
58
68
69
+
// Variant A: Assistant-supplied destination (no webhook)
59
70
const dynamicTool = await vapi.tools.create({
60
71
type: "transferCall",
61
72
// Empty destinations array makes this dynamic
62
73
destinations: [],
63
74
function: {
64
75
name: "dynamicTransfer",
65
-
description: "Transfer call to appropriate destination based on customer needs",
76
+
description: "Transfer the call to a specific phone number (assistant provides it)",
66
77
parameters: {
67
78
type: "object",
68
79
properties: {
69
-
reason: {
70
-
type: "string",
71
-
description: "Reason for transfer"
72
-
},
73
-
urgency: {
80
+
phoneNumber: {
74
81
type: "string",
75
-
enum: ["low", "medium", "high", "critical"]
82
+
description: "Destination in E.164 format (e.g., +19087528187)"
76
83
}
77
-
}
84
+
},
85
+
required: ["phoneNumber"]
78
86
}
79
87
}
80
88
});
81
89
82
90
console.log(`Dynamic transfer tool created: ${dynamicTool.id}`);
@@ -154,8 +218,7 @@ Dynamic transfers operate by leaving the destination unspecified initially, then
154
218
- Navigate to **Assistants**
155
219
- Create a new assistant or edit an existing one
156
220
- Add your dynamic transfer tool to the assistant
157
-
- Enable the **transfer-destination-request** server event
158
-
- Set your server URL to handle the webhook
221
+
- Optional: Enable the **transfer-destination-request** server event and set your server URL if using the server-supplied pattern. This is not required when the assistant provides `phoneNumber` directly.
159
222
</Tab>
160
223
<Tabtitle="TypeScript (Server SDK)">
161
224
```typescript
@@ -237,6 +300,10 @@ Dynamic transfers operate by leaving the destination unspecified initially, then
237
300
</Step>
238
301
239
302
<Steptitle="Build your webhook server">
303
+
<Info>
304
+
This step is only required for the <strong>server-supplied destination</strong> pattern.
305
+
If your assistant provides a `phoneNumber` directly when calling the transfer tool, the `transfer-destination-request` webhook will not be sent.
306
+
</Info>
240
307
<Tabs>
241
308
<Tabtitle="Node.js (Express)">
242
309
```typescript
@@ -465,6 +532,12 @@ Dynamic transfers operate by leaving the destination unspecified initially, then
465
532
**Security considerations:** Always verify webhook signatures to ensure requests come from Vapi. Never log sensitive customer data, implement proper access controls, and follow privacy regulations like GDPR and CCPA when handling customer information in routing decisions.
466
533
</Warning>
467
534
535
+
## Troubleshooting
536
+
537
+
- If transfers work but you never see `transfer-destination-request` on your webhook, your assistant likely provided the destination (e.g., `phoneNumber`) directly in the tool call. This is expected and no webhook will be sent in that case.
538
+
- If you expect a webhook but it's not firing, ensure your transfer tool has an empty `destinations` array and the assistant is not supplying a destination parameter.
539
+
- If the assistant transfers to an unexpected number, audit your prompts, tools that return numbers, and any variables the assistant can access.
540
+
468
541
## Related Documentation
469
542
470
543
***[Call Forwarding](/call-forwarding)** - Static transfer options and transfer plans
Copy file name to clipboardExpand all lines: fern/server-url/events.mdx
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -302,7 +302,7 @@ Tokens or tool-call outputs as the model generates.
302
302
303
303
### Transfer Destination Request
304
304
305
-
Requested when the model wants to transfer but the destination is not yet known.
305
+
Requested when the model wants to transfer but the destination is not yet known and must be provided by your server.
306
306
307
307
```json
308
308
{
@@ -313,6 +313,8 @@ Requested when the model wants to transfer but the destination is not yet known.
313
313
}
314
314
```
315
315
316
+
This event is emitted only if the assistant did not supply a destination when calling a `transferCall` tool (for example, it did not include a custom parameter like `phoneNumber`). If the assistant includes the destination directly, Vapi will transfer immediately and will not send this webhook.
317
+
316
318
Respond with a destination and optionally a message:
0 commit comments