How to subscribe to the sip events, for e.g. ```{...
# ask-ai
c
How to subscribe to the sip events, for e.g.
Copy code
{
callId: "SCL_WTVHGtLraBdo"
trunkId: "ST_DroyyWjoNud4"
region: "ofrankfurt1b"
roomName: "outbound_+918754442384_1771515011"
participantIdentity: "+918754442384"
participantAttributes: {
sip.callID: "SCL_WTVHGtLraBdo"
sip.callIDFull: "cafz6WATWso2QDGDjABYw02FqyL"
sip.callStatus: "dialing"
sip.phoneNumber: "+918754442384"
sip.trunkID: "ST_DroyyWjoNud4"
sip.trunkPhoneNumber: "+918049280469"
}
fromUri: {
user: "+918049280469"
host: "3poatuj2q0u.sip.livekit.cloud"
ip: "161.115.161.126"
port: 9000
}
toUri: {
user: "+918754442384"
host: "<http://073cf509.sip.vobiz.ai|073cf509.sip.vobiz.ai>"
port: 5060
transport: "SIP_TRANSPORT_UDP"
}
callDirection: "SCD_OUTBOUND"
callStatus: "SCS_ERROR"
createdAtNs: "1771515014608801622"
endedAtNs: "1771515060175756742"
error: "INVITE failed: sip status: 486: Busy Here"
callStatusCode: {
code: "SIP_STATUS_BUSY_HERE"
status: "Busy Here"
}
}
t
Thanks for reaching out, Subham. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — you're asking how to subscribe to SIP events like the example you shared (callId, callStatus, sip.* attributes). I’ll explain what you can and can’t subscribe to, and the recommended ways to receive the SIP lifecycle updates you need. Short answer • You cannot subscribe to raw SIP signaling messages (INVITE, 486 Busy Here, full SIP dumps). That low-level SIP traffic is internal to LiveKit’s SFU. • You can reliably receive SIP lifecycle and status information via: ◦ Webhooks for join/leave/room lifecycle events, and ◦ Participant attribute updates (e.g.,
sip.callStatus
,
sip.callID
) via client/agent event listeners or by polling the server SDK (list participants). How to get the SIP events you care about 1) Webhooks — for call start / end and room lifecycle • Configure a webhook URL for your LiveKit project or deployment. LiveKit sends events like
participant_joined
,
participant_left
,
room_started
, and
room_finished
. • Use
participant_joined
and
participant_left
to detect when a SIP caller enters or leaves a room. • Webhooks include participant attributes so you’ll get
sip.*
attributes available on the participant payload. • Verify webhook signatures (HMAC-SHA256) before processing. When to use: Good for asynchronous notifications (e.g., logging, ticketing, billing, or triggering backend workflows when SIP calls connect/disconnect). 2) Participant attributes / event listeners — for real-time status changes • The
Participant
object exposes attributes such as
sip.callStatus
,
sip.phoneNumber
,
sip.callID
, etc. • Listen for attribute-change events in your LiveKit client or agent. Example events are
participant_attributes_changed
(or SDK-equivalent). • Typical flow:
dialing
→
ringing
→
active
→
hangup
(or
error
). Your handler can read
changed_attributes['sip.callStatus']
and react immediately. When to use: Real-time UI updates, call-state driven logic, or routing decisions while the call is in progress. 3) Server SDK snapshot (read-only) • Use the server SDK
ListParticipants
/
Room
API to read current participants and their attributes. This provides a snapshot of SIP state (e.g.,
sip.callID
,
sip.callStatus
) at query time. • Use this when you need to poll for current state or perform server-side reconciliation. When to use: Periodic checks, administrative dashboards, or if you missed a webhook and need current state. What you cannot get • Raw SIP message streams (INVITE, BYE, status lines, SIP-level debugging messages) are not exposed as a subscription. You will not receive SIP protocol dumps or the internal INVITE failure trace directly. • Instead, you get the resulting state (e.g.,
callStatus: "SCS_ERROR"
and participant left events). Extra: passing data back to the SIP side • If you need to provide data back to the SIP trunk/IVR (for example to include in a BYE), map participant attributes to SIP headers via
attributes_to_headers
on trunk config and set attributes with
update_participant
. Those mapped headers are sent on BYE or other trunk interactions. Example flows (high level) • To detect an outbound call error (like your example with "486 Busy Here"): a. Receive
participant_joined
for the SIP participant (or
participant_attributes_changed
). b. Watch
sip.callStatus
attribute changes; when it becomes an error state or you receive
participant_left
, record the error reason from attributes (e.g.,
sip.callStatus
/
callStatusCode
fields). c. Optionally fetch room participants via the server SDK if you need a snapshot. If you’d like, I can help with: • Example webhook payload and a small webhook handler in the language you prefer. • Example client/agent code to listen for
participant_attributes_changed
in the SDK you use (Web, Node, Python, Ruby, etc.). • How to map
attributes_to_headers
for your trunk so IVR receives routing attributes on BYE. Which would you like next, and which SDK/language are you using? Sources: server-sdk-ruby | livekit/livekit_composite | DeepWiki | SIP Lifecycle Management Agent | LiveKit Documentation | sip | livekit/livekit_composite | DeepWiki | How to do call transfers with Five9 | LiveKit | server-sdk-kotlin | livekit/livekit_composite | DeepWiki