WebSocket Realtime

Real-time presentation control, room management, and collaboration API

WebSocket Realtime API

Connect to wss://cliqer.io/ws for realtime presentation control and collaboration.

Auth: browsers authenticate automatically via the session_token session cookie sent on the upgrade request. Non-browser clients may pass the same session token as a ?token= query parameter or an Authorization: Bearer header. Connecting without a token is allowed, you join as a guest (you can view and join rooms but cannot become a host).

Connection

# WebSocket connections require a WebSocket client
# Using websocat for testing:
websocat "$WS_URL/ws?token=YOUR_ACCESS_TOKEN"

Room Management

Create Room

Create a new presentation room as host.

# Send via WebSocket connection
echo '{"type":"createRoom"}' | websocat "$WS_URL/ws?token=TOKEN"

Response:

{
  "type": "roomCreated",
  "payload": {
    "roomId": "ABC123",
    "socketId": "client_550e8400",
    "isPrimary": true
  }
}

Join Room

Join an existing presentation room.

echo '{"type":"joinRoom","payload":{"room":"ABC123","presenterName":"John","joinAsHost":false}}' | websocat "$WS_URL/ws?token=TOKEN"

Response:

{
  "type": "joinedRoom",
  "payload": {
    "id": "client_550e8400",
    "hosts": ["host_abc123"],
    "needsRefresh": false
  }
}

Connection & Room Flow

Slide Navigation

Control slide navigation in real-time.

EventDescriptionPayload
webActionNavigate slides{ action: 'next' | 'prev' | 'goto', slide?: number }
clicksEnabledToggle click control for one client (host only)Send { to: string, enabled: boolean }. Rebroadcast to the target as a bare boolean payload, not an object
countdownTimer control{ type: 'start' | 'stop', time: number }
presenterMouseLaser pointer{ mouse: { x: number, y: number }, color?: string }
needsRefreshRequest refresh{ forId: string }
refreshRoomRoll room to a new link (host only)(no payload, server assigns a new room id)
# Next slide
echo '{"type":"webAction","payload":{"action":"next"}}' | websocat "wss://..."
# Previous slide
echo '{"type":"webAction","payload":{"action":"prev"}}' | websocat "wss://..."
# Go to slide 5
echo '{"type":"webAction","payload":{"action":"goto","slide":5}}' | websocat "wss://..."

Messaging

Send messages between hosts and clients.

# Message to hosts (from client)
echo '{"type":"messageToHosts","payload":{"text":"Question about slide 3"}}' | websocat "wss://..."
# Message to clients (from host)
echo '{"type":"messageToClients","payload":{"text":"Welcome everyone!"}}' | websocat "wss://..."

Incoming Message Format:

{
  "type": "messageFromHost",
  "payload": {
    "fromClientId": "host_abc123",
    "fromPresenterName": "Host",
    "originalPayload": { "text": "Welcome everyone!" }
  }
}

Event Reference

Outgoing Events (Client → Server)

EventDescription
createRoomCreate a new room
joinRoomJoin existing room
webActionSlide navigation
clicksEnabledToggle click control
countdownTimer control
presenterMouseLaser pointer position
messageToHostsSend message to hosts
messageToClientsSend message to clients (host only)
needsRefreshRequest refresh for specific client
refreshRoomRoll the host onto a brand-new room id (host only); the existing audience stays in the old room
closeStreamStop one client's screen share (host only); requires a to target and is a no-op without one
logoutLeave the room and release the host's licence seat; the socket itself stays open

Incoming Events (Server → Client)

EventDescription
connectedSent on open with { clientId, userId, isAuthenticated }
roomCreatedRoom creation confirmed
joinedRoomSuccessfully joined room
clientJoinedNew client joined room
clientLeftA client left the room
webActionSlide navigation event
clicksEnabledClick control toggled
countdownTimer event
presenterMouseLaser pointer position
messageFromHostMessage from host
messageFromClientMessage from client
needsRefreshHost requested this client refresh
refreshRoomResultResult of a refreshRoom, carries the new room id (sent to the requesting host, followed by hostInfo)
logoutDisconnection notice
errorError message