Skip to content

docs: clarify transfer event coverage and initiation semantics - #1335

Open
dhruva-vapi wants to merge 2 commits into
mainfrom
dr/clarify-transfer-update-events
Open

dhruva-vapi wants to merge 2 commits into
mainfrom
dr/clarify-transfer-update-events

Conversation

@dhruva-vapi

@dhruva-vapi dhruva-vapi commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Description

Problem: The server-events guide says transfer-update fires for every transfer, so customers can wait for a webhook that phone and SIP warm transfers never emit.

This corrects the documented event coverage and explains which signal customers can use today.

  • Update fern/server-url/events.mdx with the legacy assistant-destination behavior, valid nested payload excerpts, and the status-update / forwarding signal for Vapi-managed phone and SIP transfers. Forwarding means initiation; it does not confirm an answer or successful handoff. Explain the Server URL and subscription requirements.
  • Add a concise clarification and cross-reference in fern/calls/assistant-based-warm-transfer.mdx, including that temporary transfer-assistant activation/restoration does not emit transfer-update.
  • No navigation or runtime changes.

Verified against Vapi main b84bc498e8525679cefab8b9552e891d32b1909e: voice-call emitter, phone/SIP forwarding and transport, transfer-assistant activation, and restoration. The broader message schema does not establish ringing/success/failure lifecycle events.

Open question for Steve: Should a future runtime change extend transfer-update, or use a separate event for actual started/connected/failed/canceled outcomes? Those are proposed semantics, not an existing contract, and are outside this docs-only PR.

Testing Steps

  • Pinned Fern validation: zero errors, 14 existing warnings (11 API path conflicts, 2 theme contrast warnings, 1 unauthenticated redirect check skipped).
  • Both added/changed JSON examples parse strictly and retain the HTTP message envelope. Fourteen unrelated existing placeholder snippets on the events page remain unchanged.
  • Added internal links and the transfer-update anchor resolve to existing pages/headings.
  • git diff --check passes; source facts and customer wording reviewed. No TS/JS changes.
  • Hosted preview build and Fern CI pass. Both changed pages verified through fetched rendered HTML (scripts excluded): corrected text, links, anchor, and valid nested payload examples. Preview. The preview build reports an existing TypeScript SDK snippet upload warning for @vapi/server-sdk; the changed pages render successfully.

@lightsage-app

lightsage-app Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Lightsage docs evals

Lightsage could not queue docs evals for this PR.

Docs URL: https://vapi-preview-01a14593-be9d-70b9-91d9-e22319e57a5d.docs.buildwithfern.com
Commit: 08358b8
Reason: No custom evals are selected for GitHub PR evals. Open Lightsage > Custom Evals and enable the GitHub checkbox for at least one custom eval.

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@stephenvapiai stephenvapiai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few wording suggestions.

### Transfer Update

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses "sent" to match the rest of this page, and makes the list parallel so "every" applies to each item.

Suggested change
For voice calls, `transfer-update` is emitted by the legacy `transferCall` path when transferring to an assistant destination. It includes `destination`, `fromAssistant`, and `toAssistant`. It is not emitted for every assistant handoff or phone/SIP transfer, and it does not report ringing, connection, or transfer failure.
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.


#### Phone and SIP transfers

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeps the subject and verb together, and uses "starts" instead of "is initiated".

Suggested change
Vapi-managed phone and SIP transfers, including [assistant-based warm transfers](/calls/assistant-based-warm-transfer) (`warm-transfer-experimental`), send a `status-update` with `status: "forwarding"` when the transfer is initiated. This event is sent before the transfer is attempted; it does not confirm that the destination rang, answered, or accepted the caller.
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.


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.

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/SIP transfers emit it. Use [call logs](/observability/logs/call-logs) and your telephony provider's call records to investigate the transfer outcome.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeps the outcome guidance with the phone and SIP section, and moves the subscription rules (which cover both events) under their own heading. Also uses "send" and "phone or SIP" for consistency.

Suggested change
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/SIP transfers emit it. Use [call logs](/observability/logs/call-logs) and your telephony provider's call records to investigate the transfer outcome.
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.

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 emit `transfer-update`. The `status-update` event with `status: "forwarding"` signals transfer initiation, not a successful handoff. Switching to the transfer assistant and restoring the original assistant do not emit `transfer-update` either. See [transfer event behavior](/server-url/events#transfer-update) for payloads and subscription requirements.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shortens the callout by merging the two transfer-update sentences, and uses "send" to match the events page.

Suggested change
Assistant-based warm transfers to phone or SIP destinations do not emit `transfer-update`. The `status-update` event with `status: "forwarding"` signals transfer initiation, not a successful handoff. Switching to the transfer assistant and restoring the original assistant do not emit `transfer-update` either. See [transfer event behavior](/server-url/events#transfer-update) for payloads and subscription requirements.
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants