Room events

Track room lifecycle, membership, and playback.
View as Markdown

Room events cover room lifecycle, member management, and playback control within rooms.

Ordering note: Room lifecycle events (room.created, command.room.delete.accepted, room.deleted) and room playback events are not associated with a session_uuid. They have no ordering guarantee relative to session-scoped events.

Envelope: Like every webhook, each room event also carries a timestamp field (emission time as an RFC 3339 / ISO 8601 UTC string, e.g. "2026-06-28T14:30:00.000Z") in addition to the fields listed below. Treat it as event-time metadata, not as a guaranteed total-order key; room events do not have the per-session delivery-order guarantee. Delivery requests carry W3C trace context in headers. The example payloads omit these envelope fields for brevity.

room.created

Fired when a new room is created via POST /api/v1/rooms.

FieldTypeDescription
eventstringAlways "room.created". Required
app_uuidstringGateway-minted identifier (app_<uuid-v4>) of the application that owns the room. Required
room_idstringUnique room identifier. Required
1{
2 "event": "room.created",
3 "app_uuid": "app_3f9c0b2a-7d41-4e8b-9f12-2a6c5d0e7b34",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000"
5}

command.room.delete.accepted

Fired immediately when a room delete is requested via DELETE /api/v1/rooms/{room_id}. The delete endpoint returns 202 Accepted with body {"room_id": "...", "status": "deleting"}, acknowledging the request before teardown completes. A later room.deleted event confirms the room has actually been torn down.

FieldTypeDescription
eventstringAlways "command.room.delete.accepted". Required
room_idstringUnique room identifier. Required
1{
2 "event": "command.room.delete.accepted",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000"
4}

room.deleted

Fired when a room has been torn down following a delete request. It is emitted on confirmation that the room is gone (reason: "closed"), or after a timeout if confirmation never arrives (reason: "timeout"). The reason field is always present and is one of these two values.

FieldTypeDescription
eventstringAlways "room.deleted". Required
app_uuidstringGateway-minted identifier (app_<uuid-v4>) of the application that owned the room. Required
room_idstringUnique room identifier. Required
reasonstringWhy the room was torn down. One of "closed" (normal confirmed teardown) or "timeout" (the room was reaped after teardown confirmation never arrived). Always present. Required
1{
2 "event": "room.deleted",
3 "app_uuid": "app_3f9c0b2a-7d41-4e8b-9f12-2a6c5d0e7b34",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
5 "reason": "closed"
6}

room.member.joined

Fired when a call joins a room. This event confirms the member has actually joined. The join is asynchronous: POST /api/v1/rooms/{room_id}/members returns 202 Accepted with status "joining" only as an acknowledgment that the request was accepted, while room.member.joined fires later, once the underlying system confirms the member is in the room.

FieldTypeDescription
eventstringAlways "room.member.joined". Required
session_uuidstringSession UUID of the joining member. Required
room_idstringRoom identifier. Required

Room membership is identified by session_uuid; the caller number is available on the inbound call.created or outbound command.call.dial.accepted webhook for that session.

1{
2 "event": "room.member.joined",
3 "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000"
5}

room.member.left

Fired when a call leaves a room, whether by DELETE /api/v1/rooms/{room_id}/members/{uuid}, being kicked, or hanging up.

FieldTypeDescription
eventstringAlways "room.member.left". Required
session_uuidstringSession UUID of the departing member. Required
room_idstringRoom identifier. Required
reasonstringDeparture trigger. One of: "hangup" (member’s channel hung up), "removed" (explicit leave/kick via the room leave endpoint), "orphan" (the gateway detected that the member’s call had already gone away — typically a crash or dropped connection — and removed the now-stale membership; treat this as an abnormal disconnect, not a clean leave). Consumers should accept any string here for forward compatibility. Required

Room membership is identified by session_uuid; the caller number is available on the inbound call.created or outbound command.call.dial.accepted webhook for that session.

1{
2 "event": "room.member.left",
3 "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
5 "reason": "hangup"
6}

room.member.muted

Fired when a room member is muted via the room/mute command.

