breezy-city-58391
03/10/2026, 7:58 AMtall-airline-16756
03/10/2026, 7:58 AMtall-airline-16756
03/10/2026, 7:58 AMparticipant_attributes_changed event.
Short answer: No — there isn't a dedicated participant_attributes_changed webhook event.
Details and alternatives:
• When a participant's attributes change, the updated attributes are included in existing webhook event payloads (for example, within the participant object on lifecycle events like participant_joined or participant_left).
• For real-time in-room detection of attribute changes, use the client SDK in-room event participant_attributes_changed, which the SDKs emit immediately when attributes change.
• Webhooks are meant for server-side notifications of broader room/participant lifecycle events and include attribute data contextually, rather than emitting a separate attribute-change event.
If you want, tell me how you plan to consume attribute changes (server-only processing, syncing with a database, or reacting in real time inside clients) and I can suggest the best approach and sample payloads or implementation patterns.
Sources: Server-side | livekit/livekit_composite | DeepWikibreezy-city-58391
03/10/2026, 7:59 AMtall-airline-16756
03/10/2026, 7:59 AMparticipant_attributes_changed webhook event.
• Updated participant attributes appear inside existing webhook payloads (e.g., participant_joined, participant_left, and other lifecycle events that include a participant object).
• For immediate in-room reactions, use the client SDK in-room event participant_attributes_changed.
• For server-side needs (persisting attributes, triggering workflows), combine webhooks with a short polling or an authenticated server API call, or send attribute updates from clients to your server.
Recommended patterns
1) Real-time client behavior (in-room)
• Use the client SDK’s participant_attributes_changed event to update UI or local state immediately when attributes change.
• This is the most reliable way for in-room real-time UX (e.g., show a participant’s new role, mute status, or display name instantly).
2) Server-side processing / persistence
• Use webhooks to learn about participant lifecycle events; the participant object in those webhook payloads contains attributes.
• If you need to act on attribute changes immediately on the server (for example, trigger a workflow when an attribute flips), have clients also send attribute updates to your server whenever they change. The server can then:
◦ Validate and persist the change.
◦ Optionally call LiveKit server APIs to set attributes if the server is the authority.
• If you prefer to rely solely on webhooks, be aware attribute-only changes may not generate a dedicated webhook. Combine webhooks with an occasional check (e.g., small polling interval) or require clients to notify the server.
3) Syncing attributes to a central DB
• Best practice: make your server the canonical source of truth. When a participant updates an attribute:
a. Client sends the change to your server API.
b. Server validates and persists to DB.
c. Server calls LiveKit API to update participant attributes (if the server should own that change).
d. LiveKit SDKs and webhooks reflect the updated attributes.
• If clients can set attributes directly via SDKs, have them also POST the change to your server so the DB stays in sync.
Example payloads
• Example of a webhook lifecycle event that includes participant attributes (simplified):
{
"event": "participant_joined",
"room": "room123",
"participant": {
"sid": "Pxxxx",
"identity": "alice",
"attributes": {
"role": "presenter",
"team": "alpha"
}
}
}
• Example client SDK participant_attributes_changed event (pseudo):
room.on("participant_attributes_changed", (participant, changed) => {
// participant.attributes has the latest attributes
// changed contains keys that were updated
});
Implementation tips
• If attribute changes must trigger immediate server-side actions, require clients to send updates to your API rather than relying on webhooks alone.
• Use attribute keys and values with predictable schema (e.g., role, mutedByHost, teamId) to simplify processing.
• Include versioning or timestamps in attributes if you expect concurrent updates and need conflict resolution.
• Log webhook payloads during development so you can confirm which events include updated attributes.
Questions to tailor the recommendation
• Do you need attribute changes to trigger server-side workflows immediately, or is eventual consistency acceptable?
• Are your clients allowed to update attributes directly, or should only the server update them?
• Do you want example server-side code (Node/Python) for accepting client attribute updates and calling LiveKit server APIs?
If you tell me which of the patterns fits your use case (real-time client-only, server-authoritative, or hybrid), I’ll provide a targeted example and step-by-step code for that flow.breezy-city-58391
03/10/2026, 8:01 AMtall-airline-16756
03/10/2026, 8:01 AMsip.callStatus.
• Possible values: dialing, ringing, active, hangup, automation.
• For real-time detection, listen for participant attribute changes in-room (participant_attributes_changed in SDKs/agents).
• When a SIP participant joins, check their participant.attributes for the current sip.callStatus.
What I recommend (choose one flow depending on your needs)
• Real-time in-room updates (recommended for UIs or immediate logic): use the client SDK or agent event participant_attributes_changed and act on changes to sip.callStatus.
• Server-side monitoring / persistence: run an agent or server-side SDK that listens to participant_attributes_changed and writes status updates to your DB or triggers workflows.
• Webhook + client hybrid: webhooks do not emit a standalone participant_attributes_changed event. If you must rely on webhooks, have clients/agents also POST updates to your server whenever sip.callStatus changes.
Example patterns
1) Observe attribute changes as they happen (pseudo / Python-like)
# Register after connecting to the room
def on_participant_attributes_changed(changed_attributes, participant):
if participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP:
if 'sip.callStatus' in changed_attributes:
new_status = changed_attributes['sip.callStatus']
# handle status: update DB, notify UI, trigger workflow
print(f"SIP call status updated: {new_status}")
room.on("participant_attributes_changed", on_participant_attributes_changed)
2) Check initial status when SIP participant connects
def on_participant_connected(participant):
if participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP:
call_status = participant.attributes.get('sip.callStatus', 'Unknown')
print(f"SIP participant joined with status: {call_status}")
room.on("participant_connected", on_participant_connected)
3) Server-side flow (best for authoritative state)
• Client updates attribute or server/API sets attribute in LiveKit.
• Server agent listens to participant_attributes_changed.
• Server persists sip.callStatus to DB and triggers downstream actions (notifications, telephony integration, analytics).
Implementation considerations
• Use sip.callStatus values listed above to map to your app states (e.g., show ringing UI when ringing).
• If immediate server-side actions are required, prefer an agent/server-side SDK to avoid relying solely on webhooks.
• Log attribute change events during development to confirm exact payloads and timing.
Next step — which would you like?
• I can provide a concrete code example for a specific language (Node.js, Python, or JavaScript client).
• I can show an example DB schema and webhook/agent pattern for persisting call status.
• I can outline how to surface this status to a UI (web or mobile) in real time.
Which option fits your use case?
Sources: SIP Lifecycle Management Agent | LiveKit Documentation