API reference

HTTP API

Every alineod route — runs, agents, control actions, and results.

Base URL: http://localhost:4600 by default. Request bodies are JSON. Errors are returned as { "error": "<message>" } with an appropriate status; an invalid body is 400 and names each failing field. When the failure has a stable error code, the body also carries it as code ({ "error": "<message>", "code": "SANDBOX_NOT_RUNNING" }). Branch on code, not on the message text. A body without code means no code applies.

CodeStatusWhen
INVALID_ARGUMENT400The request body or a parameter failed validation.
AGENT_NOT_FOUND404No agent with that id.
RUN_NOT_FOUND404No run with that id.
AGENT_NOT_LIVE409The agent exists but is not live in this daemon (ended, released, or the daemon restarted).
AGENT_BUSY409The agent is still finishing its previous turn. Retryable.
CAPABILITY_UNSUPPORTED501The daemon setup lacks what the route needs, for example memory when it is disabled.

Sandbox and model failures use the codes in Error codes. The body also carries hint when the code has one.

MethodPathDescription
GET/healthLiveness check.
POST/runsCreate a run and its root agent.
GET/runs/:runIdThe run's spawn tree.
DELETE/runs/:runIdStop every live agent in the run.
GET/runs/:runId/eventsThe run's event stream (SSE).
POST/runs/:runId/agentsSpawn a child agent.
GET/agents/:agentIdOne agent's state and session stats.
POST/agents/:agentId/promptStart a new turn.
POST/agents/:agentId/steerRedirect the current turn.
POST/agents/:agentId/pauseFreeze the agent's container.
POST/agents/:agentId/resumeThaw a paused container.
POST/agents/:agentId/stopAbort and close the agent.
GET/agents/:agentId/resultGet, or wait for, the agent's result.
GET/agents/:agentId/transcriptWhat the agent said and did, turn by turn.
GET/agents/:agentId/awaitWait for the agent's subtree to finish.
POST/runs/:runId/awaitWait on a set of agents, or a subtree.
POST/agents/:agentId/notify-onTell this agent when others finish.
GET/agents/:agentId/inboxThis agent's pending and delivered notifications.
POST/agents/:agentId/inbox/deliverDeliver pending notifications now.
GET/agents/:agentId/memoryWorking memory — see Agent memory, which also covers PUT/DELETE .../memory/:key, .../facts and .../compactions.

Runs

POST /runs

Create a run with one root agent. Returns 202; the sandbox is provisioned in the background and prompt, if set, runs once it's ready.

FieldTypeDescription
specobjectAn agent spec, validated by the SDK. Required.
promptstringFirst turn to run on the root agent.
budget.spawnDepthintegerOverrides the spec's spawnDepth.
budget.maxAgentsintegerOverrides the spec's maxAgents.
closeWhenstring"explicit" (default) or "quiescent". With "quiescent" the run closes itself once every agent in it has ended and has nothing left to deliver.
// 202
{ "runId": "r_3f9a1c20", "rootAgentId": "a_7b2e44d1", "state": "provisioning" }

If provisioning fails, the root ends with outcome failed and the error appears on its agent.ended event.

GET /runs/:runId

The run's whole tree as a flat list with parent pointers. asOf is the highest ledger seq reflected in the response — pass it as Last-Event-ID to stream everything after this snapshot.

{
  "runId": "r_3f9a1c20",
  "rootAgentId": "a_7b2e44d1",
  "asOf": 42,
  "closeWhen": "explicit",
  "state": "open",
  "agents": [
    {
      "agentId": "a_7b2e44d1",
      "runId": "r_3f9a1c20",
      "parentAgentId": null,
      "depth": 0,
      "spawnIndex": 0,
      "state": "done",
      "specName": "coordinator",
      "sandboxId": "6a69afcb-7a00-437a-9819-e032022cc736",
      "createdAt": 1789000000000,
      "endedAt": 1789000071000,
      "outcome": "success"
    }
  ]
}

closeWhen is the run's close policy. state is open until the run is closed, by DELETE or by quiescence. 404 if the run doesn't exist.

DELETE /runs/:runId

Aborts and closes every live agent in the run, ending each with outcome aborted. The run's ledger is kept, so GET /runs/:runId and its event stream still work afterwards. Returns 204; 404 if the run doesn't exist.

GET /runs/:runId/events

A Server-Sent Events stream for the whole run. Send Last-Event-ID to replay persisted events after that seq. See Events.

Agents

POST /runs/:runId/agents

Spawn a child by forking a live parent's sandbox. Returns 202.

FieldTypeDescription
parentAgentIdstringA live agent in this run. Required.
specobjectThe child's agent spec. Required.
promptstringTurn to run once the child is ready.
waitForstring[] | objectAgents in this run whose results must settle before the child is forked. Their results are written to /inputs/. The object form adds mode, k, onDepFailure, deadlineSec and onDeadline; see Coordination.
notifyOnstring[]Agents to tell this child about when they finish, without blocking it. See Coordination.
budget.spawnDepthintegerOverrides the parent's remaining spawnDepth.
budget.maxAgentsintegerOverrides the parent's remaining maxAgents.
idempotencyKeystringA retry with the same key returns the original child instead of creating another.
// 202
{ "agentId": "a_c01d9e3a", "state": "provisioning" }

state is spawning when waitFor is set.

StatusWhen
400Invalid body, waitFor/notifyOn names an agent not in this run, or an invalid quorum k.
404parentAgentId isn't an agent in this run.
409The parent isn't live.

