Solution Needed Urgent
# support
a
Hello Vapi Team , I'm building an AI receptionist for a UK estate agency using VAPI. The receptionist answers inbound calls, greets the caller, finds out which department they need, and then transfers them to that department's phone number. The flow I need is: Caller rings in AI receptionist answers and asks which department they need Receptionist transfers to that department's number If the department answers — great, call connects If the department does not answer after 15 seconds — cancel the transfer and return the caller back to the AI receptionist who then takes a message The transfer itself works perfectly. The destination rings every time. The problem is step 5 — cancelling the transfer and returning to the assistant. I have tried every cancel method I can find and all fail with "failed to route call": type: "hangup", leg: "destination" — failed type: "cancel-transfer" — failed type: "transfer", transferPlan: { mode: "cancel" } — returns "property transferPlan should not exist" The controlUrl works fine for initiating the transfer but every command sent to it after the transfer fires returns "failed to route call". It seems like the controlUrl becomes invalid or the assistant is detached the moment the blind transfer executes. Has anyone successfully built a transfer with fallback return to assistant? What is the correct architecture for this? Any working production examples would be really helpful.
v
Thank you for the detailed description. Based on Vapi's documentation, returning the caller to the assistant after a failed transfer is only supported with assistant-based warm transfer (using
warm-transfer-experimental
mode), and only with certain providers (Twilio, Vapi numbers, or SIP trunks). Could you confirm which transfer mode you are currently using (blind, warm, or assistant-based warm transfer), and which telephony provider (e.g., Twilio, Vonage, SIP) your system is configured with? This will help me provide the most accurate solution or example for your fallback scenario. If you are not using assistant-based warm transfer, I can guide you through setting it up for your use case. Sources: - [Assistant-based warm transfer](https://docs.vapi.ai/calls/assistant-based-warm-transfer) - [Call Forwarding](https://docs.vapi.ai/call-forwarding) - [Call Handling with Vapi and Twilio](https://docs.vapi.ai/calls/call-handling-with-vapi-and-twilio)
a
We are currently using blind transfer with a Twilio number. The transfer mode is type: "transfer" with destination type: "number". We are using a Twilio phone number imported into VAPI. Please guide us through setting up assistant-based warm transfer with warm-transfer-experimental mode so that if the department does not answer after 15 seconds the call returns to the assistant. Please provide a working code example for Node.js Express.
@User Support Bot We are currently using blind transfer with a Twilio number. The transfer mode is type: "transfer" with destination type: "number". We are using a Twilio phone number imported into VAPI. Please guide us through setting up assistant-based warm transfer with warm-transfer-experimental mode so that if the department does not answer after 15 seconds the call returns to the assistant. Please provide a working code example for Node.js Express.
@Vapi Support Bot We are currently using blind transfer with a Twilio number. The transfer mode is type: "transfer" with destination type: "number". We are using a Twilio phone number imported into VAPI. Please guide us through setting up assistant-based warm transfer with warm-transfer-experimental mode so that if the department does not answer after 15 seconds the call returns to the assistant. Please provide a working code example for Node.js Express.
v
To set up assistant-based warm transfer with a 15-second fallback, use the following Express route to trigger the transfer. This configuration ensures that if the department does not answer within 15 seconds, the call returns to the assistant:
Copy code
js
app.post("/transfer", async (req, res) => {
  // Replace with your actual values
  const departmentNumber = "+441234567890";
  const transferPayload = {
    type: "transferCall",
    function: { name: "departmentTransferAssistant" },
    destinations: [
      {
        type: "number",
        number: departmentNumber,
        transferPlan: {
          mode: "warm-transfer-experimental",
          transferAssistant: {
            firstMessage: "Hello, I have a caller for your department. Are you available?",
            maxDurationSeconds: 15, // 15-second timeout
            model: {
              provider: "openai",
              model: "gpt-4o",
              messages: [{ role: "system", content: "You are the transfer assistant." }]
            }
          }
        }
      }
    ]
  };
  // Send this payload to Vapi's API endpoint for call control
  res.json(transferPayload);
});
This approach uses the built-in fallback: if the department does not answer, Vapi will automatically return the caller to the assistant. See the [assistant-based warm transfer documentation](https://docs.vapi.ai/calls/assistant-based-warm-transfer) for more details. Source: - [Assistant-based warm transfer](https://docs.vapi.ai/calls/assistant-based-warm-transfer)
a
@Vapi Support Bot Our server is correctly returning the warm-transfer-experimental payload but the destination phone is not ringing at all. VAPI immediately returns the request-failed message without attempting to dial. Our Railway logs confirm the payload is being sent correctly from the server. Does warm-transfer-experimental work when the transferCall config is returned dynamically from a server webhook, or does it need to be configured directly on the assistant in the VAPI dashboard? If it needs to be on the dashboard please show us exactly how to configure it there.
v
According to the documentation, assistant-based warm transfer (
warm-transfer-experimental
) can be configured dynamically by returning the correct
transferCall
payload from your webhook, and does not require setup directly in the dashboard.
If your payload matches the documented structure and you are using a supported provider (Twilio), it should work—double-check that your
function.name
matches the assistant's configuration and that all required fields are present. If the issue persists, review the [assistant-based warm transfer guide](https://docs.vapi.ai/calls/assistant-based-warm-transfer) for payload examples and limitations, and consider reaching out to Vapi support if your configuration appears correct but still fails. Source: - [Assistant-based warm transfer](https://docs.vapi.ai/calls/assistant-based-warm-transfer)
s
Hi Aditya, Thanks for the detailed writeup - let me walk you through what's happening and how to fix it. What's going on Your hypothesis is correct. The controlUrl becomes invalid the instant a blind transfer fires. Here's why: blind transfer means "hand this call to Twilio and walk away." Once Vapi sends the blind transfer command, the Vapi call session ends, the AI assistant is detached, and the controlUrl is destroyed. Every command you send after that - hangup, cancel-transfer, anything - returns "failed to route call" because there's no call on Vapi's side anymore. Twilio owns the call and Vapi can't touch it. This isn't a bug - it's how blind transfer is designed. It's a one-way handoff with no return path. The fix: warm-transfer-experimental The Discord bot was right. You need to switch to warm-transfer-experimental mode with a transferAssistant. This is the only transfer mode in Vapi that keeps Vapi in the loop while the destination rings, lets you cancel the transfer and return the caller to the AI, and supports timeout-based fallback. Here's how it works: 1. Your original AI receptionist triggers the transfer 2. The caller gets put on hold (with hold music) 3. A separate transfer assistant dials the department 4. If the department answers and confirms → call connects 5. If the department doesn't answer → the transfer assistant calls transferCancel → caller returns to the original AI receptionist to take a message Docs for reference: https://docs.vapi.ai/calls/assistant-based-warm-transfer Best regards, Vapi Support