FieldTypeDescription
eventstringAlways "room.member.muted". Required
session_uuidstringSession UUID of the muted member. Required
room_idstringRoom identifier. Required

Room membership is identified by session_uuid; the caller number is available on the inbound call.created or outbound command.call.dial.accepted webhook for that session.

1{
2 "event": "room.member.muted",
3 "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000"
5}

room.member.unmuted

Fired when a room member is unmuted via the room/unmute command.

FieldTypeDescription
eventstringAlways "room.member.unmuted". Required
session_uuidstringSession UUID of the unmuted member. Required
room_idstringRoom identifier. Required

Room membership is identified by session_uuid; the caller number is available on the inbound call.created or outbound command.call.dial.accepted webhook for that session.

1{
2 "event": "room.member.unmuted",
3 "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000"
5}

room.member.voice_activity_changed

Fired each time a room member’s voice activity detection (VAD) state changes. talking: true marks speech onset; talking: false marks the return to silence. Expect a high-frequency stream during an active conversation and debounce events on your side.

VAD state is delivered via this webhook. The member object returned by GET /api/v1/rooms/{room_id}/members/{uuid} contains only {uuid, muted}.

FieldTypeDescription
eventstringAlways "room.member.voice_activity_changed". Required
session_uuidstringSession UUID of the member whose VAD state changed. Required
room_idstringRoom identifier. Required
talkingbooleantrue when the member started talking, false when they stopped. Required

Room membership is identified by session_uuid; the caller number is available on the inbound call.created or outbound command.call.dial.accepted webhook for that session.

1{
2 "event": "room.member.voice_activity_changed",
3 "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
5 "talking": true
6}

command.room.member.volume.accepted

Fired immediately when a member’s volume is changed via the room/volume command. This is a per-member session command, distinct from the room-level command.room.playback.volume.accepted event.

FieldTypeDescription
eventstringAlways "command.room.member.volume.accepted". Required
session_uuidstringSession UUID of the member whose volume changed. Required
room_idstringRoom identifier. Required
volumeintegerNew member volume on the 19 scale (5 = normal, 1 = quietest, 9 = loudest). 1 is not silence; use mute to silence a member. Required
directionstringWhich side of the member’s audio was adjusted. "out" means how loudly the member hears the room, "in" means how loudly the room hears the member, and "both" applies to both sides. Required

Room membership is identified by session_uuid; the caller number is available on the inbound call.created or outbound command.call.dial.accepted webhook for that session.

1{
2 "event": "command.room.member.volume.accepted",
3 "session_uuid": "acW68-f47ac10b-58cc-4372-a567-0e02b2c3d479",
4 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
5 "volume": 7,
6 "direction": "out"
7}

command.room.playback.start.accepted

Fired immediately after room playback is dispatched via POST /api/v1/rooms/{room_id}/playback/play. This event acknowledges dispatch; it does not prove that audio began. If start is not confirmed within the validation window, a later room.playback.failed event reports error: "playback_timeout".

FieldTypeDescription
eventstringAlways "command.room.playback.start.accepted". Required
room_idstringRoom identifier. Required
urlsstring[]Array of audio URLs being played. Required
operation_uuidstringUnique operation identifier. Required
1{
2 "event": "command.room.playback.start.accepted",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
4 "urls": ["https://cdn.example.com/audio/announcement.wav"],
5 "operation_uuid": "d4e5f6a7-b8c9-4123-8567-89abcdef0123"
6}

command.room.playback.pause.accepted

Fired when the room playback pause toggle is accepted and the pause command is dispatched. The gateway reads the room’s prior playback_status before toggling: if it was "playing", this event fires; if it was "paused", command.room.playback.resume.accepted fires instead. Neither event independently confirms the resulting media-layer state.

FieldTypeDescription
eventstringAlways "command.room.playback.pause.accepted". Required
room_idstringRoom identifier. Required
operation_uuidstringUnique operation identifier. Required
1{
2 "event": "command.room.playback.pause.accepted",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
4 "operation_uuid": "d4e5f6a7-b8c9-4123-8567-89abcdef0123"
5}

command.room.playback.resume.accepted

