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 param | Type | Description |
|---|
kind | string | Optional. 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
}
| Field | Type | Required | Description |
|---|
kind | enum | yes | backtest (agents can also create paper requests, but they require approval). |
spec_id | string | yes | The strategy spec to run. |
spec_version | integer | yes | The 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" }
POST /api/runs/{id}/promote
Authorization: Bearer <clerk-jwt>
Content-Type: application/json
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
| Transition | Trigger |
|---|
draft → queued | Run enqueued by POST /api/runs. |
queued → running | Worker leases the job. |
running → succeeded | Kernel completes. |
running → failed | Kernel raises. |
running → timeout | Wall-clock budget exceeded. |
queued/running → cancelled | POST /api/runs/{id}/cancel. |
Every transition emits a run_transition trace event. See Trace events.