Guide

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

outbound-trunk.json
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.json

The 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.

inbound-trunk.json
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.json

3. Create the dispatch rule

dispatch-rule.json
cat > dispatch-rule.json <<'EOF'
{
  "name": "RingTrunk inbound",
  "rule": { "dispatchRuleIndividual": { "roomPrefix": "call-" } }
}
EOF
lk sip dispatch create dispatch-rule.json

4. 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:

text
your-sip-host.example.com:5060;transport=tcp

Host 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.