Get started

API / Cookbook / 03

Follow every new turn live

Build a dashboard, an index or a watcher that stays in step with Tracez. Take a snapshot of what exists, then poll a change feed that picks up exactly where the snapshot started, including anything written while you were paging.

RESTGraphQLMCPLive

Snapshot, then replay from the fence
actor app: Your consumer
actor tz: Tracez
actor db: Your store
app -> tz: GET /api/stream/snapshot?limit=10
tz --> app: items, next_cursor, events_cursor
note app: keep events_cursor from this first page
loop while has_more
app -> tz: GET /api/stream/snapshot?cursor=next_cursor
tz --> app: next page of current turns
app -> db: upsert turns
end
loop forever
app -> tz: GET /api/stream/events?cursor=…
tz --> app: changes, next_cursor, poll_after_ms
app -> db: apply changes and save cursor in one transaction
note app: wait poll_after_ms, then ask again
end

Steps

  1. Start a snapshot

    The first call fixes a fence in Tracez's commit order. Keep its events_cursor: that is where the change feed will start. Add session=SESSION_ID to follow one session; the filter is sealed into every cursor after it.

    curl "https://tracez.recurz.ai/api/stream/snapshot?limit=10" \
      -H "Authorization: Bearer $RECURZ_TOKEN"
    {"version":1,"items":[…],"has_more":true,
     "next_cursor":"eyJ2Ijox…","events_cursor":"eyJ2Ijox…",
     "high_watermark":"48211","poll_after_ms":1000,
     "completion":"unknown","consistency":"current-state-with-replay"}
  2. Page to the end

    Pass each next_cursor back until has_more is false. Pages take 1–50 items (10 by default) and stop near 2 MiB.

  3. Follow the change feed

    curl "https://tracez.recurz.ai/api/stream/events?cursor=EVENTS_CURSOR" \
      -H "Authorization: Bearer $RECURZ_TOKEN"

    Each change says what to do with your copy:

    {"cursor":"48212","session_id":"…","kind":"turn",
     "action":"upsert_turn","resource_cursor":"48212","resource":{…}}
    • upsert_turn: store resource if its resource_cursor is newer than yours.
    • redact_session or delete_session: drop every cached turn for that session.
    • refresh_session: re-read the session.
  4. Save the cursor with the data

    Write the changes and the new cursor in one transaction. Replays are safe because applying the same change twice changes nothing, and an empty page only means you're caught up, not that a session has finished.

The same two operations are snapshot and resumeEvents in GraphQL and MCP, with the same cursors. Cursors pick a position; they never grant access, and every call still needs your token.