Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions fern/calls/assistant-based-warm-transfer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ Place a test call and trigger the transfer. Confirm that:

In [**Logs → Calls**](/observability/logs/call-logs), inspect the original call, destination call leg, transcript, and ended reason. To retrieve these details through the API, see the [Get Call API reference](/api-reference/calls/get). An `assistant-forwarded-call` ended reason confirms that the transfer was initiated; it does not confirm that the destination answered.

<Note>
Assistant-based warm transfers to phone or SIP destinations do not send `transfer-update`, including when the call switches to the transfer assistant and back. A `status-update` event with `status: "forwarding"` signals that the transfer started, not that it succeeded. See [transfer event behavior](/server-url/events#transfer-update) for payloads and subscription requirements.
</Note>

## Troubleshooting

| Symptom | Likely cause | Resolution |
Expand Down
38 changes: 36 additions & 2 deletions fern/server-url/events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -427,17 +427,51 @@ Respond with a destination and optionally a message:

### Transfer Update

Fires whenever a transfer occurs.
For voice calls, `transfer-update` is sent by the legacy `transferCall` path when transferring to an assistant destination. It includes `destination`, `fromAssistant`, and `toAssistant`. It is not sent for every assistant handoff, phone transfer, or SIP transfer, and it does not report ringing, connection, or transfer failure.

Example payload excerpt for an assistant destination:

```json
{
"message": {
"type": "transfer-update",
"destination": { /* assistant | number | sip */ }
"destination": {
"type": "assistant",
"assistantName": "Support"
},
"fromAssistant": { "name": "Receptionist" },
"toAssistant": { "name": "Support" }
}
}
```

#### Phone and SIP transfers

Vapi-managed phone and SIP transfers send a `status-update` with `status: "forwarding"` when the transfer starts. This includes [assistant-based warm transfers](/calls/assistant-based-warm-transfer) (`warm-transfer-experimental`). This event is sent before the transfer is attempted; it does not confirm that the destination rang, answered, or accepted the caller.

Example payload excerpt for a phone destination:

```json
{
"message": {
"type": "status-update",
"status": "forwarding",
"destination": {
"type": "number",
"number": "+14155550100"
}
}
}
```

The forwarding payload also includes `messages`, `messagesOpenAIFormatted`, `transcript`, and an optional `summary`. The deprecated `forwardingPhoneNumber` field contains the destination number or SIP URI; use `destination` instead.

Use [call logs](/observability/logs/call-logs) and your telephony provider's call records to investigate the transfer outcome.

#### Subscribe to transfer events

To receive these events, configure a [Server URL](/server-url/setting-server-urls) and include the event type in `assistant.serverMessages`. `status-update` is included by default; `transfer-update` is not. Adding `transfer-update` to the subscription does not make phone or SIP transfers send it.

### User Interrupted

Sent when the user interrupts the assistant. The optional `turnId` identifies the LLM turn that was interrupted, matching the `turnId` on `model-output` messages so you can discard that turn's tokens.
Expand Down
Loading