Run events

The persisted transition log, and how to resume it after a disconnect.

The transition ledger

A compile publishes its transitions to an append-only ledger. The event stream replays that ledger from Last-Event-ID and then follows it, so a client that reconnects sees everything it missed rather than the current state alone.

GET/compile-jobs/{jobId}/eventsScope collections:read

Replays the persisted transition log after Last-Event-ID, then follows it. The server closes the stream at its own wall clock, so reconnecting is the normal case rather than an error path; every frame carries the durable sequence to resume from. Nothing is lost when a connection drops, because the events are written before they are sent and nothing was ever only in the connection.

curl -sS -X GET https://tavonel.com/api/compile-jobs/{jobId}/events \
  -H "Authorization: Bearer $TAVONEL_API_KEY"
StatusResponse
200text/event-stream of persisted compile transitions. Each frame's id is the durable sequence; echo it back as Last-Event-ID to resume.
400COMPILE_JOB_SCOPE_INVALID — The job exists and belongs to another workspace.
401AUTH_REQUIRED — No credential was presented, or the bearer token is not a key TAVONEL issued. This is what an unauthenticated request to any scoped route returns.
404COMPILE_JOB_NOT_FOUND — No such job in this workspace. Job ids are workspace-scoped, so this is also the answer for another tenant's id.
GET/compile-jobs/{jobId}Scope collections:read

The durable current state. A poller against this sees exactly what a stream subscriber sees, because both read the same row. A job id from another workspace answers not found, which is also all it should reveal.

curl -sS -X GET https://tavonel.com/api/compile-jobs/{jobId} \
  -H "Authorization: Bearer $TAVONEL_API_KEY"
StatusResponse
200{ code: OK, job }, including any blocked documents and the resolution recorded against them.
400COMPILE_JOB_SCOPE_INVALID — The job exists and belongs to another workspace.
401AUTH_REQUIRED — No credential was presented, or the bearer token is not a key TAVONEL issued. This is what an unauthenticated request to any scoped route returns.
404COMPILE_JOB_NOT_FOUND — No such job in this workspace. Job ids are workspace-scoped, so this is also the answer for another tenant's id.
503COMPILE_JOB_STORE_READ_FAILED — The durable job store could not be read.

Resuming after a disconnect

Resume after a disconnect
curl -N https://tavonel.com/api/compile-jobs/<jobId>/events \
  -H "Authorization: Bearer $TAVONEL_API_KEY" \
  -H "Last-Event-ID: 42"

Reconnecting is the normal case

Note The server closes the stream on its own clock. Reconnecting is the normal case, not an error path — every frame carries the sequence to resume from.

The other stream: observed runs

A compile has its own transitions, above. A connector sync or an intake is an observed run, with its own append-only event ledger and its own stream. Both resume the same way, from Last-Event-ID; this one also accepts an after query parameter for clients that cannot set the header, and sends a bounded heartbeat so an intermediary does not close an idle connection.

GET/runs/{runId}/eventsScope documents:read

Replays append-only observed run events after Last-Event-ID, then streams new events and a bounded heartbeat. This is the second of two event streams and the one over *observed* runs — a connector sync, an intake — where /compile-jobs/{jobId}/events follows a compile's own transitions. `after` is the query-parameter form of Last-Event-ID, for clients that cannot set the header.

curl -sS -X GET https://tavonel.com/api/v1/runs/{runId}/events \
  -H "Authorization: Bearer $TAVONEL_API_KEY"
StatusResponse
200Persisted run-event stream. Frames carry the durable sequence as id; a heartbeat frame keeps intermediaries from closing an idle connection.
400RUN_ID_REQUIRED — The run id path segment was empty. JOB_CURSOR_INVALID — The run's cursor did not validate.
401AUTH_REQUIRED — No credential was presented, or the bearer token is not a key TAVONEL issued. This is what an unauthenticated request to any scoped route returns.
404JOB_NOT_FOUND — No such run in this workspace. JOB_SCOPE_INVALID — The run exists and belongs to another workspace. Answered as not found rather than as forbidden, so an id cannot be probed across tenants.
503JOB_STORE_READ_FAILED — The run store could not be read.

API version 2026-09-02.1 · reviewed 11 September 2026

Something here out of date or wrong? Report an issue with this page.