LiveKit
Connect LiveKit Agents to Vonyx numbers over a SIP trunk, for outbound and inbound calls.
Point a LiveKit outbound trunk at Vonyx so your agents can dial Indian numbers, and forward your Vonyx number to your LiveKit SIP endpoint so callers reach an agent. Both directions use plain SIP over UDP or TCP.
Before you start
- A Vonyx SIP trunk with a number attached, and the trunk's username and password
- A LiveKit Cloud project
- The LiveKit CLI (
lk), signed in to that project - An agent built with LiveKit Agents, registered with an
agent_name(explicit dispatch)
Outbound calls
Create an outbound trunk
The outbound trunk tells LiveKit where to send the SIP INVITE and which credentials to use.
| Field | Value |
|---|---|
address | 43.204.9.41 (hostname or IP only, no sip:; Vonyx listens on the default port 5060) |
numbers | Your Vonyx number, 91XXXXXXXXXX. LiveKit uses it as the caller ID. |
destination_country | in, so LiveKit places the call from its India region |
auth_username / auth_password | Your Vonyx trunk username and password |
Pass the credentials as flags so they stay out of the file:
The command prints SIPTrunkID: ST_…. Save it. You can list trunks later with lk sip outbound list.
You can also create the trunk in LiveKit Cloud under Telephony → SIP trunks → Create new trunk → JSON editor, with Trunk direction set to Outbound. That editor takes the object without the trunk wrapper and accepts auth_username and auth_password directly.
Leave transport unset (auto) or set it to UDP or TCP. Don't turn on media encryption: Vonyx doesn't support TLS or SRTP.
Place a test call from the CLI
Create a SIP participant. LiveKit dials sip_call_to through the trunk and puts the callee in room_name.
With wait_until_answered, the command returns once the callee picks up. This call has no agent in the room, so you only confirm that the phone rings and the call connects.
Dial from your agent
In your agent's entrypoint, read the number from the job metadata and create the SIP participant in the agent's own room. This follows LiveKit's outbound example for the Python livekit-agents / livekit-api packages.
To place a different caller ID per call, set sip_number on the request to another of your Vonyx numbers instead of creating a new trunk.
Dispatch the agent with a number
Start a job for the agent in a new room and pass the number to dial:
From a backend, use lkapi.agent_dispatch.create_dispatch(api.CreateAgentDispatchRequest(agent_name=..., room=..., metadata=...)) instead.
Inbound calls
Find your LiveKit SIP endpoint
Your SIP URI is on the Project settings page in LiveKit Cloud and looks like sip:abc123xyz.sip.livekit.cloud. The SIP endpoint is the same value without sip:.
You can also build it from the CLI: run lk project list --json, take the ProjectId (for example p_abc123xyz) and drop the p_ prefix.
To keep calls in India, you can use the region endpoint abc123xyz.india.sip.livekit.cloud instead.
Create an inbound trunk
The inbound trunk accepts calls to your Vonyx number.
Save the trunk ID it prints.
Restricting by IP
LiveKit's allowed_addresses field could limit the trunk to 43.204.9.41, but LiveKit must enable it for your project first (contact LiveKit support). Without it, the numbers list is what restricts the trunk.
Add a dispatch rule that sends calls to your agent
The dispatch rule puts each caller in a new room (prefixed call-) and dispatches your agent to it through room_config.agents. The agent_name must match the name in your agent's rtc_session decorator.
If you leave out trunk_ids, the rule matches every inbound trunk. In the agent, ctx.job.metadata is empty on inbound calls unless you set metadata on the agent entry, so the code above skips dialing and the agent can greet the caller.
Point Vonyx at LiveKit
In the Vonyx console, open your trunk, turn on Inbound calls and set the Inbound address to your SIP endpoint, for example abc123xyz.sip.livekit.cloud. Leave out sip: and any user part. See Inbound calls.
Vonyx then forwards calls to the attached number from 43.204.9.41.
Test the connection
- Outbound: run
lk sip participant create sip-participant.jsonwith your own phone assip_call_to. Your phone should ring with your Vonyx number as caller ID. - Agent outbound: start your agent in dev mode and run the
lk dispatch createcommand above. The agent should talk once you answer. - Inbound: with the agent running, call your Vonyx number. A room named
call-…should appear in LiveKit Cloud with a SIP participant and your agent.
The SIP participant's sip.callStatus attribute is active once a call connects, and sip.trunkPhoneNumber shows the number LiveKit matched on.
Limitations
- DTMF and call transfer are not available on Vonyx yet, so don't rely on LiveKit's
dtmffield, DTMF events orTransferSIPParticipant. - New accounts make 1 call at a time (raise limits).
- No TLS or SRTP: keep LiveKit transport on UDP, TCP or auto, and media encryption off.
- Codecs are PCMU and PCMA only.
- Caller ID (
numbersorsip_number) must be one of your Vonyx numbers.
Troubleshooting
| Problem | Fix |
|---|---|
SipCallError with 401 or 407 | The trunk username or password is wrong. Re-create the trunk with the right --auth-user and --auth-pass. |
| Outbound call rejected right away | Check the caller ID in numbers (or sip_number) is one of your Vonyx numbers and the dialled number is 91XXXXXXXXXX. |
SipCallError with 486 or 603 | The callee rejected the call. |
SipCallError with 408 or 480 | No answer or the callee was unreachable. |
| Second parallel call fails | New accounts have 1 channel. See limits. |
| Inbound call never reaches LiveKit | Check the inbound address has no sip: prefix and that Inbound calls is on. |
| Inbound call reaches LiveKit but is rejected | The called number didn't match the trunk's numbers. Add the format Vonyx sends, or check trunk_ids on the dispatch rule. |
| Room is created but no agent joins | The agent_name in the dispatch rule doesn't match the agent's rtc_session(agent_name=...), or the agent isn't running. |
| Call connects with no audio | Vonyx sends RTP over UDP 10000–20000 with PCMU or PCMA only. Don't restrict LiveKit's codecs to others. See SIP troubleshooting. |