Fired when the room playback pause toggle is accepted and a resume command is dispatched while the prior playback_status was "paused". The same endpoint emits either command.room.playback.pause.accepted or this event depending on prior state; it does not independently confirm the resulting media-layer state.

FieldTypeDescription
eventstringAlways "command.room.playback.resume.accepted". Required
room_idstringRoom identifier. Required
operation_uuidstringUnique operation identifier. Required
1{
2 "event": "command.room.playback.resume.accepted",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
4 "operation_uuid": "e5f6a7b8-c9d0-4234-9678-9abcdef01234"
5}

command.room.playback.stop.accepted

Fired when a room playback stop command is accepted and dispatched. It does not independently confirm that the media layer has stopped. Its operation_uuid identifies the stop request; the resulting room.playback.ended event retains the operation UUID of the original play request.

FieldTypeDescription
eventstringAlways "command.room.playback.stop.accepted". Required
room_idstringRoom identifier. Required
operation_uuidstringUnique operation identifier. Required
1{
2 "event": "command.room.playback.stop.accepted",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
4 "operation_uuid": "d4e5f6a7-b8c9-4123-8567-89abcdef0123"
5}

command.room.playback.volume.accepted

Fired when a room playback volume-change command is accepted and dispatched. The volume field is the requested target; the event does not independently confirm that the media layer applied it.

FieldTypeDescription
eventstringAlways "command.room.playback.volume.accepted". Required
room_idstringRoom identifier. Required
volumeintegerNew room playback volume on an absolute 0200 scale, where 100 is the baseline (unity) level — the file played at its original loudness — 0 is muted, and values above 100 boost up to a maximum of 200. The value is the target level, not a relative change. Required
operation_uuidstringUnique operation identifier. Required
1{
2 "event": "command.room.playback.volume.accepted",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
4 "volume": 120,
5 "operation_uuid": "d4e5f6a7-b8c9-4123-8567-89abcdef0123"
6}

room.playback.ended

Terminal event fired exactly once when room playback completes naturally or is stopped through the API. A multi-source playlist emits one event after every source completes, rather than one event per source. Playback failures and start-confirmation timeouts emit room.playback.failed instead.

FieldTypeDescription
eventstringAlways "room.playback.ended". Required
room_idstringRoom identifier. Required
operation_uuidstringOperation identifier of the originating command.room.playback.start.accepted request. An API stop does not replace it with the stop command’s operation UUID. Required
urlsstring[]The complete original urls playlist from the room playback request, in request order. Required
reasonstringWhy playback ended: "completed" when every source finished naturally, or "stopped" when interrupted through the API. Required
1{
2 "event": "room.playback.ended",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
4 "operation_uuid": "d4e5f6a7-b8c9-4123-8567-89abcdef0123",
5 "urls": ["https://cdn.example.com/audio/announcement.wav"],
6 "reason": "completed"
7}

room.playback.failed

Fired when room playback fails: either the platform reports a playback failure, any source in a multi-source playlist fails, or the gateway does not receive confirmation within 10 seconds that a dispatched play actually started. A failure of any source fails the whole operation. A playback that is confirmed within that window does not fail merely because it runs for more than 10 seconds. The event resets playback_status to "stopped" so the room can accept a new play.

FieldTypeDescription
eventstringAlways "room.playback.failed". Required
room_idstringRoom identifier. Required
operation_uuidstringOperation identifier of the originating command.room.playback.start.accepted request. May be empty if state was cleared before this event fired. Required
urlsstring[]The complete original urls playlist from the room playback request, in request order. Required
errorstringCoarse-grained error bucket. One of "playback_error" (the platform reported a playback failure) or "playback_timeout" (the gateway’s playback watchdog timed out; normally because start was not confirmed within 10 seconds). Required
1{
2 "event": "room.playback.failed",
3 "room_id": "acW68-room-550e8400-e29b-41d4-a716-446655440000",
4 "operation_uuid": "d4e5f6a7-b8c9-4123-8567-89abcdef0123",
5 "urls": ["https://cdn.example.com/audio/announcement.wav"],
6 "error": "playback_timeout"
7}

Triggered by

These events are produced by the following endpoints: