/api/v1/events
Event replay (JSON) or live stream (SSE)
One endpoint, two representations negotiated by Accept:
application/json (default) — replay page {events,nextCursor,truncated}. cursor
is a decimal seq string (uint64, so never a JSON number), limit defaults to 100 and
is clamped to 500. Filtering by environmentIds/projectIds creates seq gaps by
design: only resume from the server-returned cursor, never try to "fill holes".
text/event-stream — live stream (replay first, then real time). Frames are
id: , event: , data: ; heartbeat comment every 15s;
no terminal EOF. Authorization must ride the header (fetch streaming), there is no
?token= channel. A slow consumer (>=257 unconsumed frames) is disconnected.
Resync: the server keeps a durable prune watermark (the smallest surviving durable seq
for the tenant, monotonic, advanced only by rows actually deleted). A cursor beyond
the stream head OR below the watermark is no longer serviceable — the JSON
representation answers 409 state_conflict with
details: {resync:'eaas.resync', lastSeq} (lastSeq = current stream head, the
re-subscribe anchor); the SSE representation emits an eaas.resync frame and closes
(WS closes 4409). The client re-reads an authorized snapshot and re-subscribes. A
watermark of 0 (never pruned) keeps the old cursor>head-only behavior. Out-of-band
event-row deletes that do not advance the watermark can strand cursors — manual
deletes must push the prune watermark in the same transaction (ops convention).
Delivery is at-least-once; clients deduplicate by eventId. Principal sessions
subscribe pinned to their bound environment; explicit client filters on the principal
face are rejected with 400, and events outside the binding are never delivered. The
principal face's actual scope gate is environments:read (NOT events:read — a
deliberate widening, T6-M-7: the principal subset never carries events:read, so the
SSE face is the principal's only event channel; the WebSocket face stays machine-key
only).
Parameters
| Field | Type | Req | Default | Description |
|---|---|---|---|---|
| Accept | string | N | application/json | `application/json` for replay, `text/event-stream` for the live stream. |
| cursor | string | N | — | Already-scanned seq position (decimal string, 0 start). |
| limit | integer | N | 100 | Replay page size (JSON representation only). |
| environmentIds | string | N | — | Comma-separated environment filter. |
| projectIds | string | N | — | Comma-separated project filter. |