Skip to navigation

Troubleshoot call transfers

Trace transfer attempts, failed connections, and caller recovery

Use this page when a call transfer fails or doesn’t behave as expected. A transfer has three separate stages: the assistant decides to transfer, Vapi starts the transfer, and the destination answers. Each stage leaves different evidence, so check both the Vapi call record and your phone provider’s call logs to find the stage where the attempt stopped.

Quick diagnosis

What you observeCheck nextLikely cause
The assistant says it will transfer, but the call continuesLook for a transferCall invocation in the call’s Messages tabAssistant prompt or model decision
The transferCall tool runs, but the transfer does not startInspect the call’s Logs tab for a Tool or Transfer errorTool configuration or Vapi transfer initiation
The call ends with assistant-forwarded-call, but the destination does not answerMatch phoneCallProviderId to the provider’s call recordProvider route, destination, or delegated call control
A warm transfer returns to the original assistant or ends after a fallback messageCheck transferPlan.mode, fallbackPlan.endCallEnabled, and the transfer attemptConfigured fallback or transfer-assistant decision

The assistant-forwarded-call ended reason means Vapi started or handed off the transfer. It does not prove that the destination rang, answered, or spoke with the caller.

Prerequisites

Before you start debugging, ensure you have:

  • The call ID of the failed transfer
  • A private Vapi API key to retrieve the call through the API
  • Access to the call’s Messages and Logs tabs, if logs were retained
  • Access to your phone provider’s call record, if the transfer reached that provider
  • A SIP trace or packet capture, if you’re debugging a SIP transfer

Troubleshooting workflow

1

Check call ended reason

First, check the call’s endedReason and the Messages tab. A spoken promise to transfer is not a transferCall invocation.

curl -X GET "https://api.vapi.ai/call/{call_id}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"
Example response (truncated)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "inboundPhoneCall",
"status": "ended",
"endedReason": "assistant-forwarded-call",
"phoneCallProvider": "twilio",
"phoneCallTransport": "pstn",
"phoneCallProviderId": "CA0123456789abcdef0123456789abcdef",
"destination": {
"type": "number",
"number": "+14155550100"
}
}

For every field in the call object, see the Get Call API reference.

Interpret the result:

  • No transferCall tool call: Check the assistant prompt and tool assignment. The model did not invoke the transfer tool.
  • A transferCall tool call followed by a Tool or Transfer error: Inspect the destination, transfer plan, and call logs.
  • assistant-forwarded-call: Vapi submitted the transfer to the phone provider or sent a phone-call-control request to your server. Check the downstream result before treating it as a connected call.
  • call.in-progress.error-transfer-failed, call.forwarding.operator-busy, or call.forwarding.no-answer: Inspect the transfer attempt and provider result. These reasons do not all mean the assistant failed to invoke the tool.
2

Identify who controls the transfer

When the assistant includes phone-call-control in serverMessages, Vapi sends a phone-call-control request to your server instead of transferring the call itself. Your server then decides whether and how to transfer. Check your server’s response and your phone provider’s call record before changing this setting.

{
"serverMessages": ["status-update", "end-of-call-report", "tool-calls"]
}

Remove phone-call-control unless your server handles transfers. Setting serverMessages replaces the default list, so include every message type your server needs. See server events for the full list.

Use Webhook logs to inspect a recorded server-message delivery. If your application intentionally controls the provider call, its logs and provider call record are the source of the downstream outcome.

3

Validate transfer scenario compatibility

Confirm that the call type supports the destination type:

Call typeTo a phone numberTo a SIP address
Phone call on Twilio, Telnyx, a Vapi number, or a SIP trunkYesYes
Phone call on VonageYesNo
Web callNoNo

For a SIP destination, check the inbound provider, transferPlan.sipVerb, and the receiving private branch exchange (PBX). For a phone-number destination, verify E.164 format and call the number directly to confirm it is reachable.

4

Analyze telephony provider logs

Use the call’s phoneCallProviderId and timestamp to find the matching record in your phone provider’s logs. Check whether the provider received the transfer command, dialed the destination, and recorded an answer, busy signal, no answer, rejection, or other failure.

  1. Open Twilio Console call logs.
  2. Search for the call SID from phoneCallProviderId. It starts with CA.
  3. Check the call’s status, its child calls, and any errors or warnings.

