Skip to content

This import’s live socket

GET
/orgs/{org}/imports/{id}/live
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, with by naming 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 (status is authorised) and as it ends (status says how) — and in answer to resume, with run null 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, in seq order — live, a frame a tenth of a second while it runs, and replayed in answer to resume. after is the seq the 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 whose after it 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.

org
required

The org id the session was issued for. A token for one org can never read another.

string
Example
org_9f3c

The org id the session was issued for. A token for one org can never read another.

id
required

The import id.

string
Example
imp_4d1a

The import id.

ticket
required

The ticket from POST …/socket.

string
>= 1 characters

The ticket from POST …/socket.

Switching Protocols: the socket is open.

The address carries no ticket (code: INVALID_BODY).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

The ticket is unknown, used or expired (code: TICKET_INVALID).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
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).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

No such import, or it is not visible to this session.

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

Not a WebSocket upgrade (code: UPGRADE_REQUIRED).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
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.

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

Report a problem with this page