SIP trunks
Connect your own SIP infrastructure — a PBX, an SBC, or a carrier — to Ruut Voice. Trunks give you authenticated ingress and egress for programmatic or PBX-driven calling.
What a trunk does
- Termination (outbound): route calls from your PBX or API to the PSTN through Ruut Voice.
- Origination (inbound): receive calls from a carrier or SBC and route them to numbers, extensions, or TwiML applications.
- Auth: restrict which source IPs may send calls (inbound source allowlist) and how outbound calls authenticate.
Create a trunk
Create a SIP trunk via the dashboard (SIP Trunks → New trunk) or the API:
curl -X POST "https://voice.ruut.chat/carrier/v1/accounts/$RUUT_ACCOUNT_SID/sip_trunks" \
-u "$RUUT_ACCOUNT_SID:$RUUT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Carrier SBC",
"region": "hydrogen",
"inbound_source_ips": ["203.0.113.10"]
}'
Allowlist inbound source IPs
Add the public IPs of your SBC or carrier as inbound source IPs. Only traffic from these IPs is accepted on the trunk — everything else is dropped at the gateway. Whitelisting the gateway's own containers is required for dev/test calls (e.g. 172.19.0.x).
Assign a trunk to an account
Point an account's outbound calls at the trunk. In the dashboard open the account's Voice section and choose the SIP trunk. Via the API, set SipTrunkId on the account:
curl -X PATCH "https://voice.ruut.chat/carrier/v1/accounts/$RUUT_ACCOUNT_SID" \
-u "$RUUT_ACCOUNT_SID:$RUUT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "sip_trunk_id": "ST…" }'
Route calls through a trunk
Once assigned, outbound API calls from the account use the trunk automatically. Inbound calls from the trunk's source IPs are handled by the number's Voice URL or ring group.
Troubleshooting
- Call rejected / 403 — the source IP isn't in the trunk's inbound allowlist. Check gateway logs for
ACL … denies access to …. - 503 on lookup — the trunk or dispatcher isn't reachable. Verify the dispatcher list and FreeSWITCH reachability.
- No audio — see the security and troubleshooting notes in the platform docs.