COMPLETED / FAILED / CANCELLED / TIMEOUT. Since PR #234 the legacy agent_runs table is gone; runs are reconstructed from the Crew Journal by grouping journal_entries on trace_id (which equals the run id). The HTTP shape is preserved — frontend consumers don’t see a contract change.
Every endpoint is workspace-scoped via the session context.
Runs are read-only — there is no write endpoint. A run comes into existence when the orchestrator emits
run.started and concludes when a terminal run.{completed|failed|cancelled|timeout} lands on the same trace_id.Endpoints
List runs
stats) and pagination metadata. Backed by journal.ListRuns (CTE-grouped over journal_entries keyed on trace_id) plus journal.RunStats for the tiles.
Query parameters:
Response:
200 OK
Errors:
Fleet insights
journal.RunInsights; the handler resolves per-agent counts into a
crew rollup and a display-named top-agents leaderboard (one workspace-scoped
agents→crews join).
Query parameters:
Response:
200 OK
Get a single run
data[] array from GET /api/v1/runs — the handler reuses the same enrichment so dashboard detail views can share the row renderer.
Path parameters:
Response:
200 OK
journal.GetRunByID lookup. A
trace ID from another workspace is treated as not found.
Tenancy
workspace_idis taken from the session context — never from a query parameter.- Cross-tenant trace IDs are filtered out at the journal store (
journal.ListRunsrequires a non-emptyWorkspaceID). - Enrichment lookup (
agents+crews) is workspace-scoped, so an agent ID collision across workspaces (test fixtures, restored backups) cannot attach foreign names to a row.
Related
- Crew Journal guide — full event-type catalog and the
run.*lifecycle. - Journal API — the underlying read surface, including FTS search and SSE live tail with
trace_idfiltering for one run’s spans. crewship journal --trace-id <run-id>— list every span (LLM call, exec, network egress) belonging to one run.