DEV Community

Priyanka
Priyanka

Posted on

Setting up a SIP trunk for Voice AI: step-by-step (Twilio + Vapi)

SIP trunk configuration is the part of every Voice AI project that looks simple in the documentation and takes three times longer than expected in practice.

Not because the technology is hard - it is not - but because the failure modes are silent, the error messages are cryptic, and the gap between a correct-looking configuration and a working one is often a single codec setting.

This is the step-by-step guide I use on every deployment.
It covers Twilio as the SIP provider and Vapi as the Voice AI platform - the most common combination in production.

What you need before starting

  • A Twilio account with credit added
  • A Vapi account (free tier is fine to start)
  • A phone number purchased in Twilio (~$1/month)
  • Access to your firewall settings if on a corporate network

Step 1 - Create a SIP trunk in Twilio

In Twilio Console go to:
Voice → SIP Trunking → Trunks → Create new SIP Trunk

Name it something descriptive like voice-ai-production.

Settings to configure:

  • Call Recording: Record from Ringing (essential for debugging)
  • Secure Trunking: Enable if your platform supports SIP/TLS
  • Transfer Mode: Enable SIP Diversion Header (needed for call transfers)

Step 2 - Configure origination (inbound calls to your AI)

Click the Origination tab on your trunk.

Add a new Origination URI. Get the SIP URI from Vapi under:
Settings → SIP → Origination SIP URI

It will look like:

sip:your-account-id@sip.vapi.ai;transport=tcp
Enter fullscreen mode Exit fullscreen mode

Set Priority: 10, Weight: 10. Click Add.

⚠️ Most common mistake here: using transport=udp
instead of transport=tcp. With UDP, calls fail silently —
no error, the SIP INVITE just goes unanswered. Always
confirm required transport with your platform docs first.

Step 3 - Configure termination (outbound calls from your AI)

Click the Termination tab.

Your Twilio-generated termination SIP URI looks like:

your-trunk-name.pstn.twilio.com
Enter fullscreen mode Exit fullscreen mode

Copy this - you will paste it into Vapi in Step 4.

Under Authentication, create a credential list with a username and strong password. This is what Vapi uses to authenticate outbound calls through Twilio.

Under IP Access Control Lists, add Vapi's server IP
addresses (listed in Vapi's SIP documentation). This allows
Vapi's inbound traffic without password auth - reducing
SIP handshake latency.

Step 4 = Connect Vapi to the SIP trunk

In Vapi go to Settings → Phone Numbers → Import → SIP Trunk

Fill in:

Field Value
Outbound SIP URI your-trunk-name.pstn.twilio.com
Username Your Twilio credential username
Password Your Twilio credential password
Phone number E.164 format e.g. +441234567890
Codec PCMU (G.711) — matches Twilio default

Then in Twilio Console: Phone Numbers → Active Numbers → click your number → Voice → A CALL COMES IN → SIP Trunk → select your trunk → Save

💡 My approach: I explicitly set PCMU as the only codec
on both sides during initial setup - even if both platforms
support better codecs. Once the call path is confirmed
working, I then test enabling Opus. Narrowing to one codec
eliminates the most common failure mode before introducing
variables.

Step 5 - Test the call path

Run these four tests in order. Do not skip any of them.

Test 1 - Inbound from real phone
Dial your Twilio number from a mobile. The AI should answer.

  • Fast busy = origination URI wrong
  • Silence = codec mismatch
  • Twilio error recording = number not pointing to SIP trunk

Test 2 - Outbound from AI to real phone
Trigger an outbound call from Vapi to your mobile.

  • Call fails to initiate = termination URI or credential wrong
  • Connects but no audio = codec mismatch

Test 3 - Full 12-turn conversation
Run your full test script. Log per-turn latency. Test
human escalation transfer mid-conversation.

Test 4 - Concurrent load test
Place 5–10 simultaneous calls. Check for latency degradation.
Confirm Twilio account concurrency limits are adequate.

Common SIP errors and exact fixes

Error / Symptom Cause Fix
Fast busy on inbound Origination URI wrong Check SIP URI format
No audio either way Codec mismatch Set PCMU only on both sides
One-way audio NAT/firewall blocking RTP Open UDP 10000–20000
SIP 407 Proxy Auth Wrong credentials Recreate credential list
SIP 488 Not Acceptable No matching codec Add G.711 PCMU to platform
SIP 503 Unavailable Platform unreachable Check IP allowlist
Calls drop at 30s Missing session timer Enable session timers

Pre-go-live checklist

  • [ ] Inbound call test passed - two-way audio confirmed
  • [ ] Outbound call test passed - two-way audio confirmed
  • [ ] 12-turn conversation test completed, latency logged
  • [ ] Human escalation transfer tested and confirmed
  • [ ] Concurrent load test - 5+ calls without degradation
  • [ ] Twilio account upgraded from trial
  • [ ] Call recording enabled
  • [ ] Firewall: SIP port 5060/5061 + RTP 10000–20000 open
  • [ ] P50 and P95 latency baseline recorded
  • [ ] Rollback plan documented

The principle that saves the most time

Change one thing at a time.

When a call fails, revert to the last known working state,
change one variable, and test again.

SIP debugging done methodically takes minutes.
SIP debugging done by changing multiple settings simultaneously
is how teams spend a week on something that was always
going to work.

Full guide with architecture details and more context:
https://www.voiceaipm.com/2026/04/setting-up-sip-trunk-for-voice-ai.html

I write weekly about Voice AI and SIP telephony from real
enterprise deployments at voiceaipm.com

Top comments (0)