Production Board
WebSocket transport
Optional: same CRUD surface plus live events over one socket.
WebSockets are optional. The HTTP API covers every operation on its own - if you'd rather keep things simple, stop at the auth + per-model pages and ignore this one. The WebSocket transport is here when you want live events (no polling), or when you'd rather pay one TLS handshake for a long burst of operations. Connect to /xapi2/ch, hand it the same Bearer token the HTTP API accepts, and run any CRUD op (list, read, create, update, delete) plus subscribe over the same socket. Auth, scopes, rate limits, audit, and access checks are identical to HTTP - only the transport differs.
How it works
Handshake
Connect to /xapi2/ch?token=<jwt-or-pat>, or send the token via the Sec-WebSocket-Protocol: bearer, <token> header. Server replies with a hello frame on accept.
Live events
Send { op: "subscribe", id, dataType } to receive event frames whenever a row of that type is created, updated, or deleted - filtered server-side by your read access.
Streaming list
WS list streams results as list_chunk frames (default 25/page, hard cap 10k rows total) followed by a final list_done carrying the same metadata HTTP's meta block does. Useful for large initial loads.
Examples
const ws = new WebSocket(`wss://${location.host}/xapi2/ch?token=${encodeURIComponent(token)}`,)ws.onopen = () => {// Receive live created/updated/deleted events for this type.ws.send(JSON.stringify({ op: "subscribe", id: "sub-1", dataType: "board" }))}ws.onmessage = (msg) => {const frame = JSON.parse(msg.data)if (frame.op === "event") console.log(frame.event, frame.dataType, frame.object ?? frame.id)}