Connect a Twilio SIP trunk to Wixzel Voice
To run an AI voice agent on a Twilio number, connect Twilio Elastic SIP Trunking to Wixzel Voice: add the platform_ip your trunk returns to the IP Access Control List so outbound calls are accepted, and set the Origination SIP URI to its origination_uri so inbound calls arrive. Twilio keeps billing you for the line at your rates; Wixzel Voice bills the voice engine per second from a prepaid balance.
Last updated
Published
Twilio is the carrier; Wixzel Voice is the voice AI API that runs the agent on top of it. They work together over standard SIP. Twilio is a trademark of its owner, and Wixzel Voice is not affiliated with or endorsed by Twilio.
What do you need before you start?
- A Twilio account with Elastic SIP Trunking, and the host and credentials of the trunk.
- A phone number you own at Twilio, attached to that trunk. Wixzel Voice does not sell or port numbers.
- A Wixzel Voice API key and some prepaid credit. The minimum top-up is $5; there is no free tier.
- Wixzel Voice is in alpha and runs 5 concurrent calls per account by default, raised on request; web and app sessions count toward the same limit.
How do you create the Twilio trunk in Wixzel Voice?
The Termination SIP URI Twilio shows on the trunk, the same your-domain.pstn.twilio.com as in the console.
curl https://api.voice.wixzel.com/v1/sip-trunks \
-H "Authorization: Bearer $WIXZEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Twilio",
"host": "your-domain.pstn.twilio.com",
"transport": "udp"
}'Add username and password to the body if Twilio authenticates by credentials rather than IP. The password is encrypted at rest and never returned by the API again. The response carries platform_ip and origination_uri: the two values the next step needs.
What do you set at Twilio?
| Setting | What Twilio calls it | Value |
|---|---|---|
| Allowlist calls from Wixzel Voice | IP Access Control List | 95.216.218.102 |
| Send inbound calls to Wixzel Voice | Origination SIP URI | sip:95.216.218.102:5090 |
Both values are today's: read platform_ip and origination_uri from GET /v1/sip-trunks rather than copying them from a page. Then register each number on the trunk with POST /v1/phone-numbers and give it an inbound_agent_id, so an agent answers it. The AI phone call API walkthrough has those requests, and the full setup steps for Twilio go through the console field by field.
What goes wrong on Twilio?
- Twilio authorises outbound calls by source IP and rejects anything else instantly. A missing IP ACL entry shows up as an immediate rejection, roughly a second after the call is placed, with
failure_code21 (call rejected). It does not ring and it does not time out. - Outbound works without the Origination URI; inbound does not, and does not complain. The number is attached, the agent is assigned, and the phone simply never reaches the agent.
- Twilio expects the leading
+in the dialled number, so leavesend_plusat its default oftrue.
Why did a call over Twilio not connect?
The failure code most often seen on Twilio:
| failure_code | Carrier said | What it means | What to do |
|---|---|---|---|
| 21 | 403 / 407 | The carrier rejected the call outright, before it tried the number. | In order of likelihood: the carrier account is suspended, closed or out of balance; the trunk username or password is wrong; platform_ip is not allowlisted; or the caller ID is not authorised on the account. Check the carrier dashboard first. |
A call Twilio refused has status: "failed", a failure_code (the Q.850 cause from the carrier) and a failure_reason saying what to do, and it costs nothing. Every failure code, every refusal and how to debug a trunk are on the integrations page.
What does an AI call over Twilio cost?
Twilio bills you for the line at your rates; Wixzel Voice bills only the voice engine, per second of actual usage, from $0.0466 per connected minute on gemini-live to $0.1851 on deepgram-agent. Every engine's price.
Frequently asked questions
- Why is my Twilio call rejected within a second?
- A call that fails in about a second with
failure_code21 and no ringing was refused by Twilio before it was routed. On Twilio this is almost always the Termination IP Access Control List: add95.216.218.102(theplatform_ipyour trunk returns) to it. A call that is accepted and then fails several seconds later is a different problem: routing, number format or account permissions. - Can I use a Twilio Credential List instead of an IP ACL?
- Yes. Put the Credential List username and password on the Wixzel Voice trunk's
usernameandpasswordfields and they are used in place of IP authentication. The password is encrypted at rest and never returned by the API again.
Other carriers
An IP-authenticated SIP Connection. Add the platform IP as an authorised address, pick an inbound region, and match the transport.
Zentrunk. An outbound trunk with the platform IP in its IP ACL, and a separate inbound trunk whose Primary URI points at the platform.
Programmable SIP. Add the platform IP to the trunk's ACL in the SIP Dashboard, and send inbound calls to the origination URI.
No SIP REGISTER, so a static IP is required. Add the platform IP to the location, configure Termination and Origination separately, or use network-bridge credentials.
Virtual SIP Trunking (vSIP), for Indian numbering, over TCP. The platform IP mapped to the trunk as an ACL, and the Destination URI pointed at the platform's TCP port for inbound.
A per-trunk SIP domain as the host, the platform IP in the trunk's IP ACL, and "origination URI" meaning the opposite of what it means on Twilio.
The pattern is the same everywhere: allowlist the platform IP, set the inbound destination to the origination URI, and match the number format and transport.
How the two halves of a trunk work, every failure code, and every carrier guide on one page.