A successful API command to the provider is not proof that the downstream call connected. Compare the provider record with the Vapi call’s endedReason, Messages, and Logs. A missing provider record can point to a problem starting the transfer or a configuration problem. A provider error identifies a downstream failure to investigate with that provider.

5

Analyze SIP packets (SIP calls only)

For SIP trunking or bring-your-own-number setups, analyze the SIP signaling.

Check whether a packet capture is available: Look for artifact.pcapUrl in the call record you retrieved in the first step.

For an eligible Vapi or bring-your-own SIP phone call, the completed call can contain artifact.pcapUrl when packet capture was enabled and retained. If present, download that URL and open the capture in a SIP analysis tool. For example, Wireshark supports SIP. A missing URL does not prove that no transfer command was sent.

Filter for transfer packets:

Wireshark filter
sip.Method == "REFER"

What to look for:

  • REFER request present: The transfer request reached the SIP signaling path captured in this file.
  • 202 Accepted response: The SIP provider accepted the transfer request. Check any later NOTIFY or referred-call status, because acceptance alone doesn’t prove that the destination answered.
  • Error response (4xx or 5xx): The SIP provider rejected the transfer request.
  • No REFER request: Check whether the transfer used sipVerb: "dial" or sipVerb: "bye", whether capture started before the transfer, and whether the tool was invoked. Vapi numbers always dial the destination, so look for the dial leg instead.

With sipVerb: "refer", your SIP provider completes the transfer after it accepts the REFER request, so its logs show the outcome. With sipVerb: "dial", Vapi calls the destination itself, so inspect the outbound dial leg instead of looking for a REFER. Vapi numbers always transfer this way. With sipVerb: "bye", Vapi ends its leg without dialing the destination.

For SIP configuration details, see the SIP trunk inbound call test.

Diagnose busy, no answer, rejection, voicemail, and timeout

Recovery depends on the transfer mode. Check transferPlan.mode before changing a fallback setting.

Mode or pathWhat to checkCaller recovery
Blind transfer or non-assistant warm transferProvider call record for busy, no answer, rejection, voicemail, or a failed destination legTwilio: Vapi hands the call to Twilio and ends with assistant-forwarded-call, even if the destination is busy or doesn’t answer. The caller’s call ends, and voicemail counts as answered.

Vapi numbers and SIP trunks: Busy and no-answer can have their own ended reasons when transfer outcome detection is enabled. Otherwise the call ends with assistant-forwarded-call.
warm-transfer-experimentalOperator-leg status, transferAssistant configuration, transfer-assistant tool call, and timeoutWith transferAssistant configured, busy and no-answer statuses roll back. transferCancel can roll back a declined call or detected voicemail. After rollback, the original assistant says the configured fallback message.
Blind SIP transfer with SIP transfer fallbackTransfer outcome, fallbackPlan, and provider recordAfter a busy, unanswered, or failed transfer, the original assistant says the fallback message, then continues or ends the call.

For assistant-based warm transfer, set fallbackPlan.endCallEnabled explicitly. Set it to false to keep the original assistant on the call after the fallback message, or to true to end the call after the message.

When the destination is voicemail or an automated queue, the transfer assistant must cancel the transfer, or configured voicemail detection must identify the non-human destination. Do not assume that a standard message, summary, or TwiML introduction detects voicemail.

Read the call’s messages and logs with the ended reason rather than using that field alone to decide where the failure occurred.

A failed transfer command can end with call.in-progress.error-transfer-failed. On a blind SIP transfer with SIP transfer fallback enabled, a configured fallbackPlan can also handle a recoverable transfer-request failure while the caller is still connected to Vapi. It cannot recover a call that has already ended.

An operator-leg busy or no-answer outcome can produce a different reason or return the caller to the original assistant, depending on the mode and recovery configuration.

Fix transfer tool and message problems

