Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt

Use this file to discover all available pages before exploring further.

A “run” is one agent execution — orchestrator picks up an assignment, exec’s the CLI, the run ends with one of 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. There is no write endpoint — runs come into existence when the orchestrator emits run.started and conclude when a terminal run.{completed|failed|cancelled|timeout} lands on the same trace_id.

List runs

GET /api/v1/runs
Returns a paginated list of runs with KPI tiles (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:
ParamTypeDescription
statusstringFilter to one of RUNNING, COMPLETED, FAILED, CANCELLED, TIMEOUT. Invalid values → 400.
agent_idstringFilter by agent.
triggerstringFilter by payload.trigger_type on the run.started entry (e.g. USER, WEBHOOK, CRON).
tagstringMatch a single tag inside payload.metadata.tags array on the run.started entry.
pageinteger1-based page index, default 1. Out-of-range values clamp to 1.
limitintegerPage size, 1-100, default 50. Out-of-range values fall back to the default.
Response: 200 OK
{
  "data": [
    {
      "id": "run_a1b2c3",
      "workspace_id": "ws_123",
      "agent_id": "agt_viktor",
      "agent_name": "Viktor",
      "agent_slug": "viktor",
      "crew_name": "Backend",
      "chat_id": "chat_xyz",
      "triggered_by": "user_42",
      "trigger_type": "USER",
      "status": "COMPLETED",
      "started_at": "2026-04-30T10:00:00Z",
      "finished_at": "2026-04-30T10:02:00Z",
      "error_message": null,
      "exit_code": 0,
      "metadata": {"tags": ["urgent", "compliance"]},
      "created_at": "2026-04-30T10:00:00Z"
    }
  ],
  "stats": {
    "running": 1,
    "today": 12,
    "failed": 2
  },
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 12,
    "total_pages": 1
  }
}
FieldTypeDescription
data[].idstringThe run’s trace_id.
data[].statusstringComputed from the terminal entry’s type. RUNNING when no terminal has landed.
data[].started_atstring?RFC3339 from run.started. Null only on a corrupt row that lost its starter.
data[].finished_atstring?RFC3339 from the terminal entry. Null while still running.
data[].error_messagestring?Pulled from terminal.payload.error_message. Null on success.
data[].exit_codeinteger?Pulled from terminal.payload.exit_code. Null while running.
data[].metadataobject?Pulled from started.payload.metadata. Free-shape per orchestrator.
data[].agent_name / agent_slugstring?Enriched from the agents table by the handler (one extra workspace-scoped SELECT per page).
data[].crew_namestring?Enriched via the agents.crew_idcrews.name join.
stats.runningintegerDistinct trace_ids with run.started and no terminal in the workspace.
stats.todayintegerDistinct trace_ids with run.started ts >= start-of-today UTC.
stats.failedintegerDistinct trace_ids with run.failed or run.timeout today.
Errors:
StatusCondition
400Invalid status value (must be one of the five enum values).
401No workspace context.
500DB error.

Tenancy

  • workspace_id is taken from the session context — never from a query parameter.
  • Cross-tenant trace IDs are filtered out at the journal store (journal.ListRuns requires a non-empty WorkspaceID).
  • 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.