IceLive Socket API
Connect to the `/socket` namespace with a Socket.IO client, passing the access token in the connection `auth` payload: `{ "token": "" }`. On success the server emits `authenticated`; an invalid token rejects the connection. Every connected user is auto-joined to a personal room (`user_{id}`) and, after `join_live`, to the live room (`live_{id}`).
Client → Server (22)
SENDaccept_live_inviteInvitee accepts their pending invite; they may then join directly.
| Field | Type |
|---|
live_id required | integer |
SENDaccept_live_join_requestActive host approves a pending request; the requester may then join.
| Field | Type |
|---|
live_id required | integer |
user_id required | integer |
SENDcall_acceptAnswer a ringing call. Acks the callee with their token; the caller gets ``call_accepted``.
| Field | Type |
|---|
call_id required | integer |
SENDcall_cancelCaller hangs up before it connects; the callee gets ``call_cancelled``.
| Field | Type |
|---|
call_id required | integer |
SENDcall_endEither party ends the call; the other party gets ``call_ended``.
| Field | Type |
|---|
call_id required | integer |
SENDcall_initiateRing a user. Acks the caller with their token; the callee gets ``incoming_call``.
| Field | Type |
|---|
callee_id required | integer |
call_type | #/$defs/CallType |
SENDcall_rejectDecline a ringing call; the caller gets ``call_rejected``.
| Field | Type |
|---|
call_id required | integer |
SENDdecline_live_inviteInvitee declines their pending invite.
| Field | Type |
|---|
live_id required | integer |
SENDdelete_messageDelete the caller's own message; the thread gets ``message_deleted``.
| Field | Type |
|---|
message_id required | integer |
SENDhost_leftClient leaves (or host steps out). The room learns whether the host left so the client can react (e.g. show 'host will be right back').
| Field | Type |
|---|
live_id required | integer |
SENDinvite_to_liveA member invites another user into a private room. Acks the inviter and notifies the invitee in real time.
| Field | Type |
|---|
live_id required | integer |
user_id required | integer |
SENDjoin_liveClient joins a room; gets a private ack with a scoped LiveKit token, and everyone already in the room is told a new participant arrived.
| Field | Type |
|---|
live_id required | integer |
SENDkick_userActive host removes a participant and blocks their rejoin.
| Field | Type |
|---|
live_id required | integer |
user_id required | integer |
SENDleave_liveClient leaves (or host steps out). The room learns whether the host left so the client can react (e.g. show 'host will be right back').
| Field | Type |
|---|
live_id required | integer |
SENDlive_room_endActive host ends the room for everyone.
| Field | Type |
|---|
live_id required | integer |
SENDmark_readMark a conversation read; the other members get ``message_read``.
| Field | Type |
|---|
conversation_id required | integer |
SENDreject_live_join_requestActive host rejects a pending request.
| Field | Type |
|---|
live_id required | integer |
user_id required | integer |
SENDrequest_join_liveViewer asks to join a public room. Acks the requester and notifies the active host.
| Field | Type |
|---|
live_id required | integer |
SENDsend_messageSend a DM to a conversation or straight to a user; the sender gets a ``message_sent`` ack and every other member gets ``new_message``.
| Field | Type |
|---|
conversation_id | integer|null |
recipient_id | integer|null |
body required | string |
SENDset_active_hostActive host hands the role to another active participant.
| Field | Type |
|---|
live_id required | integer |
user_id required | integer |
SENDtypingFan out a transient typing indicator to the other members (never persisted — the socket is its only home).
| Field | Type |
|---|
conversation_id required | integer |
is_typing | boolean |
SENDupdate_media_stateFan out transient device state (mic/camera/facing/network). These are deliberately never persisted — the socket is their only home.
| Field | Type |
|---|
live_id required | integer |
mic_enabled | boolean|null |
camera_enabled | boolean|null |
camera_facing | string|null |
network_quality | string|null |
Server → Client (38)
RECEIVEaccepted_live_join_requestAck to the host after approving a request.
{
"live_id": "<uuid>",
"accepted_user_id": "<uuid>"
}RECEIVEactive_host_setHostship transferred; sent to the room.
{
"live_id": "<uuid>",
"active_host_id": "<uuid>",
"active_host": {
"id": "<uuid>",
"display_name": "Bob"
}
}RECEIVEauthenticatedConnection accepted (sent only to the connecting client).
{
"user_id": "<uuid>",
"message": "Authentication successful."
}RECEIVEcall_acceptedSent to the caller when the callee answers.
{
"call_id": "<uuid>",
"callee": {
"id": "<uuid>",
"display_name": "Bob"
}
}RECEIVEcall_cancelledSent to the callee when the caller hangs up before connecting.
RECEIVEcall_connectedPrivate ack to the callee with their LiveKit token on accept.
{
"call": {
"id": "<uuid>",
"status": "ongoing"
},
"token": "<livekit-jwt>",
"livekit_url": "ws://localhost:7880"
}RECEIVEcall_endedSent to the other party when a connected call ends.
RECEIVEcall_rejectedSent to the caller when the callee declines.
RECEIVEcall_ringingPrivate ack to the caller with their LiveKit token while the callee is rung.
{
"call": {
"id": "<uuid>",
"status": "ringing"
},
"token": "<livekit-jwt>",
"livekit_url": "ws://localhost:7880"
}RECEIVEerrorAn error for the caller (bad payload, unknown event, permission denied, …).
{
"message": "Only the active host can manage this stream"
}RECEIVEgift_receivedA gift was sent to the room's host; fanned out to everyone in the room so clients can play the animation.
{
"live_id": "<uuid>",
"gift": {
"id": "<uuid>",
"code": "rose",
"name": "Rose",
"asset_url": "https://cdn/\u2026/rose.svga",
"effect": "hearts"
},
"quantity": 2,
"total_price": 200,
"sender": {
"id": "<uuid>",
"display_name": "Ada"
},
"recipient_id": "<uuid>"
}RECEIVEhost_left_liveThe active host stepped out; sent to the room.
{
"left_user": "<uuid>",
"host_left": true
}RECEIVEincoming_callSent to the callee: someone is calling. No token yet — the callee accepts to receive one.
{
"call": {
"id": "<uuid>",
"caller_id": "<uuid>",
"callee_id": "<uuid>",
"call_type": "audio",
"status": "ringing"
},
"caller": {
"id": "<uuid>",
"display_name": "Ada"
}
}RECEIVEjoin_live_request_sentAck to the requester that their join request was sent.
RECEIVEjoined_livePrivate ack to the joiner carrying the scoped LiveKit token.
{
"stream": {
"id": "<uuid>",
"room_name": "live-\u2026",
"status": "live"
},
"token": "<livekit-jwt>",
"livekit_url": "ws://localhost:7880",
"identity": "<uuid>"
}RECEIVEkicked_successfullyAck to the host after kicking a user.
{
"live_id": "<uuid>",
"kicked_user_id": "<uuid>"
}RECEIVElive_endedThe room was ended by its active host; sent to the room.
{
"live_ended": true,
"live_id": "<uuid>"
}RECEIVElive_invite_acceptedSent to the inviter when the invitee accepts.
{
"live_id": "<uuid>",
"invitee_id": "<uuid>"
}RECEIVElive_invite_declinedSent to the inviter when the invitee declines.
{
"live_id": "<uuid>",
"invitee_id": "<uuid>"
}RECEIVElive_invite_receivedSent to the invitee: a member invited you into a private room. Accept, then join.
{
"live_id": "<uuid>",
"inviter": {
"id": "<uuid>"
}
}RECEIVElive_invite_sentAck to the inviter after inviting someone to a private room.
{
"live_id": "<uuid>",
"invitee_id": "<uuid>"
}RECEIVElive_join_request_receivedSent to the active host with the requester's profile.
{
"live_id": "<uuid>",
"requester": {
"id": "<uuid>",
"display_name": "Ada"
}
}RECEIVElive_startedA followed host went live; sent to each of their followers' personal rooms (FR-NOTIF-01).
{
"live_id": "<uuid>",
"room_name": "live-\u2026",
"category": "video",
"host": {
"id": "<uuid>",
"display_name": "Ada"
}
}RECEIVEmedia_state_changedA participant's transient device state (never persisted); fanned out to the room except the sender.
{
"live_id": "<uuid>",
"user_id": "<uuid>",
"mic_enabled": false,
"camera_enabled": true,
"camera_facing": "front",
"network_quality": "good"
}RECEIVEmessage_deletedA message was deleted; sent to the thread (and as the deleter's ack).
{
"conversation_id": "<uuid>",
"message_id": "<uuid>"
}RECEIVEmessage_readA member read the thread; sent to the other members.
{
"conversation_id": "<uuid>",
"reader_id": "<uuid>",
"read_at": "<iso-8601>"
}RECEIVEmessage_sentPrivate ack to the sender with the persisted message.
{
"id": "<uuid>",
"conversation_id": "<uuid>",
"sender_id": "<uuid>",
"body": "hey!",
"is_deleted": false,
"created_at": "<iso-8601>"
}RECEIVEnew_messageA new message; sent to every conversation member except the sender.
{
"id": "<uuid>",
"conversation_id": "<uuid>",
"sender_id": "<uuid>",
"body": "hey!",
"is_deleted": false,
"created_at": "<iso-8601>"
}RECEIVErejected_live_join_requestAck to the host after rejecting a request.
{
"live_id": "<uuid>",
"rejected_user_id": "<uuid>"
}RECEIVErequest_join_live_acceptedSent to the requester when the host approves.
{
"live_id": "<uuid>",
"accepted_by": "<uuid>"
}RECEIVErequest_join_live_rejectedSent to the requester when the host rejects.
{
"live_id": "<uuid>",
"rejected_by": "<uuid>"
}RECEIVErole_changedA user's org role changed (agent/host granted, detached or inserted); fanned to everyone so apps re-render.
{
"user_id": "<uuid>",
"role": "host"
}RECEIVEuser_joined_liveA participant joined; sent to the room (except the joiner). Payload is the public user profile plus `live_id`.
{
"id": "<uuid>",
"display_name": "Ada",
"role": "user",
"is_online": true,
"live_id": "<uuid>"
}RECEIVEuser_left_liveA non-host participant left; sent to the room.
{
"left_user": "<uuid>",
"host_left": false
}RECEIVEuser_offlineBroadcast to everyone when a user's last socket drops.
RECEIVEuser_onlineBroadcast to everyone when a user connects.
RECEIVEuser_typingTransient typing indicator (never persisted); sent to the other members.
{
"conversation_id": "<uuid>",
"user_id": "<uuid>",
"is_typing": true
}RECEIVEyou_kickedSent to a user when the host removes them from the room.
{
"live_id": "<uuid>",
"kicked_by": "<uuid>"
}