Skip to content
Bring your own SIP trunk

Bring your own SIP trunk: AI voice agents on the carrier you already use

Wixzel Voice runs your AI voice agents over the SIP trunk you already own, from Twilio, Telnyx, Plivo, Vonage, Bandwidth, Exotel, Vobiz or any SIP provider. Your numbers and your carrier rates stay yours: Wixzel Voice never sells or ports numbers and never marks up minutes.

Last updated

Published . The carrier names are trademarks of their owners; Wixzel Voice integrates with them over standard SIP and is not affiliated with or endorsed by any of them.

Why bring your own SIP trunk?

Wixzel Voice is a voice AI API for building AI agents that place and answer real phone calls over your own SIP trunk, or talk to people in your web and mobile apps. One API key and one prepaid balance cover every voice engine, billed per second of actual usage.

Wixzel Voice is the voice AI API for building AI phone agents, and it stops at the voice. The phone line is yours. That is a deliberate trade: it means one more step before your first call, and it means Wixzel Voice is never between you and your telephony provider. There is no markup, no resale margin, and no reason for Wixzel Voice to care which carrier you pick.

  • Your numbers stay yours. Wixzel Voice does not sell or port numbers, so leaving costs you nothing but a setting at your carrier.
  • Your carrier rates stay yours. The carrier bills you directly for the line. Wixzel Voice charges only for the voice engine, billed per second of actual usage from a prepaid balance.
  • Your compliance stays with your carrier. Caller ID provisioning, KYC and destination registration are between you and the carrier you already trust with them.

How does a bring-your-own SIP trunk connect?

A Wixzel Voice trunk has two halves, and they live in different parts of your carrier's console. Both addresses are returned on every trunk, so read them from the API rather than trusting a page to stay current.

Outbound: calls from the platform
platform_ip

Add 95.216.218.102 to your carrier's IP allowlist. Nearly every carrier authorises outbound calls by source IP, and a trunk that is correct in every other respect still fails without it.

Inbound: calls to your numbers
origination_uri

Set your carrier's inbound destination to sip:95.216.218.102:5090. Miss it and a number simply never rings: the carrier has nowhere to deliver the call, so nothing appears in any log.

Read both from the API
curl https://api.voice.wixzel.com/v1/sip-trunks \
  -H "Authorization: Bearer $WIXZEL_API_KEY" \
  | jq '.data[0] | {platform_ip, origination_uri}'

Which carriers have a setup guide?

Every carrier below has its own page with what to buy, what to allowlist, where inbound calls go, the trunk request that fits it, and the gotchas that are specific to it, with a link to the full console steps in the docs. Each carrier names the two settings differently; the setting is the same.

CarrierProductAllowlist is calledInbound destination is calledTransport
TwilioElastic SIP TrunkingIP Access Control ListOrigination SIP URIudp
TelnyxSIP Connectionsauthorised addresses on an IP-authenticated SIP ConnectionNot named in the guide yetudp
PlivoZentrunkIP Access Control ListPrimary URIudp
VonageProgrammable SIPACL (Access Control List)Not named in the guide yetudp
Bandwidth-Voice IP addresses / DNS hosts on a locationOriginationudp
ExotelVirtual SIP Trunking (vSIP)ACL mapped to the trunkDestination URItcp
Vobiz-IP ACLNot named in the guide yetudp
Any SIP provider-IP ACL, allowlist or authorised addressOrigination URI, or the carrier's name for itudp

What do carriers call the two settings?

What it doesNames carriers use
Authorise calls from Wixzel VoiceIP ACL, IP Access Control List, Access Control List, allowlist, authorised address, network bridge
Deliver calls to Wixzel VoiceOrigination URI, Primary URI, Destination URI, termination point, destination SIP URI, host

Two more settings decide whether a correct-looking trunk works. Number format: Twilio, Telnyx and Vobiz expect the leading +; many wholesale carriers cannot parse it and time out with 408, which send_plus: false fixes. Transport: UDP is the default almost everywhere, but Exotel does not take UDP, so an Exotel trunk runs over TCP, and a mismatch looks like the carrier ignoring you.

What happens when a call does not connect?

A call the API accepted and the carrier then refused shows status: "failed" (or busy for cause 17 and no-answer for cause 19) on GET /v1/calls/{id}, with failure_code (the Q.850 cause from the carrier, the stable thing to branch on) and failure_reason (what to do, in plain language). Its cost_micros is null: a call that never connected costs nothing, and the credit reserved for it is released.

Read your carrier's own call log first. If the call is not listed, it never reached the carrier: the allowlist, the trunk host or a firewall is wrong. If it is listed with zero answered and zero cost, the carrier accepted the INVITE and then cleared it, which is a carrier permission problem far more often than a configuration one: the caller ID you present must be authorised on the account, KYC and any destination registration must be complete where the market requires them, and the destination range must be enabled, not just funded. These are the causes the API explains:

