Subject: Inbound SIP from Twilio — repeated `180 R...
# ask-ai
a
Subject: Inbound SIP from Twilio — repeated
180 Ringing
, never
200 OK
(intermittent) We’re bridging Twilio → LiveKit Cloud SIP for outbound utility calls. TwiML dials
sip:call-{uuid}@j5g2f3fygb2.sip.livekit.cloud
after we
CreateRoom
+
CreateAgentDispatch
for room
call-{uuid}
. Working case: Twilio SIP child completes (
200 OK
, multi‑minute call); we see the session in LiveKit → Telephony. Failing case (intermittent): Twilio shows No answer (~8s). No matching row in LiveKit Telephony for that attempt. PCAP from Twilio (failed child leg) shows: • `INVITE`to`sip:call-<uuid>@j5g2f3fygb2.sip.livekit.cloud`hits161.115.179.202:5060 • LiveKit responds`100 Processing`, then`180 Ringing`about once per second • Never
200 OK
• Twilio sends`CANCEL`; LiveKit returns`487 Request Terminated` So LiveKit’s SIP edge sees the INVITE and keeps sending
180
, but never answers before Twilio’s timeout. Dispatch rule: Callee, empty
room_prefix
, trunk
ST_…
, same project as
j5g2f3fygb2.sip.livekit.cloud
. We also pre-dispatch agent
vacancy-caller
via API (SIP rule may still attach the same agent — can duplicate if misconfigured). Ask: What should we check so inbound SIP reliably gets
200 OK
(or
183
if that’s expected) instead of endless
180
until cancel? Known issues with Callee + pre-created room + parallel
CreateAgentDispatch
, SIP dial timeout, or worker not joined causing no answer? Any recommended Twilio ↔️ LiveKit settings (timeouts, trunk headers, rule config)? Happy to share PCAP + Call-IDs /
To
tag (
SCL_…
) if useful.
t
Thanks for reaching out, Mark. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’m looking into the intermittent “180 Ringing” without a final 200 OK. I don’t yet have enough detail to pinpoint the root cause. To diagnose quickly, please share the following and I’ll correlate SIP, room, and dispatch activity: What to attach or paste • PCAP / SIP trace for the failing child leg (full INVITE, provisional responses, CANCEL, final 487). • Twilio child Call SID and timestamps for the failed attempt. • The exact Request-URI you dialed (e.g.,
sip:call-<uuid>@j5g2f3fygb2.sip.livekit.cloud
) and the Call-ID / To-tag strings from the trace. • The CreateRoom and CreateAgentDispatch request bodies (JSON). Redact any secrets. • Your SIP rule config (callee rule,
room_prefix
, trunk name). • Any LiveKit Telephony logs or Cloud Dashboard timeline entry for that attempt (if available). • Whether the expected agent/worker actually joined the LiveKit room before Twilio timed out (client/SDK connect logs). • Frequency/pattern of the failure (how often, any load/agent correlation). • Twilio SIP/trunk timeout settings you control (SIP timers, forking settings). Quick checks you can run now • Confirm the agent/client joins the room and is ready before Twilio’s dial timeout — if no participant joins, LiveKit may not send 200. • Verify the callee SIP rule maps exactly to the created room name (no prefix/typo mismatch). • Check for duplicate pre-dispatch + callee dispatch causing forked/competing attempts for the same agent. • Inspect INVITE Contact/Route/SDP to ensure LiveKit has what it needs to generate an answer (or early 183/SDP if you expect early media). • Confirm whether you expect 183 (early media) versus 200 only after an agent joins; that affects whether LiveKit should send early SDP. If you attach the PCAP plus the CreateRoom/CreateAgentDispatch JSON and the SIP rule, I’ll correlate the traces with LiveKit events and point to the likely root cause (worker not joining, misrouted rule, duplicate dispatch/forking, or required client behavior). , with interactive elements
a
Thanks — here’s everything we have so you can correlate SIP / room / dispatch. 1) PCAP / SIP trace (failing child leg) Twilio child Call SID:
CA344f7eea72bc93cd6432ac43c73d08e7
Parent Call SID:
CA9956b0fb6dea15708c05d6bd482bebd
Time (from PCAP): ~`2026-05-07 180109–180118` UTC on the capture (Twilio UI was PDT for us). Flow observed: •
INVITE <sip:call-75dbf8e3-fcd4-4142-a40f-bbeedb7447e1@j5g2f3fygb2.sip>.livekit.cloud SIP/2.0
From Twilio`54.172.60.2:5060`→LiveKit`161.115.179.202:5060` • LiveKit:`100 Processing`, then`180 Ringing` about once per second • No `200 OK`(no answered SDP) • Twilio sends`CANCEL`~8.5s after INVITE • LiveKit:`200 OK`on CANCEL,`487 Request Terminated`on the INVITE Identifiers from the trace: • Request-URI:`sip:call-75dbf8e3-fcd4-4142-a40f-bbeedb7447e1@j5g2f3fygb2.sip.livekit.cloud` • Call-ID:`40f14504c63124840678ad762ae90657@0.0.0.0` • To-tag (LiveKit):`SCL_KAikHxcJpccq` PCAP file: [attach
call-log-CA344f7eea72bc93cd6432ac43c73d08e7.pcap
] 2) CreateRoom / CreateAgentDispatch (JSON bodies — shape only, secrets redacted) We use the official REST SDK from the worker; effectively: CreateRoomRequest { "name": "call-75dbf8e3-fcd4-4142-a40f-bbeedb7447e1" } (
name
is always
call-{call_id}
where
call_id
is the UUID returned by our
/dispatch
.) CreateAgentDispatchRequest { "room": "call-75dbf8e3-fcd4-4142-a40f-bbeedb7447e1", "agent_name": "vacancy-caller", "metadata": "<JSON string: full dispatch payload with provider, addresses, business_name, tax_id, etc. — can share structure without PII on request>" } Order in code:
await create_room
→
await create_dispatch
→
twilio.calls.create
(TwiML
<Dial><Sip>sip:{room}@{TWILIO_SIP_DOMAIN}</Sip></Dial>
). No intentional delay between dispatch and Twilio dial. 3) SIP dispatch rule (Cloud UI) • Rule type:Callee • `room_prefix`:empty(so room name = SIP`To`user =
call-{uuid}
) • Trunk:`ST_ajWwFjTc8kPF`(inbound routing on the rule; name in UI: “Vacancy Inbound” or similar) • Agents on rule:`vacancy-caller`is still listed on the rule (we also`CreateAgentDispatch`the same agent from the worker —possible duplicate dispatchif that’s a problem; tell us if we should remove the agent from the SIP rule and rely only on API dispatch.) 4) LiveKit Telephony / dashboard for this attempt For this failing
call-75dbf8e3-…
window: no Telephony row showed up for us (while an earlier successful test did appear). If you can see internal SIP logs for
SCL_KAikHxcJpccq
/ that Call-ID, that’s exactly what we’re missing on our side. 5) Agent / worker joined room before Twilio timeout? We don’t currently have a single “agent joined room at T+Xs” metric in-app beyond LiveKit agent logs / Cloud timeline. Ask: should we add a short
asyncio.sleep(1–2)
between
CreateAgentDispatch
and Twilio dial as a mitigation if SIP answer waits on worker readiness? Worker runs
livekit-agents
vacancy-caller
against the same project/URL as the REST API. 6) Failure pattern Intermittent: same Twilio/LiveKit URI pattern sometimes
200 OK
for several minutes, sometimes only
180
until Twilio cancels (~8s). Not tied to prompt/voice changes on our side; SIP child PCAP is the evidence. 7) Twilio SIP / trunk timeouts We’re on standard
<Dial><Sip>
from `calls.create`; we haven’t customized SIP timers beyond Twilio defaults. If you need exact trunk / SIP profile settings, point us to what to export from Console and we’ll paste them. What we’re asking you: why would LiveKit emit repeated
180
and never
200 OK
for this INVITE pattern when room name matches
call-{uuid}
and we pre-create room + dispatch agent? Is this worker-not-ready / no answer path, dispatch-rule / duplicate-dispatch, or expected to use
183
early media in this setup? You can delete or shorten the metadata bullet if you don’t want to share payload structure in Slack; the PCAP + SIDs + Call-ID + To-tag + room/dispatch JSON are the high-signal parts.
t
Thanks — this is very helpful. I’m responding to your question: why LiveKit sends repeated
180 Ringing
and never
200 OK
for that INVITE, and what to check next. Quick diagnosis summary • The SIP INVITE reaches LiveKit and LiveKit sends provisional `100`/`180` but no final
200
before Twilio cancels. • The LiveKit Telephony dashboard shows no row for this attempt, which suggests LiveKit never completed the answer/room-join flow that creates the Telephony session. What to check next (please provide items you can) 1. Agent/worker readiness (highest likelihood) ◦ Confirm whether the
vacancy-caller
agent process actually joined the
call-75dbf8e3-…
room before Twilio timed out. If the agent hasn't joined, LiveKit may intentionally not produce a final
200 OK
. ◦ Please share agent/worker connect logs (SDK connect success, participant join events) around 2026-05-07 180109–180118 UTC. If you can’t share logs, tell me whether your worker logs show a join within ~5–8s of the Twilio INVITE. ◦ As a quick mitigation, try adding a short delay (1–2s) between
CreateAgentDispatch
and invoking Twilio dial so the agent has time to accept and join — tell me the result. 1. Dispatch vs. rule duplication ◦ You have
vacancy-caller
both on the SIP rule and created via
CreateAgentDispatch
. Duplicate dispatches can cause forking or race conditions where LiveKit routes but no single agent completes the join/answer path. ◦ Try removing the agent from the SIP rule and rely solely on API dispatch (or vice versa) for a test. Report whether the intermittent failures drop. 1. Correlate LiveKit internal SIP logs with Call-ID / To-tag ◦ You included Call-ID
40f14504c63124840678ad762ae90657@0.0.0.0
and To-tag
SCL_KAikHxcJpccq
. I need your permission to look up internal SIP logs for that Call-ID/To-tag. If you confirm, I’ll fetch the server-side SIP/telephony logs and correlate why no answer was generated. 1. SDP / early media expectations ◦ Do you expect LiveKit to send early SDP (
183
) for early media, or only
200 OK
once an agent joins? If you expect early media, check the INVITE SDP: ensure LiveKit is allowed to generate early SDP (some setups require agent-side readiness first). If you want early media, we can look at forcing
183
behavior, but confirm your expectation. 1. Twilio timer / SIP profile ◦ Twilio canceled after ~8.5s (their default). If agents occasionally take longer to join, you can increase the Twilio SIP/timeout or adjust Dial timeout to allow more time while you stabilize dispatch timing. If you want, paste your Twilio SIP profile/timeouts and I’ll advise exact values. Immediate tests I recommend • Test A: Delay dial 1–2s after CreateAgentDispatch and see if Twilio receives
200 OK
consistently. Report success/failure counts (e.g., 10 dials). • Test B: Remove agent from SIP rule (use only API dispatch) and run repeat dials to see if failure pattern changes. • Test C: Capture a successful child leg PCAP and compare timing: when did the agent join relative to INVITE and 200 OK? That will confirm whether readiness is gating the answer. If you want me to correlate server-side logs now, please confirm you want me to retrieve LiveKit logs for Call-ID
40f14504c63124840678ad762ae90657@0.0.0.0
/ To-tag
SCL_KAikHxcJpccq
and I’ll pull them and report findings. , with interactive elements
a
Thanks — answers and consent below. _Yes — please pull internal SIP / telephony logs for Call-ID
40f14504c63124840678ad762ae90657@0.0.0.0
/ To-tag
SCL_KAikHxcJpccq
at 2026-05-07 180109–180118 UTC, and any other failures from the same project (
j5g2f3fygb2
) in the past 24h that match Twilio child SIDs we can send if useful. Permission granted._ What we’re running on our side now: 1. _Test A (delay):Justshipped`WORKER_DISPATCH_DELAY_SECONDS=1.5`—a1.5s`asyncio.sleep`between`CreateAgentDispatch`and`twilio.calls.create`.Willrun~10dialsandreportsuccess/failurecounts(andafreshPCAPfromonesuccess+onefailureifany)._ 2. Test B (de-dup dispatch):We’llremove the
vacancy-caller
agent from the SIP ruleinCloudandrelyonlyonourAPI`CreateAgentDispatch`(worker-side),thenre-test.Willreportwhetherthefailurepatternchanges.
3. Test C (timing compare):WillgrabasuccessfulchildPCAPandcompareINVITE→first200OKtimingvsthefailedone. Answers to your other questions: • Worker readiness logs around 180109–180118 UTC:wedon’tcurrentlyhaveaclean“participantjoined”metricexported;we’llsurfaceitviaworkerlogsonthenextrunsandshare.Withoutthat,wecan’tyetconfirmwhethertheagentjoinedwithinTwilio’s~8sSIPtimeoutforthefailurewindow. • Early media / 183 vs 200:wedo not expect early media.Weexpect`200 OK` only after the agent joinstheroom.IfLiveKitneedsustooptinto`183`we’dratheravoidit;letusknowifoursetupforcesearlymediaforanyreason. • Twilio SIP / dial timeouts:stock—weuse`twilio.calls.create(twiml=<Dial answerOnBridge="true"><Sip>sip:call-{uuid}@j5g2f3fygb2.sip.livekit.cloud</Sip></Dial>)`withnocustomSIPtimers.Happytobump`<Dial timeout="...">`ifyourecommendavaluewhilewestabilizedispatchtiming. • _Dispatch order in code:`await create_room`→`await create_dispatch(agent_name="vacancy-caller", metadata=<JSON>)`→(now`sleep 1.5s`)→`twilio.calls.create(...)`._ • _SIP rule in Cloud:Callee,
room_prefix
= empty,trunk`ST_ajWwFjTc8kPF`,agent`vacancy-caller`currentlyattached(willremoveforTestB)._ Will report back with: dial counts for A, dial counts for B, and any new PCAP + Call-IDs if failures persist.
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!