Skip to main content
GET
cURL

Authorizations

Authorization
string
header
required

Primary scheme: Authorization: Key <key_id>:<secret>.

Headers

Last-Event-Id
string | null

Resume after this event id — the standard SSE reconnect header; browsers' EventSource sends it automatically.

Path Parameters

job_id
string
required

The job's id (job_<uuid>).

Response

Server-Sent Events. Each frame's event: names its type. The data: line of a status frame is a StatusResponse and of a log frame a JobLogItem (the same row GET /jobs/{job_id}/logs serves), both JSON. The stream opens with a status snapshot and ends with a done frame, sent after the terminal status frame: reaching it means the job finished (COMPLETED or FAILED) and there is nothing more to read. A stream that ends without it was cut short; reconnect with Last-Event-Id. Closes the server initiates instead (drain, max connection duration) send a retry: line and no done. The done frame's data: line is the literal token [STREAM_DONE] — not JSON, and not a member of the JobStreamFrame schema below. It is a fixed end-of-stream sentinel, matched verbatim; switch on event: and skip done before parsing a data: line, or the parse fails on the last frame of every stream. It repeats no state: which job ended and how was just delivered by the terminal status frame. status and log frames carry an id: to send back as Last-Event-Id; done does not, since it is not a new stream position. Comment lines (: keep-alive) and retry: lines are protocol-level and carry no payload.

The lightweight poll envelope, also the SSE status frame and the MCP progress notification payload.

The two log fields are poll-only by construction, like cost on the result envelope: they are populated when — and only when — a GET /v3/jobs/{job_id}/status caller supplies a logs_after cursor, and they exclude when None, so the frame the stream transports build from a Redis payload with no DB session is byte-identical to a log-free envelope. That was ENG-9693's reason for having no logs field at all; the stream now carries lifecycle rows as their own event: log frames instead of inside this one (ENG-9694).

job_id
string
required

The job this status describes.

status
enum<string>
required

The four states a job can be in.

Available options:
IN_QUEUE,
IN_PROGRESS,
COMPLETED,
FAILED
progress
number

Fraction of the job completed, from 0 to 1 (not a percentage). Null when the job has not reported progress yet.

Required range: 0 <= x <= 1
estimated_completion_at
string<date-time> | null

ISO-8601 instant this job is estimated to finish; null when no estimate exists for the model yet. Refreshed on every poll.

logs
JobLogItem · object[] | null

Lifecycle events newer than the logs_after cursor, oldest first. Present only when logs_after is supplied; absent from SSE status frames and MCP progress notifications.

logs_next_cursor
string | null

Cursor to send as logs_after on the next poll. Absent when this poll delivered no new events — keep using the cursor you sent.