Codevisor Docs

Events and replay

Synchronize clients with global and session-scoped server events.

Every event is an envelope with a server ID, kind, subject, timestamp, cursor information, and an event-specific payload.

{
  "id": 42,
  "globalEventId": 42,
  "subjectRevision": 7,
  "serverId": "build-box",
  "kind": "session.updated",
  "subjectId": "session-id",
  "createdAt": "2026-07-10T12:00:00.000Z",
  "payload": {}
}

id is the cursor for the stream that delivered the envelope. globalEventId identifies the event in the global shell log when it belongs there. subjectRevision is monotonic within one subject and drives session-scoped replay. Optional cursor fields are absent when they do not apply.

Close the snapshot race

To load a snapshot without missing an event created during the request:

  1. Read GET /v1/events/cursor and save its cursor.
  2. Fetch the project, workspace, or session snapshot needed by the screen.
  3. Connect to /v1/events/socket?since=CURSOR or /v1/events?since=CURSOR.
  4. Apply the replayed events, then continue with live events.

Capturing the cursor first guarantees that changes concurrent with the snapshot are replayed.

Persisted session history

GET /v1/sessions/{id}/transcript returns a session's stored transcript one page at a time, starting from the newest items. Pass the page's nextBefore cursor as before to load older items. Read the tool calls, diffs, plans, and other non-text events behind one item with GET /v1/sessions/{id}/transcript/{itemId}/details.

Each page includes an eventCursor. Pass it as since to the session socket to continue with live events. GET /v1/sessions/{id}/events is no longer a history API; it returns 410 Gone.

Server-Sent Events

GET /v1/events?since=CURSOR returns text/event-stream, replays persisted global events after the cursor, and stays open for new events.

WebSockets

  • /v1/events/socket?since=CURSOR streams global shell events.
  • /v1/sessions/{id}/events/socket?since=CURSOR streams one session and uses its subject revision as the cursor.

Each WebSocket message is one JSON-encoded event envelope. Reconnect with the last processed cursor. Passing Number.MAX_SAFE_INTEGER as since requests live events without replay.

The session socket sends a kind: "keepalive" envelope about every 25 seconds. Its id equals the current session cursor; do not advance the saved cursor or render it as session activity. On session sockets, the envelope id has already been rewritten to the subject-revision cursor.

Event handling should be idempotent. Replayed metadata events may replace cached resources, while append-only output should be deduplicated by its event cursor.

On this page