This organisation’s live socket
const url = 'https://api.sloose.com/orgs/org_9f3c/live?ticket=example';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.sloose.com/orgs/org_9f3c/live?ticket=example'A WebSocket upgrade, authenticated by a ticket from POST …/socket rather than a bearer. The room writes down the socket, reads the session behind the ticket again — still signed in, still in the organisation, not banned, the organisation open — and only then accepts it; a ticket works once. A socket whose session no longer holds — it ended or moved to another organisation, or the organisation closed — is closed with code 4001. Send ping to be answered pong.
Frames from the room are JSON: { "type": "changed", "topics": [...] }, after a change to what the organisation’s people see about it commits — billing (the plan, its status, the trial, the period, a payment problem or notice), credits (the balance), entitlements (an override or a limit). A frame says only which; the page reads the organisation’s own routes again. A topic is named at most once every 1 second, so changes that come together arrive as one frame. Nothing is replayed: a page that was away reads everything again as its socket opens. Topics this list does not name yet may be added; a page passes over one it does not know. Today: billing, credits, entitlements.
Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The organisation id the session was issued for. A token for one organisation can never read another.
Example
org_9f3cThe organisation id the session was issued for. A token for one organisation can never read another.
Query Parameters
Section titled “Query Parameters”The ticket from POST …/socket.
The ticket from POST …/socket.
Responses
Section titled “Responses”Switching Protocols: the socket is open.
The address carries no ticket (code: INVALID_BODY).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}The ticket is unknown, used or expired (code: TICKET_INVALID).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}Not from the app’s own origin, or naming no origin at all (code: BAD_ORIGIN); the session is no longer in this organisation (code: SESSION_ENDED); or the organisation is closed (code: ORG_CLOSED).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}Not a WebSocket upgrade (code: UPGRADE_REQUIRED).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}The person’s sessions kept changing while the room read this one (code: ROOM_BUSY): ask for a new ticket and try again. Or the restore switch is on (code: MAINTENANCE): every route but /health and /robots.txt is refused before anything is read, with Retry-After (the operator’s ADMIN_TOKEN alone is let through to POST /staff/people/{id}/delete, and to nothing else).
Headers
Section titled “Headers”Seconds until asking again is worth it (300 while the switch is on).