Skip to content

Live event stream (SSE)

GET
/events
curl --request GET \
--url https://example.com/api/v1/events

Server-Sent Events stream of live job, sync, canary and drift progress.

Framing: the stream opens with retry: 5000, then emits data: <LiveEvent JSON> frames (see #/components/schemas/LiveEvent). The first frame is always hello. Domain events (job.*, sync.recorded, canary.updated, drift.updated) carry id: <bootId>-<seq>; hello, resync and session.expired carry no id. A : ping comment is sent every 20 s.

Replay: send the last received id in the Last-Event-ID header (set automatically by EventSource on reconnect) or the lastEventId query parameter. Missed domain events are replayed from a 256-event in-memory buffer, at most 61 events per connection. When replay is impossible the server sends resync and the client must refetch its state: reason: boot when the id is from a previous server process or is over-long or malformed; reason: gap when the id is older than the buffer or the backlog exceeds 61 events.

Session checks: each heartbeat re-validates the session or API token; when it is no longer valid the server sends session.expired and closes the stream. Streams are closed after a maximum lifetime of 60 minutes; clients reconnect and resume via Last-Event-ID.

Authentication: browser session cookie, or an API token with the read scope. Prefer the X-Api-Key header; the ?apikey= query parameter is accepted for EventSource clients that cannot set headers, but leaks into logs and history.

X-Api-Key
string

Praxrr API token (prx_…) with the read scope. Preferred over the apikey query parameter.

Last-Event-ID
string

Id of the last domain event the client received (<bootId>-<seq>), for replay.

apikey
string

Praxrr API token with the read scope, for EventSource clients that cannot set headers. Warning: the token leaks into proxy and access logs and browser history; prefer X-Api-Key.

lastEventId
string

Query-string alternative to the Last-Event-ID header.

text/event-stream of LiveEvent frames. Each data: line is a JSON #/components/schemas/LiveEvent.

Media typetext/event-stream
string

Unauthenticated (no valid session, or missing, invalid, revoked, or expired API token).

Media typeapplication/json
object
error
required

Error message

string
code

Stable machine-readable code present on 5xx responses; error is a fixed user-safe message, raw detail is logged server-side only

string
Allowed values: cleanup_failed library_fetch_failed episodes_fetch_failed releases_fetch_failed
Example
{
"code": "cleanup_failed"
}

The API token lacks the read scope.

Media typeapplication/json

An authenticated API token lacks the scope the requested route requires.

object
error
required

Always Forbidden.

string
requiredScope
required

The API token scope this request requires.

string
Allowed values: read mcp sync:apply admin
Example
{
"requiredScope": "read"
}

Too many concurrent streams for this principal.

Media typeapplication/json
object
error
required

Error message

string
code

Stable machine-readable code present on 5xx responses; error is a fixed user-safe message, raw detail is logged server-side only

string
Allowed values: cleanup_failed library_fetch_failed episodes_fetch_failed releases_fetch_failed
Example
{
"code": "cleanup_failed"
}
Retry-After
integer

The server-wide stream limit is reached.

Media typeapplication/json
object
error
required

Error message

string
code

Stable machine-readable code present on 5xx responses; error is a fixed user-safe message, raw detail is logged server-side only

string
Allowed values: cleanup_failed library_fetch_failed episodes_fetch_failed releases_fetch_failed
Example
{
"code": "cleanup_failed"
}
Retry-After
integer