Skip to content

Current status of a run and its steps.

GET
/v1/runs/{id}
curl --request GET \
--url https://example.com/v1/runs/example
id
required
string

Run id

Media typeapplication/json
object
id
required
string
origin_pr_base

The PR base branch (ADR-0057) — the branch a pull_request run targets, rendered base ← head in the ref cluster. A discrete origin fact; absent for non-PR runs and runs created before base-stamping.

string | null
params

The run’s frozen launch parameters, name → typed value (ADR-0043 §5). A run-level constant resolved once at creation; non-secret by contract (§6), so safe to expose. Empty when the run took none. Lets the UI’s re-run flow pre-fill the form from the prior run’s params.

object
pipeline

The pipeline this run executed (the bare .scarab/<name> selection). Absent for inline runs and runs created before pipeline-stamping.

string | null
run_number

The run number (ADR-0057 amendment) — the per-repo sequential #N, the human handle shown in the run-detail breadcrumb + gutter. Absent for untenanted inline runs and pre-allocation runs. Distinct from id.

integer | null format: int64
snapshot_retention
required

This run’s Workspace Snapshot retention promise (ADR-0061 s5) — the cold tier’s time bound, made explicit rather than left implicit in a sweeper’s config, plus any manual pin over it.

object
expired
required

The promise has lapsed: this run is terminal, unpinned, and past its window, so its snapshots may already have been swept. Not the same as “gone” — GC is periodic and content is shared, so data often outlives the promise. The honest word for it is expired, not deleted, and a rerun resolves the difference by checking the store.

boolean
expires_at

When this run’s Workspace Snapshots stop being promised (epoch millis). None while the run is non-terminal: a run that has not settled — including one suspended on a gate for weeks — is never GC-eligible regardless of age (ADR-0050), so no expiry applies yet. Also None while pinned, because a pin holds the window open indefinitely.

integer | null format: int64
pinned
required

A human pinned this run’s Workspace Snapshots — hold them past the window for an investigation.

boolean
pinned_at

When it was pinned, epoch millis.

integer | null format: int64
pinned_by

Who pinned it (None when unpinned, or when auth is off).

string | null
retention_days
required

The retention window in days — what the GC sweeper actually enforces.

integer format: int32
status
required
string
steps
required
Array<object>
object
attempt_list

Per-attempt detail (ADR-0047) — the rerun/retry history in append order. attempts is the count; this is the list, so the UI can show retries (a failed attempt followed by a succeeding one — the durable-execution story) and fold a step’s logs per attempt. Empty until the step first launches.

Array<object>

One attempt at executing a step (ADR-0047) — the rerun unit. A step with more than one attempt is one that failed-and-retried (or was restarted); the last attempt carries the current outcome.

object
failed
required

true if this attempt ended in a classified failure. A later attempt may still have succeeded — that divergence is exactly the retry story worth showing. Retained for back-compat; prefer outcome for the full picture (a superseded/cancelled attempt is failed:false but NOT green).

boolean
failure

Coarse failure kind when failed: infra | step | timeout | lost | config | missing-inputs (an input snapshot gone from every tier — Rerun/Retry regenerates it; ticket e140121).

string | null
failure_detail

The executor’s human-readable cause for a failed attempt (ticket 4cf03d7) — e.g. “cold tier refused: connection refused” — alongside the machine-consumed failure class. Absent = the class is the whole story (or a pre-0041 row). Stored since migration 0041.

string | null
id
required
string
outcome
required

The attempt’s recorded outcome (ADR-0056 amendment): running | succeeded | failed | superseded | cancelled. Unlike failed this distinguishes a superseded attempt (a rerun/retry replaced its input while it was still running and its Pod was torn down) from a genuine success — so the UI never renders an abandoned attempt green.

string
started_at
required

When this attempt started (unix-ms).

integer format: int64
attempts
required
integer
gate

manual/timer/external if this step is a gate (ADR-0008), else absent. Gates launch no pod and suspend the run until released.

string | null
id
required
string
needs

Upstream step ids this step depends on — the DAG in-edges (ADR-0006). The UI folds these into the run’s graph view.

Array<string>
services

Co-located sidecar services (ADR-0058) this step declares — rendered as sidecar nodes attached to the step, each with its own log stream (fetched via ?sidecar=<index> on the step-logs endpoint). Empty for a step with no services:.

Array<object>

One of a step’s co-located sidecar services (ADR-0058) — a throwaway backing container in the step’s own Pod, reachable at localhost:<port>. Positional: identified by its index in the step’s authored services:, which is also its container ordinal (service-{index}) and the ?sidecar= selector for its logs. Not a needs-able DAG node.

object
image
required

The service OCI image (e.g. postgres:16).

string
index
required

Index in the step’s services: list — the log selector and container ord.

integer
ports

Container ports the service listens on (all reachable at localhost:<p>).

Array<integer>
status
required
string
uses

Names of pipeline-level shared services this step opts into via uses: (ADR-0058) — the DAG’s service edges. Empty for a step that uses none.

Array<string>
trigger_title

The run Headline (ADR-0057) — the one human line saying what this run is about (a push’s commit subject; later a PR title / dispatch reason), disambiguated by the trigger kind. Display/audit only; absent when the trigger carried no headline and on runs created before headline-stamping.

string | null
Examplegenerated
{
"id": "example",
"origin_pr_base": "example",
"params": {},
"pipeline": "example",
"run_number": 1,
"snapshot_retention": {
"expired": true,
"expires_at": 1,
"pinned": true,
"pinned_at": 1,
"pinned_by": "example",
"retention_days": 1
},
"status": "example",
"steps": [
{
"attempt_list": [
{
"failed": true,
"failure": "example",
"failure_detail": "example",
"id": "example",
"outcome": "example",
"started_at": 1
}
],
"attempts": 1,
"gate": "example",
"id": "example",
"needs": [
"example"
],
"services": [
{
"image": "example",
"index": 1,
"ports": [
1
]
}
],
"status": "example",
"uses": [
"example"
]
}
],
"trigger_title": "example"
}

No such run