The /api/v1 surface lets external systems drive KB-grounded agents over authenticated HTTP. It exposes the same durable harness the UI uses. All requests carry a Bearer key — see Authentication. Base URL is your host, e.g. https://your-host/api/v1.
Start a run
Runs are identified by the agent's slug. The default request persists a queued run as the durable handoff record, attempts to send worker work, and immediately returns HTTP 202 with the run id and reattachment URL. If that broker send is interrupted, the worker reconstructs the pinned start from the row at boot or during its minute reconciliation loop.
POST/api/v1/agents/:slug/runsBearer · agents:run
Start a run of the named agent.
Request body
inputrequired
string
The task or question (min length 1).
conversationId
string
Continue an existing conversation for multi-turn context.
Example requestbash
curl -X POST https://your-host/api/v1/agents/budget-analyst/runs \ -H "Authorization: Bearer $ELI_KEY" \ -H "Content-Type: application/json" \ -d '{"input":"What changed in the FY26 budget?"}'
Reattach from any web replica with GET /api/v1/runs/:id/stream. It replays persisted steps, tails the database, and closes on a terminal state; reconnecting does not restart the run.
GET/api/v1/runs/:id/streamBearer · runs:read
Replay and tail a durable run as Server-Sent Events.
data: {"type":"model_call","runId":"01J…","textLength":0,"toolCalls":1}data: {"type":"tool_call","runId":"01J…","name":"kb_search","ok":true}data: {"type":"final","runId":"01J…","status":"succeeded","text":"…","citations":[{"docId":"01J…","chunkId":"01J…"}]}# terminal event is one of:# {"type":"final","runId,status,text,citations}# {"type":"suspended","runId","approvalId","toolName"}# {"type":"error","message":"…"} e.g. "no-model-configured"
Inline compatibility mode
POST /api/v1/agents/:slug/runs?stream=inline retains the legacy in-request SSE mode for compatible clients. It still passes monthly spend and concurrency admission, but the queued 202 + reattachment path is the durable default.
Terminal statuses
queued · running · succeeded · failed · budget_exceeded (graceful stop; text holds the partial answer) · interrupted · suspended (awaiting a HITL decision — resolve with /approve). Setup failures are persisted on the run and appear as an error event during reattachment.
Read a run
GET/api/v1/runs/:idBearer · runs:read
Fetch a run and its full ordered step trace. A run in another workspace is invisible under RLS → 404.
Cooperatively cancel a running run. Worker runs poll a DB cancel-flag between steps.
Example requestbash
curl -X POST https://your-host/api/v1/runs/$RUN_ID/cancel \ -H "Authorization: Bearer $ELI_KEY"
Responsejson
{ "cancelled": true }
Resolve an approval
When a run is suspended, record the human decision. The transition from pending approval to queued continuation is atomic and idempotently reconciled to pg-boss; continue reading the same reattachment stream.
POST/api/v1/runs/:id/approveBearer · agents:run
Resolve a suspended HITL approval and queue its durable worker continuation.
Request body
approvalIdrequired
string
The approval to resolve (from the suspended event).
decisionrequired
"allow" | "deny"
Allow executes the tool; deny returns an error result to the model.
All endpoints share the conventions in Errors & rate limits: 401 for a bad key, 403 for a missing scope, 404 for an unknown/other-workspace run, 400 for an invalid body, 402 when the monthly spend cap denies admission, and 429 when the active-run cap is full.