Docs / Operate
Jobs and long-running work
6 minute read · Updated 2026-09-11
Every render is a job. The launch call returns a job id immediately and the work continues on a render worker; you poll get_job until the status is terminal. Treating the launch response as a result is the single most common integration mistake.
Why renders are asynchronous
Assembling video needs ffmpeg and a headless browser, and it takes minutes. That cannot happen inside a request, so pipeline tools hand the work to a dedicated render worker and return a handle.
The worker scales to zero when idle and is woken on enqueue, so the first job after a quiet period spends its opening moments cold-starting. A job sitting in pending for a minute is normal, not stuck.
The lifecycle
- 01
Launch
Any job-mode tool returns { job_id, kind } and nothing else. Credits are reserved at this point, before dispatch.
- 02
Poll
Call get_job with the id. Poll every 20–30 seconds; polling faster gains nothing and burns tokens.
json { "name": "get_job", "arguments": { "job_id": "a1b2c3d4-…" } } - 03
Report progress
Each poll returns the latest log event. Surface it — a user watching a five-minute render wants to see which stage it reached, not silence.
- 04
Finish
When status reaches completed, result holds the generated assets. On failed, error and the final log event say why.
| Status | Meaning |
|---|---|
| pending | Queued. The worker may be cold-starting. |
| running | In progress — the log event tells you which stage. |
| completed | Done. Read result. |
| failed | Terminal. Read error; the credit reservation is refunded. |
| cancelled | You asked it to stop and it reached a checkpoint. |
What get_job returns
Response fields
statusstringrequired- pending | running | completed | failed | cancelled.
latest eventobject- The most recent progress entry from the pipeline log.
resultobject- Present once completed — the assets the pipeline produced.
errorstring- Present on failure. Report it verbatim rather than paraphrasing.
Cancelling
cancel_job requests a stop; the pipeline aborts at its next progress checkpoint, usually within a few seconds. It is not instantaneous, and a stage already in flight with an external model will finish that stage first.
Use list_jobs to see everything currently running or pending in the workspace if you have lost track of an id.
When a job dies
Jobs fail in two ways: the pipeline throws, or the process running it dies outright. Both end with the job marked failed, the credit reservation refunded, and a terminal error event in the log — a reaper handles the second case, since the normal failure path is exactly what did not run.
The practical consequence for a caller: a failed job is always eventually visible as failed. If a job appears to hang forever in running, that is worth reporting rather than waiting out.
Keep going