Connect self-hosted LiveKit to an Indian phone number
Use your own LiveKit deployment with the SIP service enabled. Create the outbound and inbound trunks and the dispatch rule against your LIVEKIT_URL, open the firewall for RingTrunk's source IP, and point RingTrunk at your SIP service.
Updated 6 September 2026
In short: Self-hosted LiveKit connects to RingTrunk with the same three objects as LiveKit Cloud, plus one firewall rule for our source IP and an origination URI pointing at your SIP service.
This guide is for your own LiveKit deployment with the SIP service running. The LiveKit objects are the same as on LiveKit Cloud, created with lk against your LIVEKIT_URL. The only extra work is letting our source IP reach your SIP service.
1. Create the outbound trunk
cat > outbound-trunk.json <<'EOF'
{
"trunk": {
"name": "RingTrunk outbound",
"address": "pstn.ringtrunk.com",
"transport": "SIP_TRANSPORT_TCP",
"numbers": ["9XXXXXXXXX"],
"auth_username": "TRxxxxxxxxxxxxxxxx",
"auth_password": "YOUR_SIP_PASSWORD"
}
}
EOF
lk sip outbound create outbound-trunk.jsonThe numbers entry is the caller ID this trunk may present and must be attached to your RingTrunk trunk. Pin the transport to TCP so the SRV port is honoured.
2. Create the inbound trunk
No credentials on this object. Our INVITE carries none, so credentials here make every inbound call fail with 401. Trust our source IP and list the number in every form the To header may take.
cat > inbound-trunk.json <<'EOF'
{
"trunk": {
"name": "RingTrunk inbound",
"numbers": ["9XXXXXXXXX", "+919XXXXXXXXX", "09XXXXXXXXX", "919XXXXXXXXX"],
"allowed_addresses": ["<RINGTRUNK_SOURCE_IP>"]
}
}
EOF
lk sip inbound create inbound-trunk.json3. Create the dispatch rule
cat > dispatch-rule.json <<'EOF'
{
"name": "RingTrunk inbound",
"rule": { "dispatchRuleIndividual": { "roomPrefix": "call-" } }
}
EOF
lk sip dispatch create dispatch-rule.json4. Open the firewall
Allow our source IP, shown on your trunk's Origination tab, to reach your SIP service port (5060 UDP and TCP by default) and your RTP port range. Firewalls and security groups match on the packet's source address, which is why this is an IP and not a hostname.
5. Point RingTrunk at your SIP service
In the RingTrunk portal, set the trunk's origination URI to your SIP service, for example:
your-sip-host.example.com:5060;transport=tcpHost only. No user@, no path, no IPv6 literal. Until this is set, inbound calls have nowhere to go.
6. Place and receive calls
Placing a call is identical to LiveKit Cloud: lk sip participant create with --trunk, --call for the destination, --number for the caller ID and --room, or create_sip_participant from the LiveKit API. Receiving works as soon as the origination URI is set and the firewall allows our source IP.
See Connect LiveKit Cloud for the call examples and Troubleshooting for what each SIP response means.