rapid-honey-43838
02/12/2026, 7:45 PMtall-airline-16756
02/12/2026, 7:45 PMtall-airline-16756
02/12/2026, 7:46 PM<sip:username@sip.exampl>e.com) — redact passwords.
◦ Does your LiveKit SIP trunk require authentication (username/password or IP ACL)? If yes, which method?
◦ If using credentials, confirm Twilio is configured to send them (TwiML Dial attributes or Twilio SIP domain settings).
1. TwiML (the exact snippet)
◦ Paste the TwiML Dial/SIP element you’re using (or the relevant portion of your app that generates it). For example:
<Dial>
<Sip><sip:user@sip.exampl>e.com</Sip>
</Dial>
• Any custom SIP headers you set?
1. Errors & logs
◦ The exact error message you see in Twilio (call logs, call attempt status) or in your LiveKit logs.
◦ If available, SIP traces (INVITE/401/407/486/etc.) from Twilio or LiveKit (redact sensitive fields). The INVITE and final response are especially helpful.
1. Network / firewall details
◦ Are there firewalls or NAT between Twilio and LiveKit? Have you opened SIP ports (UDP/TCP 5060 and/or TLS 5061) and RTP ports required by LiveKit?
◦ If self-hosted, does your LiveKit server have a public IP or reachable hostname and valid certificate for TLS?
1. Reproduction & timing
◦ Is the failure for all calls or intermittent? When did it start?
◦ Can you reproduce consistently? If yes, note a recent call SID/timestamp so I can examine patterns you paste here.
What I’ll check next once you share the details:
• Verify TwiML syntax and credentials format.
• Identify SIP transport or authentication mismatches (e.g., Twilio sending INVITE without auth while LiveKit expects it).
• Look for network/firewall or TLS certificate issues.
• Suggest exact TwiML changes, LiveKit SIP trunk config adjustments, and test steps (including SIP trace extraction).
If you paste the TwiML and any INVITE/response lines you have, I can point to the likely failure point and give step-by-step fixes.rapid-honey-43838
02/12/2026, 7:48 PMtall-airline-16756
02/12/2026, 7:49 PMsip:username@domain is the user portion of the SIP address — the identifier the SIP provider expects (for example a trunk account name or endpoint ID).
• When SIP uses username/password (SIP digest) authentication, the “username” is the authentication account name provided by the SIP provider (often a trunk credential or account SID), and it’s paired with a password.
• LiveKit itself does not require a per-user SIP digest credential for trunking. LiveKit SIP integrations commonly use IP allowlisting or token/JWT-based methods rather than exposing a traditional SIP username/password for each endpoint.
What this means for a TwiML Dial to LiveKit:
• If Twilio (TwiML) is dialing a third-party SIP provider, put the SIP provider’s expected username in the SIP URI or in Twilio’s trunk credential set (e.g., <sip:username@sip.provid>er.com or Twilio trunk credentials).
• If you’re dialing LiveKit directly, LiveKit typically expects connectivity via the trunk configuration you set up (IP allowlist, TLS with valid certs, or token-based headers) instead of a simple SIP digest username/password.
If you want, tell me:
• The exact SIP URI or TwiML snippet you’re using (you can redact passwords), and
• Whether your LiveKit trunk is configured for IP allowlisting or for credential-based auth.
With that I can point out exactly where the “username” should go and recommend the right TwiML or LiveKit trunk configuration.
Sources: How Vicidial Handles Bridging, Transfers, and SIP Calls | sip | livekit/livekit_composite | DeepWiki | How VICIdial handles bridging, transfers, and SIP calls | LiveKitrapid-honey-43838
02/12/2026, 7:50 PMreturn fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>
<Sip username="%s" password="%s">
sip:%s@%s%s
</Sip>
</Dial>
</Response>`, username, password, toNumber, sipHost, queryString)
}tall-airline-16756
02/12/2026, 7:51 PMusername incorrectly in that TwiML snippet. I’ll address that and explain what to do next.
Short answer
• If LiveKit is the endpoint you’re dialing directly, the username and password attributes on TwiML’s <Sip> element will not authenticate against LiveKit in the way a traditional SIP digest account would. LiveKit SIP trunking typically relies on IP allowlisting or token/JWT-based mechanisms rather than per-call SIP digest credentials.
• If you are actually dialing a third‑party SIP provider (e.g., Twilio trunk → another SIP provider) that expects SIP digest auth, then embedding credentials in the SIP URI or configuring Twilio trunk credential sets is the correct approach — not necessarily the TwiML element attributes as you have them.
What’s happening with your snippet
• Your code builds a TwiML <Sip username="..." password="...">sip:toNumber@sipHost{query}</Sip>. Twilio does support `username`/`password` attributes on <Sip> for trunk credential use, but whether those credentials will be used to authenticate depends on the SIP endpoint’s expectations.
• LiveKit does not use per-call SIP digest username/passwords for trunking. If LiveKit expects IP allowlisting or token headers, those <Sip> attributes will be ignored by LiveKit and the call will fail to authenticate.
How to fix or verify depending on your setup
1. If LiveKit is the SIP endpoint:
◦ Confirm how your LiveKit trunk is configured: IP allowlist, TLS with certs, or header/token-based authentication.
◦ Use IP allowlisting (whitelist Twilio IPs) or configure the token/header-based method in the LiveKit trunk configuration — do not rely on `username`/`password` attributes.
◦ Ensure SIP transport (TLS vs plain SIP) and ports (5060/5061) and certificates are correct and reachable.
1. If the SIP endpoint expects SIP digest auth (a third‑party SIP provider):
◦ You can provide credentials in TwiML attributes, but often the recommended pattern is to use Twilio Trunk credential lists or to embed credentials in the SIP URI:
▪︎ Example SIP URI with credentials (redact in logs): sip:username:password@sip.example.com
◦ Alternatively, set the Credential List in the Twilio SIP Domain settings and reference it, so Twilio will supply correct auth on outbound INVITE.
Concrete next steps I can help with
• Tell me which endpoint you are dialing:
◦ A LiveKit trunk (hosted at a LiveKit domain / your LiveKit server), or
◦ A third‑party SIP provider/trunk (e.g., another SIP service)?
• Share the LiveKit trunk auth method (IP allowlist, token/JWT, or other). If you don’t know, I can list how to check.
• If you are dialing a non‑LiveKit SIP provider, paste the TwiML you’re generating (redact passwords) and the Twilio call log errors or SIP responses (INVITE/401/407/503). I’ll point out exactly where the username should be placed.
If you confirm which of the two cases above applies, I’ll give the exact TwiML or LiveKit configuration changes to try.rapid-honey-43838
02/12/2026, 7:52 PMtall-airline-16756
02/12/2026, 7:52 PM<Sip> will not authenticate to LiveKit.
• To connect Twilio → LiveKit you should use whatever auth method your LiveKit trunk is configured for (typically IP allowlisting or token/header-based auth and correct TLS/cert setup), and ensure Twilio can reach the LiveKit host and ports.
Why your current TwiML is likely failing
• Your snippet:
<Sip username="%s" password="%s">
sip:%s@%s%s
</Sip>
sets SIP digest credentials for Twilio to use. LiveKit does not expect SIP digest credentials for its trunks, so those attributes will be ignored by LiveKit and authentication will fail.
• If LiveKit expects IP-based trust or special headers/JWTs, the correct solution is to configure the LiveKit trunk and Twilio network settings accordingly — not to pass a username/password in the TwiML.
What to do next — checklist and concrete steps
1. Confirm LiveKit trunk auth method
◦ Tell me whether your LiveKit trunk is set up with IP allowlisting, token/JWT or header-based auth, or something else.
1. If LiveKit uses IP allowlisting (common):
◦ Whitelist Twilio’s outbound SIP IPs on your LiveKit side (or allow Twilio’s SIP traffic).
◦ Make sure LiveKit’s SIP port (UDP/TCP 5060 or TLS 5061) and RTP ports are reachable from Twilio.
◦ Use TwiML without username/password, e.g.:
<Response>
<Dial>
<Sip><sip:destination@your-livekit-host.exampl>e.com</Sip>
</Dial>
</Response>
• Ensure TLS is used if LiveKit requires it (use sips: and port 5061).
1. If LiveKit uses token/header-based auth:
◦ Configure Twilio to send the required headers or tokens (Twilio supports custom SIP headers in <Sip>).
◦ Example (how header might look — adapt to your required header name/value):
<Sip>
<sip:destination@your-livekit-host.exampl>e.com
<Header name="X-Auth-Token">your-token-value</Header>
</Sip>
• Or configure a SIP proxy/relay that injects tokens before reaching LiveKit.
1. Verify TLS & DNS
◦ If you use sips:, ensure your LiveKit host has a valid TLS certificate for the hostname Twilio is connecting to.
◦ Make sure the SIP host in the URI matches the cert CN/SAN.
1. Collect logs if it still fails
◦ Twilio call logs and SIP traces (INVITE and final response) and LiveKit logs (INVITE arrival and reject reason) will show the rejection cause. Paste those (redact secrets) and I’ll point to the exact failure.
If you tell me:
• Which auth method your LiveKit trunk is configured for (IP allowlist or token/header), and
• The TwiML you’re currently sending (redact passwords) and any Twilio or LiveKit error messages or SIP responses you see,
I’ll give exact TwiML examples and configuration steps tailored to that method.rapid-honey-43838
02/12/2026, 7:56 PMtall-airline-16756
02/12/2026, 7:56 PMSIPAdmin and SIPCall which permit trunk management and programmatic call actions.
• Result: Use the JWT to create and configure your LiveKit SIP trunk and routing, not as the primary SIP transport credential Twilio will use on the wire.
2) Primary SIP transport authentication — IP allowlisting (recommended)
• For Twilio → LiveKit trunks, the usual secure option is to whitelist Twilio’s outbound SIP IP addresses on your LiveKit server/firewall.
• Steps:
a. Collect Twilio’s outbound SIP IP addresses (Twilio publishes these).
b. Add those IP addresses to your LiveKit instance / firewall allowlist so INVITEs from Twilio are accepted.
c. Ensure the SIP transport and ports are reachable (UDP/TCP 5060 or TLS 5061) and that TLS certs match the SIP host if using sips:.
• Why: This treats Twilio as a trusted, authenticated source without requiring SIP digest credentials per call.
3) Optional: Header-based authentication for additional validation
• Purpose: Add another layer so LiveKit can extract and validate credentials carried as SIP headers (for example an API key or token injected by Twilio).
• How it works:
◦ Configure Twilio to add custom SIP headers in the outbound INVITE from your TwiML or Twilio trunk settings.
◦ Configure the LiveKit trunk to map specific SIP headers into participant attributes using headers_to_attributes in the trunk config.
◦ Your backend or LiveKit routing logic validates those attributes and decides whether to accept the call.
• Example TwiML (conceptual):
<Response>
<Dial>
<Sip>
<sip:destination@your-livekit-host.exampl>e.com
<Header name="X-Auth-Token">your-token-value</Header>
</Sip>
</Dial>
</Response>
• Note: exact header names and values depend on how your LiveKit trunk is configured to read them.
• LiveKit side mapping (conceptual JSON):
{ "trunk": { "headers_to_attributes": { "X-API-Key": "auth.api_key", "X-Auth-Token": "auth.jwt" } } }
• Then validate these attributes in your application (or via LiveKit hooks) to permit the incoming call.
4) Practical recommended flow
1. Use JWT server-side to create/configure the LiveKit inbound trunk and any dispatch rules.
2. Whitelist Twilio IPs in your LiveKit firewall/trunk settings.
3. If you need extra verification, have Twilio add a custom header with a token; configure LiveKit to map that header to an attribute and validate it.
4. Use simple TwiML without SIP digest username/password when calling LiveKit:
<Response>
<Dial>
<Sip><sip:destination@your-livekit-host.exampl>e.com</Sip>
</Dial>
</Response>
or include a header if you are using header-based auth (see example above).
5) TLS, DNS, and connectivity checks
• If you use sips: ensure the certificate on your LiveKit host covers the hostname Twilio connects to.
• Validate that Twilio can resolve your SIP host and reach the required ports.
• If calls still fail, collect Twilio SIP INVITE and LiveKit logs to see whether the INVITE reaches LiveKit and how LiveKit rejects/accepts it.
What I can do next
• If you want, paste the LiveKit trunk auth method (IP allowlist or header mapping) and your current TwiML (redact secrets). I’ll give an exact TwiML snippet and the LiveKit trunk config you should use.
• If calls are failing now, share the Twilio SIP INVITE and the LiveKit log response (redact secrets) and I’ll point to the precise mismatch.
Would you like to:
• Walk through generating the JWT you need to create the trunk, or
• See an exact TwiML example with a header that matches a sample LiveKit headers_to_attributes mapping? Sources: server-sdk-go | livekit/livekit_composite | DeepWiki | sip | livekit/livekit_composite | DeepWiki | How VICIdial handles bridging, transfers, and SIP calls | LiveKit | How to do call transfers with Five9 | LiveKit | server-sdk-ruby | livekit/livekit_composite | DeepWikirapid-honey-43838
02/12/2026, 8:02 PMtall-airline-16756
02/12/2026, 8:02 PM@) that identifies the target endpoint you want to reach. It can represent a phone number, an extension, a LiveKit room prefix, or a participant identity depending on how your trunk/dispatch rules are configured.
Examples and how they map to LiveKit
• sip:+15551234567@your-livekit-host.example.com
◦ Destination: +15551234567 — typically a PSTN phone number. LiveKit can map incoming numbers to trunk numbers or dispatch rules.
• sip:alice@your-livekit-host.example.com
◦ Destination: alice — could map to a participant identity, an extension, or a routing key your dispatch rules recognize.
• sip:room-123@your-livekit-host.example.com
◦ Destination: room-123 — often used when you want the call routed into a specific LiveKit room named room-123.
• sip:1001@your-livekit-host.example.com
◦ Destination: 1001 — an internal extension that your dispatch rule can interpret and route to a specific room or participant.
How LiveKit typically uses it
• Dispatch rules: LiveKit dispatch rules inspect the SIP URI (destination) and decide which room or participant to route the call to. For example, you might configure a rule that maps sip:+1... to an inbound trunk, or routes sip:room-* into rooms.
• Headers/attributes: If you use header-based auth, you can also pass routing info or tokens in headers — but the basic routing key is usually the destination in the SIP URI.
• JWT/API setup: JWTs are used for API actions (creating trunks, dispatch rules, participants) rather than per-call SIP digest auth. Use those API actions to define how destination strings should be interpreted.
What to choose for your setup
• If you want each incoming call to land in a specific LiveKit room, use the room name as the destination (e.g., sip:myroom@host).
• If you need simple phone-number routing, use the E.164 number (+1555...) as the destination and map that in the trunk.
• If you have an IVR or PBX-like setup, use extensions (1000, 2000, etc.) and configure dispatch rules to route those extensions.
If you share:
• One sample SIP URI you plan to use (redact secrets), or
• How you want calls routed (to a specific room, to phone numbers, or to participant identities),
I’ll give the exact SIP URI format and the LiveKit dispatch rule mapping you should use.rapid-honey-43838
02/12/2026, 8:03 PMtall-airline-16756
02/12/2026, 8:03 PMroom-123)
• A phone number in E.164 format (example: +15551234567)
• An internal extension/endpoint (example: 1001)
• A participant identity (example: alice)
Once you confirm which of those you intend as the destination, I’ll give the exact TwiML SIP URI to use and verify the dispatch rule behavior for a direct routing setup. If you also want to include header-based token validation, say so and I’ll include the header example and the matching LiveKit mapping.rapid-honey-43838
02/12/2026, 8:05 PM<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n
<Response>\n
<Dial>\n
<Sip>\n <sip:call-CA1b43268a5dda5c6fde49e2a4ff681011@persistence-stage-3bg9ne5m.sip>.livekit.cloud?X-Call-Sid=CA1b43268a5dda5c6fde49e2a4ff681011&X-Direction=inbound&X-From=%2B918005994757&X-Room-Name=call-CA1b43268a5dda5c6fde49e2a4ff681011&X-To=%2B12762219741\n </Sip>\n
</Dial>\n
</Response>tall-airline-16756
02/12/2026, 8:06 PMsips: require a valid cert for that hostname.
1. Dispatch rule alignment
◦ Confirm your LiveKit dispatch rule in “direct” mode is configured to map the incoming destination to the room name exactly (roomPrefix = "call-" or direct mapping to call-CA1b43268...).
◦ If dispatch expects a prefix but the full room name is used, ensure it still matches.
1. How LiveKit reads your query params/headers
◦ Query string params in the SIP URI are pass-through; if you need LiveKit to convert them into participant attributes, confirm your trunk’s headers_to_attributes or similar mapping is set up to capture the keys you send (X-Call-Sid, X-Room-Name, etc).
◦ Alternatively you can send them as SIP headers instead of query params if your mapping expects headers.
1. TLS / certificate
◦ If Twilio is dialing via TLS (sips:) make sure the certificate presented by persistence-stage-3bg9ne5m.sip.livekit.cloud covers that hostname and is trusted by Twilio.
1. Logs to inspect
◦ Twilio SIP trace for the call (INVITE and final response) — this will show whether the INVITE reached LiveKit and, if rejected, why (401/407/403/503).
◦ LiveKit logs showing the inbound INVITE and any rejection reason.
If you want, I can give the exact TwiML variations for:
• Sending those values as SIP headers (example) instead of query params, or
• Using sips: vs sip: depending on your TLS requirement.
Next step from you
• Share which of the checks above you’ve already verified, and paste (redact secrets) either:
◦ The Twilio SIP trace (INVITE + response), or
◦ The LiveKit inbound log for that call.
I’ll read the trace/log and point to the exact failure and the exact change to make.
Sources: How VICIdial handles bridging, transfers, and SIP calls | LiveKit | Accepting calls overview | LiveKit Documentation | Agents telephony integration | LiveKit Documentation | How to do call transfers with Five9 | LiveKit | Understanding TLS in SIP | LiveKitrapid-honey-43838
02/12/2026, 8:10 PM{
"sipDispatchRuleId": "SDR_3vv5hVkSrjBp",
"rule": {
"dispatchRuleDirect": {
"roomName": "$header.X-Room-Name"
}
},
"trunkIds": [
"ST_wehZTvDLYbiz"
],
"name": "Twilio Inbound - URI Parameters",
"metadata": "{\"call_sid\": \"$header.X-Call-Sid\", \"from\": \"$header.X-From\", \"to\": \"$header.X-To\", \"direction\": \"$header.X-Direction\", \"call_status\": \"$header.X-Call-Status\", \"from_city\": \"$header.X-From-City\", \"from_state\": \"$header.X-From-State\", \"from_country\": \"$header.X-From-Country\", \"to_city\": \"$header.X-To-City\", \"to_state\": \"$header.X-To-State\", \"to_country\": \"$header.X-To-Country\", \"source\": \"twilio_inbound\"}"
}tall-airline-16756
02/12/2026, 8:10 PMX-Room-Name as a SIP header, not as a URI query parameter. Your TwiML currently puts those values in the SIP URI query string (e.g., ?X-Room-Name=...), which will not populate $header.X-Room-Name for the dispatch rule.
What to do
• Send the routing/auth fields as SIP headers from Twilio, not only as query params.
• Keep IP allowlisting/TLS checks in place (Twilio IPs must be allowed and your cert must match if you use sips:).
Corrected TwiML example (adds headers)
<Response>
<Dial>
<Sip>
<sip:call-CA1b43268a5dda5c6fde49e2a4ff681011@persistence-stage-3bg9ne5m.sip>.livekit.cloud
<Header name="X-Call-Sid">CA1b43268a5dda5c6fde49e2a4ff681011</Header>
<Header name="X-Direction">inbound</Header>
<Header name="X-From">+918005994757</Header>
<Header name="X-Room-Name">call-CA1b43268a5dda5c6fde49e2a4ff681011</Header>
<Header name="X-To">+12762219741</Header>
</Sip>
</Dial>
</Response>
Notes and checks
• The key header your dispatch rule needs is X-Room-Name. Once Twilio includes it as a SIP header, LiveKit’s "$header.X-Room-Name" expression will resolve and the call will be routed to that room.
• If you prefer query parameters for other reasons, you must change the dispatch rule to read from URI params instead of headers. But header-based mapping is cleaner and supported by your current dispatch rule.
• Confirm Twilio can reach persistence-stage-3bg9ne5m.sip.livekit.cloud and that Twilio’s IPs are whitelisted on your LiveKit trunk. If you use TLS (sips:), ensure the certificate matches the hostname.
If you’d like, I can:
• Provide the exact Go code snippet you should generate (matching your earlier formatter), or
• Show a TwiML variation using sips: if you need TLS, or
• Review a Twilio SIP trace / LiveKit log if the call still fails after switching to headers. Which would you like next?rapid-honey-43838
02/12/2026, 8:12 PMtall-airline-16756
02/12/2026, 8:13 PM