GET /runs

Paginated list of runs, newest first. Scoped to the caller's API key when keys are provisioned (anonymous in open mode).

Request

GET /runs?limit=50&offset=0
X-Verdifax-Key: vfx_...

Query parameters

ParameterTypeDefaultNotes
limitint50Max 500
offsetint0Pagination cursor

Response

{
  "ok": true,
  "total": 1248,
  "limit": 50,
  "offset": 0,
  "runs": [
    {
      "id": 63,
      "created_at": "2026-04-30T03:35:04.123Z",
      "program_id": "aaaa...",
      "route_id": "route-test",
      "manifest_hash": "6c1428f81519c5bb...",
      "duration_ms": 3,
      "duration_micros": 3140,
      "outcome_kind": "ok",
      "error_stage": ""
    }
  ]
}

Fields:

  • id, Run identifier
  • created_at, RFC3339 timestamp
  • program_id, The program that was attested
  • route_id, The route identifier
  • manifest_hash, For OK runs only; nil for non-OK outcomes
  • duration_ms, Wall-clock duration in milliseconds
  • duration_micros, Sub-millisecond precision (microseconds)
  • outcome_kind, One of ok, pepg_deny, ccv_halt, macc_halt, stage_error
  • error_stage, For pipeline crashes only; one of the nine stage codes

The outcome_kind field tells you which sealed-artifact endpoint to call:

  • ok/runs/{id}/allow-token
  • pepg_deny/runs/{id}/deny-receipt
  • ccv_halt/runs/{id}/ccv-halt-receipt
  • macc_halt/runs/{id}/macc-halt-receipt
  • stage_error → No artifact; run record only

The summary view omits the full ExecutionManifest for performance. Use GET /runs/{id} for the full record.

Example

curl -s "http://localhost:9090/runs?limit=10" \
  -H "X-Verdifax-Key: vfx_..." | python3 -m json.tool

For filtering by manifest hash prefix, program_id, route_id, status, or date range, use GET /runs/search, same shape, additional query params.

Continue