This import’s live socket
const url = 'https://api.sloose.com/orgs/org_9f3c/imports/imp_4d1a/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/imports/imp_4d1a/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 import’s org, not banned, the org open — and the import — still there, not being deleted — and only then accepts it; a ticket works once. A socket whose session no longer has the import — it ended or moved, or the import is being deleted — is closed with code 4001. Send ping to be answered pong.
Frames from the room are JSON:
{ "type": "presence", "people": [{ "userId", "name" }] }whenever somebody arrives or leaves, one entry per person however many tabs they have open.{ "type": "version", "version", "by": { "userId", "name" } }after every accepted write that moves the import’s version and leaves it open, so a page learns of somebody else’s change as it happens (deleting the import closes the socket instead, with 4001) — sent too as the socket is admitted, saying where the import stands, withbynaming who took it there when the room has heard that write, and null when it has not.{ "type": "run", "run": { "id", "status", "kind", "declaredRows", "by": { "userId", "name" } } }: the run holding the import, as it takes it (statusisauthorised) and as it ends (statussays how) — and in answer toresume, withrunnull when no run holds it.{ "type": "records", "runId", "after", "records": [{ "seq", "rowKey", "flowId", "rowNumber", "module", "phase", "target", "attempt", "outcome", "recordId", "code", "message" }], "more" }: what the run wrote, inseqorder — live, a frame a tenth of a second while it runs, and replayed in answer toresume.afteris theseqthe frame follows on from: every record of the run above it, up to the frame’s last, is in the frame. A live frame can start past what a replay has reached, so a place kept to resume from moves only along frames whoseafterit has reached. A record can arrive twice — live and replayed — and is the same record both times.
And one a page sends, besides ping: { "type": "resume", "runId", "afterSeq" }, asking where things stand — how the run runId ended if it no longer holds the import, and its records after afterSeq, which the live frames may not have reached the page with; then which run holds it now, and that run’s records after afterSeq (from its first, when it is another run than runId). A replay sends at most 20,000 records; when there are more, its last frame carries "more": true, and the page asks again from the furthest seq it has reached.
Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The org id the session was issued for. A token for one org can never read another.
Example
org_9f3cThe org id the session was issued for. A token for one org can never read another.
The import id.
Example
imp_4d1aThe import id.
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); or the session no longer has this import (code: SESSION_ENDED).
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"}No such import, or it is not visible to this session.
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.
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"}