Tranfering in-progress Twilio Call to Vapi
# support
s
I previously raised an issue regarding the DTMF tool not functioning as expected (https://discord.com/channels/1211482211119796234/1211483291191083018/threads/1349824417781514240) . In the meantime, I’m exploring a temporary workaround. After reviewing similar threads, I noticed that Vapi recommends bypassing the IVR outside using Twilio first, then transferring the call to Vapi. Are there any documentation resources available that explain how to transfer an in-progress call from Twilio to Vapi? I attempted to use TwiML Redirect with the URL https://api.vapi.ai/twilio/inbound_call, but received the following error from Vapi:
Copy code
{
  "message": [
    "CallStatus must be one of the following values: ringing",
    "Direction must be one of the following values: inbound, outbound"
  ],
  "error": "Bad Request",
  "statusCode": 400
}
Any guidance or clarification would be greatly appreciated.
v
Hi there! 👋 I understand you're trying to transfer an in-progress call from Twilio to Vapi and encountering an error. Let me help explain what's happening and provide some solutions. Unfortunately, I don't have access to your previous DTMF tool issue thread, but I can definitely help with your current transfer problem. ## Why You're Getting This Error The error you're seeing occurs because Vapi expects incoming calls to have a "ringing" status, but after gathering DTMF digits, Twilio changes the call status to "in-progress". This is standard Twilio behavior that can't be changed. Additionally, Vapi requires the Direction parameter to be either "inbound" or "outbound". ## Solutions for Transferring In-Progress Calls Here are several approaches you can use: ### 1. Use a Conference Call Approach After gathering DTMF tones, transfer the call to the Vapi assistant using a conference call instead of a direct redirect. This is a recommended workaround for the CallStatus issue. ### 2. Use WebSockets for Audio Streaming You can set up a WebSocket bridge between Twilio and Vapi:
Copy code
ts
app.post('/twilio/voice', async (req, res) => {
  // Create a Vapi call with bypass enabled
  const vapiCall = await fetch('https://api.vapi.ai/call', {
    method: 'POST',
    body: JSON.stringify({
      phoneCallProviderBypassEnabled: true,
      // other call parameters...
    })
  });
  const { callId } = await vapiCall.json();

  // Return TwiML to connect Twilio to your websocket
  const twiml = new VoiceResponse();
  const connect = twiml.connect();
  connect.stream({
    url: `wss://your-server.com/twilio-bridge/${callId}`
  });
  res.type('text/xml');
  res.send(twiml.toString());
});
This approach is documented in [Discord discussions](https://discord.com/channels/1211482211119796234/1211483291191083018/threads/1341810370700120064). ### 3. Use the Vapi API Directly You can bypass the TwiML redirect by making a direct API call to Vapi: ```json {
"phoneCallProviderBypassEnabled": true, "type": "inboundPhoneCall", "assistantId": "your-assistant-id", "phoneNumber": { "provider": "twilio", "number": "your-phone-number" }, "customer": { "number": "customer-number" }, "phoneNumberId": "your-phone-number-id" }
Copy code
### 4. Set Up Your Own Webhook Endpoint
Instead of auto-registering your Twilio number with Vapi, you can set up your own webhook endpoint, process the call as needed, and forward it to Vapi when required:

```python
@app.post("/twilio/inbound_call", response_class=PlainTextResponse)
async def receive_call_data(
        AccountSid: str = Form(...),
        ...,
        ToZip: Optional[str] = Form(None)
):
    call_data = CallData(
        AccountSid=AccountSid,
        ....,
        ToZip=ToZip
    )

    r = requests.post("https://api.vapi.ai/call", json={
        "phoneNumberId": "your-phone-number-id",
        "phoneCallProviderBypassEnabled": True,
        "customer": {
            "number": call_data.Caller
        },
        "assistantId": "your-assistant-id"
    }, headers={
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": f"Bearer {api_key}"
    })
    result = r.json()
    return result["phoneCallProviderDetails"]["twiml"]
This approach is documented in [Discord discussions](https://discord.com/channels/1211482211119796234/1211483291191083018/threads/1343397177182912553). ### 5. SIP REFER for Call Transfers For more advanced scenarios, you can use SIP REFER to transfer calls with additional context: ```javascript const transferDestination = { type: 'sip', sipUri: 'sip:genesys@your-domain.com', transferPlan: { mode: 'blind-transfer-add-summary-to-sip-header', summaryPlan: { // Configure how the summary should be generated } }, sipHeaders: { 'X-Caller-Intent': 'policy_inquiry', 'X-Caller-Details': JSON.stringify({ name: customer.name,
policy: customer.policyNumber }) } }; ``` For more information on SIP integration, check out these guides: - [SIP Inbound Guide](https://relieved-yuzu-73a.notion.site/SIP-Inbound-Guide-1f0789ae62024748a62a6d81076b9f32) - [SIP Outbound Guide](https://relieved-yuzu-73a.notion.site/SIP-Outbound-Guide-997d66df35284295b7149fc10c82f3e8) - [Dynamic Call Transfers](https://docs.vapi.ai/phone-calling/dynamic-call-transfers) - [SIP Documentation](https://vapi.notion.site/SIP-104008c8393f80feaeb7de8ca19565ed) Is there a particular approach you'd like me to explain in more detail? Sources: - [Discord discussion on WebSocket bridge](https://discord.com/channels/1211482211119796234/1211483291191083018/threads/1341810370700120064) - [Discord discussion on CallStatus error](https://discord.com/channels/1211482211119796234/1211483291191083018/threads/1342459464346767492) - [Discord discussion on webhook endpoint](https://discord.com/channels/1211482211119796234/1211483291191083018/threads/1343397177182912553) - [Discord discussion on SIP REFER](https://discord.com/channels/1211482211119796234/1211483291191083018/threads/1340813822193041499) - [SIP Inbound Guide](https://relieved-yuzu-73a.notion.site/SIP-Inbound-Guide-1f0789ae62024748a62a6d81076b9f32) - [SIP Outbound Guide](https://relieved-yuzu-73a.notion.site/SIP-Outbound-Guide-997d66df35284295b7149fc10c82f3e8) - [Dynamic Call Transfers](https://docs.vapi.ai/phone-calling/dynamic-call-transfers) - [SIP Documentation](https://vapi.notion.site/SIP-104008c8393f80feaeb7de8ca19565ed)
k
@Sedrick was this helpful?
s
VAPI assistants cannot join the in-progress call. Instead, either you have to create a conference call where you join the VAPI assistant with your primary number (which started the call) and the customer phone number, or you forward the call to the VAPI. Either way, you can then integrate the calls with VAPI assistant post-IVR navigation. Let me know if you require further help.
s
@Shubham Bajaj Thanks for your quick response. Let me try the conference method and get back to you.
s
Marking this ticket as Solved ✅
3 Views