Skip to main content

Jobs API

The Jobs API runs a unit of work and lets you watch it happen. A run is a single execution; a definition is a reusable, scheduled template that produces runs on a cron. Both are served over the public admin API under /api/public/v1/admin/jobs, and both are indexed in the public OpenAPI document.

A job run is executed as an orchestration run on the cell, the Jobs API is the public, stable front door over that machinery. That is why the permissions are the orchestration operator scopes (below) and why a run's identifier is the orchestration run identifier, reused verbatim in the journal and event stream.

How to read this page

Each operation carries a status. Live means the endpoint is served and its core function is reachable. Where a broader headline (recurring schedules, reusable definitions) is only partly wired, this page names the reachable slice and marks the rest owed. It does not claim the whole.

Authentication and scope​

Present an API key or OAuth token as a bearer token.

Operation kindPermission required
Read (list, status, journal, events)system.orchestration.admin.read
Write (run, cancel, create/update/enable/disable/delete a definition)system.orchestration.admin.write
caution
A fine-grained system.jobs.* scope is owed

Because a job run is an orchestration run, the Jobs API today reuses the orchestration operator permissions above. A dedicated system.jobs.* scope family which would let an API key be attenuated to jobs-only authority, is owed, not yet served. Scope a jobs-only key by the orchestration admin permissions for now.

Runs​

All run endpoints are Live.

OperationMethod + path
Trigger a run (run now)POST /api/public/v1/admin/jobs/runs
List runsGET /api/public/v1/admin/jobs/runs
Get run statusGET /api/public/v1/admin/jobs/runs/{job_id}
Run journal (events so far)GET /api/public/v1/admin/jobs/runs/{run_id}/journal
Live event stream (SSE)GET /api/public/v1/admin/jobs/runs/{run_id}/events/sse
Cancel a runPOST /api/public/v1/admin/jobs/runs/{run_id}/cancel

Trigger a run​

curl -sS -X POST https://<node>/api/public/v1/admin/jobs/runs \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"job_type": "sql",
"workspace_id": "<workspace_id>",
"spec": { "…": "…" }
}'

job_type is one of notebook, compute, sql, or single (a single-agent run). The requester is taken from the authenticated session, never from the request body. The response carries the run identifier used by the status, journal, cancel, and event-stream endpoints.

List and inspect​

GET …/jobs/runs accepts limit (default 200, 1–2000) and offset, like the rest of the public API's pagination. The list and status responses carry a checked_cell_id:

note
What checked_cell_id honestly means

The scheduled-jobs table is per-cell and not replicated. A read lands on one cell and reports what that cell sees, so the response names which cell answered in checked_cell_id. A status of unknown alongside a checked_cell_id means "this job was not found on this cell". It is never dressed up as "no such job." A single call is not a fleet-wide view; a cross-cell aggregate is a later item.

Watch a run live​

GET …/jobs/runs/{run_id}/events/sse is a Server-Sent Events stream of the run's events as they happen; …/journal returns the events accumulated so far as a normal response. Cancel is idempotent, cancelling an already-finished or already-cancelled run is safe.

Figure: the run lifecycle: trigger a run, obtain its id, watch it over SSE (or poll the journal), and cancel if needed.

Table equivalent

StepCallResult
TriggerPOST /jobs/runsrun_id; requester from session
Watch (live)GET /jobs/runs/{run_id}/events/sseSSE event stream
Watch (snapshot)GET /jobs/runs/{run_id}/journalevents accumulated so far
StatusGET /jobs/runs/{job_id}state + checked_cell_id
CancelPOST /jobs/runs/{run_id}/cancelidempotent cancel

Definitions (scheduled jobs)​

A definition is a reusable template, a typed {job_type, spec} plus a cron schedule, that produces runs automatically. The definition endpoints are served (Live), backed by the cell's cron-schedule store.

OperationMethod + path
CreatePOST /api/public/v1/admin/jobs/definitions
ListGET /api/public/v1/admin/jobs/definitions
GetGET /api/public/v1/admin/jobs/definitions/{schedule_id}
UpdatePATCH /api/public/v1/admin/jobs/definitions/{schedule_id}
EnablePOST /api/public/v1/admin/jobs/definitions/{schedule_id}/enable
DisablePOST /api/public/v1/admin/jobs/definitions/{schedule_id}/disable
Delete (soft)DELETE /api/public/v1/admin/jobs/definitions/{schedule_id}

Five job types are schedulable: compute, notebook, sql, agent and team. Two of them validate their template when the definition is authored, rather than failing on every fire:

Job typeTemplate must nameRefused
agentgraph_id, the agent graph the run executesA formation_id; that is a crew, so schedule it as team
teamcrew_id, the crew instance whose members are boundA formation_id alone, which is a template with no members
Served, and one thing still owed

Unscheduled reusable definitions, a saved template you trigger on demand with no cron, are owed. A definition requires a valid cron expression, so every definition is a schedule. For a one-off, use a run (above).

Figure: a cron definition produces observable runs, and all five job types can carry one. The single owed shape is a reusable definition with no schedule.

Table equivalent

Definition shapeStatus
Recurring compute, notebook or sql job on a cronLive: produces runs on schedule
Recurring agent schedule (naming a graph_id)Live: dispatched durably through the governed submit path
Recurring team schedule (naming a crew_id)Live: compiles and launches the crew
Unscheduled reusable template (trigger on demand)Owed: not wired