Skip to main content
A run is a single execution of a strategy — either a backtest or a paper-trading deployment. Runs are created by agents (backtests) and promoted by humans (paper trading).

List runs

GET /api/runs?kind=backtest
Authorization: Bearer <token>
Query paramTypeDescription
kindstringOptional. Filter by backtest or paper.

Response

{
  "runs": [
    {
      "id": "run_abc",
      "kind": "backtest",
      "status": "succeeded",
      "spec_id": "spec_xyz",
      "spec_version": 3,
      "tenant_id": "tnt_abc",
      "created_at": "2025-01-15T12:00:00Z"
    }
  ]
}

Get a run

GET /api/runs/{id}
Authorization: Bearer <token>
Returns the full run record plus a shaped trace — the trace events for this run, ordered by seq, ready for the web UI to render.

Response

{
  "id": "run_abc",
  "kind": "backtest",
  "status": "succeeded",
  "spec": { "spec_version": "1.0", "...": "..." },
  "result_hash": "sha256:9f2c...",
  "trace": [
    { "seq": 1, "type": "job_queued", "ts": "..." },
    { "seq": 2, "type": "run_transition", "ts": "...", "data": { "to": "running" } },
    { "seq": 3, "type": "run_progress", "ts": "...", "data": { "pct": 0.5 } },
    { "seq": 4, "type": "artifact_created", "ts": "..." }
  ],
  "created_at": "2025-01-15T12:00:00Z",
  "finished_at": "2025-01-15T12:00:12Z"
}

Get paper positions

GET /api/runs/{id}/book
Authorization: Bearer <token>
Returns the current paper-trading positions for a promoted run. Only valid for runs with kind: "paper".

Response

{
  "run_id": "run_abc",
  "positions": [
    { "symbol": "NVDA", "weight": 0.32, "shares": 120, "cost_basis": 480.10 }
  ],
  "cash": 1234.56,
  "as_of": "2025-01-15T16:00:00Z"
}

Create a backtest run

POST /api/runs
Authorization: Bearer <token>
Content-Type: application/json
{
  "kind": "backtest",
  "spec_id": "spec_xyz",
  "spec_version": 3
}
FieldTypeRequiredDescription
kindenumyesbacktest (agents can also create paper requests, but they require approval).
spec_idstringyesThe strategy spec to run.
spec_versionintegeryesThe immutable version to pin.

Response

{
  "id": "run_abc",
  "kind": "backtest",
  "status": "queued",
  "spec_id": "spec_xyz",
  "spec_version": 3,
  "created_at": "2025-01-15T12:00:00Z"
}
Requires the runs:write scope.

Cancel a run

POST /api/runs/{id}/cancel
Authorization: Bearer <token>
Cancels a run that is queued or running. Emits a run_transition event to cancelled. Requires the runs:cancel scope.

Response

{ "id": "run_abc", "status": "cancelled" }

Promote a run

POST /api/runs/{id}/promote
Authorization: Bearer <clerk-jwt>
Content-Type: application/json
{ "scope": "paper" }
Promotion is human-only. An API key (agent) calling this endpoint is rejected with 403. The endpoint checks actor_kind === "human".
Promotion creates an approval record in the pending state and emits an approval_requested trace event. The actual deployment happens only after a human approves via Approval endpoints. See Approval workflow.

Response

{
  "run_id": "run_abc",
  "approval_id": "apr_def",
  "state": "pending",
  "scope": "paper"
}

Run state machine

draft → queued → running → succeeded
                         → failed
                         → timeout
                         → cancelled
For paper runs after approval:
pending_approval → paper_active → paper_stopped
TransitionTrigger
draft → queuedRun enqueued by POST /api/runs.
queued → runningWorker leases the job.
running → succeededKernel completes.
running → failedKernel raises.
running → timeoutWall-clock budget exceeded.
queued/running → cancelledPOST /api/runs/{id}/cancel.
Every transition emits a run_transition trace event. See Trace events.