SymptomLikely causeResolution
The assistant selects the wrong destinationDestination descriptions overlap or do not state a clear routing intentGive every destination a distinct description and add matching routing rules to the system prompt.
The tool returns a validation or configuration errorThe destination is missing or malformedConfirm that destinations is an array and that each item has a valid type and required value. Use E.164 format for public switched telephone network (PSTN) phone numbers.
The assistant transfers when it should continue helpingThe prompt permits broad invocationNarrow the prompt conditions. For tools configured through the API, you can also add a tool rejection plan.
The same request is transferred on some calls and refused on othersThe prompt asks the model to apply several rules before it transfers, such as office hours, eligibility flags, or building the destination numberMove the rules to your server. Leave the destination off the tool so Vapi sends a transfer-destination-request, then respond with a destination or an error.
The assistant says it’s transferring, then nothing happensYour server refused the transfer, and the tool has no request-failed message, so the default Transferring the call now playedAdd a request-failed message to the tool.
The caller hears silence before the transfer messageVapi is waiting for your server’s response to transfer-destination-requestRespond faster, or store the destinations on the tool. The request-response-delayed message doesn’t apply to transfers.
A transfer you set up as silent still plays a messageThe destination came from your server, and an empty message only silences destinations stored on the toolStore the destination on the tool with message set to an empty string.
The transcript repeats or cuts off the transfer messageThe transcript can duplicate or truncate the assistant’s last line before the transferListen to the recording to confirm what the caller heard.
An assistant-to-assistant transfer stalls or behaves like an external callThe transfer call tool is being used for assistant routingUse the handoff tool for transfers between standalone assistants or assistants in a Squad.

Common solutions

The transfer started but the destination never answered

  • Use E.164 format with the country code, for example +14155550100.
  • Call the destination directly from another phone to confirm it’s reachable.
  • Check whether the destination blocks or screens incoming calls, for example with call blocking or spam filtering.
  • Find the call in your phone provider’s logs to see why it didn’t connect.
  • Check the Transfer Completed entry in the call’s Logs tab. A result of unconfirmed means Vapi received no final outcome, not that the destination answered or received the call.

The assistant didn’t transfer the call

  • Confirm the transfer tool is attached to the assistant and has a destination.
  • Describe when to transfer in both the tool description and the assistant prompt. The assistant saying it will transfer doesn’t start a transfer.
  • Check that phone-call-control isn’t in serverMessages unless your server handles transfers.
  • Confirm the call is a phone call. Web calls can’t transfer to a phone number or SIP address.

The packet capture has no REFER request

  • Check transferPlan.sipVerb. With dial, look for the outbound call to the destination instead. Vapi numbers always use dial.
  • Confirm a SIP destination is a full SIP URI, for example sip:support@example.com.
  • Check that phone-call-control isn’t sending the transfer to your server.

Limitations

  • Web calls can’t transfer to a phone number or SIP address. The call ends with call.in-progress.error-transfer-failed.
  • Vonage calls can’t transfer to a SIP address.
  • Warm modes that speak a message or summary, or run TwiML, work only on Twilio. Other providers transfer the call without the introduction.
  • Assistant-based warm transfer on Twilio needs a phone-number destination. A SIP destination is transferred without the transfer assistant.
  • Transfer outcome detection and SIP transfer fallback are available on Vapi numbers and SIP trunks.
  • Your server completes transfers when serverMessages includes phone-call-control. Vapi sends transfers to your server instead of transferring the call itself.

When to contact support

Contact support when the tool was invoked with a supported configuration but the Vapi and provider records disagree, a transfer error has no clear cause, or the same failure persists across controlled calls.

Include in your support request:

  • Vapi call ID, timestamp, call type, and endedReason
  • Transfer tool ID, mode, destination type, and a redacted destination
  • Expected caller and operator outcome, plus what each party heard
  • Relevant Messages and Logs entries, including the transfer tool call and fallback behavior
  • phoneCallProviderId, provider call record, error code, and SIP trace or artifact.pcapUrl when available
  • Whether phone-call-control in serverMessages sends transfers to your server
  • Screenshots of the transfer tool and transfer plan settings in the Dashboard

Next steps

Test the chosen transfer mode with a reachable operator, a busy destination, and an unanswered call before using it for production escalation. For SIP routing, compare the result with your SIP trunk configuration. To catch transfer failures early, set up monitoring with an Insight that tracks transfer-related ended reasons, such as call.in-progress.error-transfer-failed and call.forwarding.no-answer.