Events Reference
All events are for the session bound to the current connection. Events are JSON objects with an event field (string) and a data field (object).
dtmf
DTMF digit detected from a remote endpoint.
{"event":"dtmf","data":{"endpoint_id":"...","digit":"5","duration_ms":160}}endpoint.state_changed
Endpoint state transition. States: new, buffering, connecting, connected, playing, paused, disconnected, finished.
{"event":"endpoint.state_changed","data":{"endpoint_id":"...","old_state":"connecting","new_state":"connected"}}endpoint.file.finished
File playback completed or errored.
{"event":"endpoint.file.finished","data":{"endpoint_id":"...","reason":"completed","error":null}}endpoint.media_timeout
No RTP packets received from a remote endpoint for 5 seconds. This threshold defaults to 5 seconds and can be configured via media_timeout_secs. The event is factual — it could mean the remote is silent, or there's a network issue. The event fires once per timeout period and resets when packets resume.
{"event":"endpoint.media_timeout","data":{"endpoint_id":"...","duration_ms":5000}}endpoint.rtcp_bye
RTCP BYE packet received from a remote endpoint, indicating graceful departure. This is informational — the endpoint remains in its current state. The application should decide whether to tear down the endpoint.
{"event":"endpoint.rtcp_bye","data":{"endpoint_id":"...","ssrc_list":[12345],"reason":"User hung up"}}Note:
reasonmay benullif the BYE packet contains no reason string.
endpoint.transferred_out
Emitted on the source session when an endpoint is transferred to another session.
{"event":"endpoint.transferred_out","data":{"endpoint_id":"...","target_session_id":"..."}}endpoint.transferred_in
Emitted on the target session when an endpoint is transferred in from another session.
{"event":"endpoint.transferred_in","data":{"endpoint_id":"...","source_session_id":"...","endpoint_type":"rtp","direction":"sendrecv","state":"connected"}}recording.stopped
Recording was stopped externally (not by recording.stop).
{"event":"recording.stopped","data":{"recording_id":"...","file_path":"...","duration_ms":30000,"packets":1500,"dropped_packets":0,"reason":"..."}}session.idle_timeout
Session was automatically destroyed because no activity (media packets or commands) occurred for the configured session_idle_timeout_secs period. This is a critical event — it is delivered with priority over normal events.
{"event":"session.idle_timeout","data":{"session_id":"550e8400-...","idle_timeout_secs":300}}session.empty_timeout
Session was auto-destroyed because it had zero endpoints for the configured empty_session_timeout_secs duration. This is a critical event.
{"event":"session.empty_timeout","data":{"session_id":"...","empty_timeout_secs":30}}session.orphaned
Control connection dropped. The session remains alive for the configured disconnect_timeout_secs. This event is delivered on a best-effort basis — if the WebSocket is already in the closing handshake or the TCP connection has dropped, the event may not reach the client. Use session.attach on a new connection to reclaim the session before the timeout expires.
{"event":"session.orphaned","data":{"timeout_remaining_ms":30000}}events.dropped
Fired when events were dropped due to client backpressure. The server uses a bounded event channel; when a slow client can't keep up, excess events are dropped and this notification is sent with the count of lost events.
{"event":"events.dropped","data":{"count":5}}Recovery: When events are dropped, the client may have missed state transitions (endpoint state changes, recording stops). Poll
session.infoon the same connection to reconcile any missed state.
stats
Periodic session statistics (see Statistics).
vad.speech_started
Speech detected after silence.
{"event":"vad.speech_started","data":{"endpoint_id":"..."}}vad.silence
Periodic silence notification.
{"event":"vad.silence","data":{"endpoint_id":"...","silence_duration_ms":3000}}