failure_codeCarrier saidWhat it meansWhat to do
1404The carrier does not recognise the number.Check the number format. If the carrier needs a technical dial prefix, set dial_prefix on the trunk.
3-The carrier has no route to this destination.The destination is probably not enabled on your carrier account. Ask the carrier to open the route.
16-Normal clearing: the far end ended the call deliberately.On a call that was never answered, read it as something upstream choosing to end the call, not as a completed call.
17486The number is busy.-
18480The destination did not respond.The phone may be switched off or unreachable.
19-It rang and nobody answered.Nothing to fix: the trunk and the number both work.
20-The subscriber is absent or unreachable.-
21403 / 407The 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.
22-The number has changed and is no longer in service.-
27-The destination is out of order.-
28484The carrier rejected the number format.If the carrier needs a technical dial prefix, set dial_prefix on the trunk.
34-The carrier has no circuits available (congestion).Retry shortly.
38500 / 501 / 502The carrier returned a server error.-
41503The carrier is reachable but refusing calls.Usually capacity, balance, or a route being down at the carrier.
42-The carrier's switch is congested.Retry shortly.
58488Codec mismatch: the carrier rejected the audio codecs offered.Offer G.711 (PCMU or PCMA) on the carrier side. G.729 is not supported.
88493The carrier rejected the call as incompatible.-
102408The carrier did not respond in time.Verify the trunk host and port, and that the carrier accepts SIP from platform_ip. If the carrier shows the call as received but never answered, set send_plus to false.

These are refused by POST /v1/calls before anything is dialled, and cost nothing:

HTTP statuscodeWhat it means
400no_outbound_numberNo caller ID: pass from_number_id, or set outbound_phone_number_id on the agent.
400number_not_on_trunkThe calling number has no sip_trunk_id, so there is nowhere to send the call.
400missing_idempotency_keyThe raw HTTP request had no Idempotency-Key. The SDKs send one for you.
402insufficient_creditsThe balance cannot fund the first 15 seconds. Top up and retry.
429rate_limit_exceededMore than 10 requests per second on this key. Wait for Retry-After; a 429 is never charged.
503-The voice engine is unavailable, the account already has as many calls in progress as its concurrent-call limit (5 by default), or the API key has reached its spend limit. The message says which.

GET /v1/sip-trunks/{id}/status shows whether the trunk is reachable right now and lists its last few carrier rejections; POST /v1/sip-trunks/{id}/test probes it on demand, and GET /v1/sip-trunks/{id}/logs returns the SIP log.

cURL
curl https://api.voice.wixzel.com/v1/sip-trunks/$TRUNK_ID/status \
  -H "Authorization: Bearer $WIXZEL_API_KEY"

An inbound number that never rings is not a failure you can look up: if the carrier has no destination set, the call never leaves the carrier, so there is no failed call to inspect. Check the inbound destination, that the number is attached to the trunk on the carrier side, and that it has an inbound_agent_id. If calls connect but nobody hears anything, the media is not getting through: a firewall in the path has to allow the RTP range, not just the signalling port.

Frequently asked questions

Why does Wixzel Voice need my own SIP trunk?
Because Wixzel Voice never sells or ports phone numbers and never resells telephony. Phone calls run over a trunk from a carrier you choose, so your numbers stay yours, your carrier bills you directly at your rates with no markup, and Wixzel Voice has no reason to care which carrier you pick. The cost is one more setup step before the first call.
Which carriers work with Wixzel Voice?
Any carrier that offers a SIP trunk with IP allowlisting (or username and password authentication) and a configurable destination for inbound calls. There are setup guides for Twilio, Telnyx, Plivo, Vonage, Bandwidth, Exotel, Vobiz, and a general one for any other SIP provider.
What are the two settings a trunk needs?
The outbound half is an allowlist entry at the carrier for platform_ip (95.216.218.102 today), so the carrier accepts calls from the platform. The inbound half is the carrier's destination for inbound calls set to origination_uri (sip:95.216.218.102:5090 today), so calls to your numbers reach the platform; a carrier that takes a bare host and port, or will not send UDP, needs a different form of it, which its guide gives. Both are returned on every trunk by GET /v1/sip-trunks: read them from there rather than copying them from a page.
Can I keep my existing phone number?
Yes, if it is on a SIP trunk you can route. Register it with POST /v1/phone-numbers on that trunk and give it an inbound_agent_id. Wixzel Voice does not port numbers, so the number stays with your carrier.
How is my carrier password stored?
A new or updated password is encrypted at rest with AES-256-GCM under a key held only by the deployment; one saved under the older scheme is re-encrypted that way the next time it is saved. It is never returned by the API again, including to you. Store it wherever you keep the rest of your carrier credentials.
Do I need a SIP trunk for a web or mobile app?
No. A trunk is only for phone calls. To put an agent in a web page or an app, your server mints a realtime session with POST /v1/realtime/sessions and the app talks to the agent over a WebSocket, with no trunk and no number.
Do trunk changes need a restart?
No. Creating, updating or deleting a trunk rewrites the telephony configuration and reloads it, so a change takes effect immediately.
Do I buy phone numbers from Wixzel Voice or from my carrier?
From your carrier. Wixzel Voice never sells or ports phone numbers and never marks up carrier minutes. You register a number you already own with POST /v1/phone-numbers on the trunk it lives on.
Why does my number never ring the agent?
Inbound is configured separately from outbound. Your carrier has to deliver the call to the origination_uri your trunk returns (sip:95.216.218.102:5090 today), the number has to be attached to that trunk on the carrier side, and the number needs an inbound_agent_id in Wixzel Voice. Without the first, the call never leaves the carrier and nothing appears in any log.
What does an AI call over my own SIP trunk cost?
Two bills. Your carrier charges its own per-minute rate for the line, directly to you. Wixzel Voice charges the voice engine per second of actual usage: from $0.0466 per connected minute on gemini-live to $0.1851 on deepgram-agent, prepaid from a minimum top-up of $5, with no subscription and no free tier. A call that never connects costs nothing on the Wixzel Voice side.

Carrier guides