A spawn refused by a budget still returns 202; the child then ends with outcome budget-exceeded and a budget.denied event is emitted. See Fan-out and gather.

GET /agents/:agentId

The agent's view (same fields as an entry in GET /runs/:runId) plus sessionStats from the harness when available. sessionStats is omitted while the agent is paused, or if the harness doesn't answer within 2 seconds. 404 if the agent doesn't exist.

POST /agents/:agentId/prompt

{ "text": "Now write tests for the fix." }

Starts a new turn and returns 202 immediately; follow it on the event stream or via the result route. 409 if the agent isn't live. On a blocked agent this is the retry — see Supervision.

POST /agents/:agentId/steer

{ "message": "Focus only on src/auth." }

Delivers a steering message to the current turn — after its running tool calls finish, before the next model call. Returns 202 and emits agent.steered.

With "scope": "subtree", the agent gets one message: yours plus a list of its direct children, so it redirects them itself. Returns 200 with { deliveredAs: "steer" | "turn" | "queued", roster }. See Steering a subtree.

StatusWhen
404No such agent.
409The agent isn't live.
502The harness didn't accept the message.

See Steering and pausing.

POST /agents/:agentId/pause

Freezes the agent's container. Returns 202 and emits agent.state_changed (to: "paused", with pausedBy). A no-op if already paused. 404 if no such agent, 409 if not live, 502 if the sandbox couldn't be paused.

With { "scope": "subtree" }, pauses the agent and every descendant, parents first, and returns 200 with one result per member ({ asOf, results: [{ agentId, outcome: "applied" | "skipped" | "failed", reason? }] }).

POST /agents/:agentId/resume

Thaws a paused container and returns the agent to the state it had before the pause. Returns 202. 404 if no such agent, 409 if the agent isn't paused or isn't live, 502 if the sandbox couldn't be resumed. With { "scope": "subtree" }, resumes every paused member, children first, and returns the same per-member result.

POST /agents/:agentId/stop

{ "mode": "abort" }

Aborts the current turn, closes the sandbox, and ends the agent with outcome aborted. The body is optional; mode is abort (default) or drain, which currently behaves the same. Returns 202; 404 if no such agent.

Stopping an agent that already finished closes its sandbox and emits agent.released, keeping its outcome. With "scope": "subtree", stops every member, leaves first, and returns the per-member result.

Results

GET /agents/:agentId/result

QueryDescription
waitSeconds to hold the request open while the result is pending. Maximum 240. Default 0.

Settled — 200:

{
  "agentId": "a_e4b7d210",
  "state": "settled",
  "outcome": "success",
  "resultRef": "fs://a_e4b7d210/result.md",
  "result": "Three Landscapes\n\n..."
}

Still pending after wait — 202:

{ "agentId": "a_e4b7d210", "state": "pending", "outcome": null, "resultRef": null, "result": null }

404 if the agent doesn't exist. resultRef is null when a turn failed without producing any text.

GET /agents/:agentId/transcript

What the agent said and did, read from the ledger: one entry per finished turn, each with its messages.

QueryDescription
full1 to keep long text whole and include the model's thinking. Default: text over 2,000 characters is cut.
{
  "agentId": "a_e4b7d210",
  "turns": [
    {
      "seq": 41,
      "ts": 1789910400000,
      "messages": [
        { "role": "user", "text": "Run the judge." },
        {
          "role": "assistant",
          "text": "Running it.",
          "toolCalls": [{ "name": "bash", "arguments": { "command": "python3 evaluate.py" } }],
          "stopReason": "toolUse",
          "errorMessage": null
        },
        { "role": "tool", "toolName": "bash", "text": "val_bpc: 2.51", "isError": false }
      ]
    }
  ]
}

Use it to see why an agent did what it did, including a model API error (stopReason: "error" with the provider's errorMessage). A turn appears once it ends, so an agent mid-turn shows its earlier turns only. 404 if the agent doesn't exist.

Coordination

See Coordination for how these fit together.

GET /agents/:agentId/await

QueryDescription
scopesubtree (the only value, and the default).
waitSeconds to hold the request until the subtree is quiescent. Maximum 240.

Returns { rootAgentId, quiescent, asOf, members, blockedOnPaused }. 404 if the agent doesn't exist.

POST /runs/:runId/await

{ "agents": ["a_c01d9e3a", "a_5e8f2b71"], "mode": "any", "wait": 60 }

Or { "subtree": "<agentId>", "wait": 60 }. Waits with the same modes as waitFor, but spawns nothing. Returns { outcome: "satisfied" | "partial" | "depfail" | "pending", selected, settled, pending }. 400 for an invalid body (neither or both of agents / subtree, an invalid k, or an agent not in this run).

POST /agents/:agentId/notify-on

{ "agents": ["a_c01d9e3a"], "wake": false }

Subscribes this agent to be told when each listed agent finishes. wake: true starts a new turn if it's idle when a notification arrives. Agents that already finished notify at once. 400 for an unknown agent or self-subscription, 404 if this agent doesn't exist.

GET /agents/:agentId/inbox

{ agentId, pending: [...], delivered: [...] }. Each item has seq, kind (notification or steer), aboutAgentId, outcome, resultRef, excerpt, again, state and deliveredAs.

POST /agents/:agentId/inbox/deliver

Delivers whatever is pending now, starting a new turn if the agent is idle. Returns { delivery: "steer" | "turn" | "held" | "dropped" | "none" }.