https://api.opencomputer.dev/v3. Management calls authenticate with your org API key; stream and steer also accept a client token.
Sessions
| Method · Path | Purpose |
|---|---|
POST /sessions | Start a session. Body: agent (required), input, key?, webhook?, destinations?[], limits?: { tokens?, turn_seconds?, turns? }. Returns { session, client_token }. |
GET /sessions/:id | Fetch a session. |
GET /sessions?status=&agent=&key=&after=&before=&limit= | List sessions (filtered, paginated). |
POST /sessions/:id/archive | Cancel any active turn, then close (read-only). |
POST /sessions/:id/cancel | Cooperatively stop the active turn (no-op if not running). |
GET /sessions/:id/result | The result helper — { last_turn, result? } (the resolved final event). |
GET /sessions/:id/turns · GET …/turns/:turnId | Per-turn history: timing, usage, error. |
POST /sessions/:id/client-tokens | Mint a client token. Body: scopes? (subset of read, steer), ttl? (seconds; clamped to 60–86400). |
agent is required (create a saved agent first); a resolvable Anthropic credential is also required (422 no_credential otherwise). key gives get-or-create (one session per key); a request-level Idempotency-Key header makes a keyless create retry-safe. input is the task — a string or a full envelope (structured context rides input.refs: repo/branch/commit/issue/…). limits { tokens, turn_seconds, turns } are non-monetary — token budget, per-turn wall-clock, auto-run count; hitting one ends the turn with a matching last_turn.yield_reason. Destinations on an idempotent create-replay are ignored — manage them via the destinations API.
yield_reason (completed | needs_input | error | budget_exceeded | deadline_exceeded | max_turns | canceled; requires_action is reserved, not emitted yet) is the machine-readable “why the turn ended” — needs_input means the agent asked a question; answer it by steering.
Events
| Method · Path | Purpose |
|---|---|
GET /sessions/:id/events?after=<seq>&level=<lvl>&type=&turn_id=&limit=<n> | Read events since a cursor (filter by type exact or prefix.*, or turn_id). |
GET /sessions/:id/events?after=<seq>&level=<lvl>&stream=sse | Live SSE stream from a cursor. |
GET /sessions/:id/events/:eventId | Fetch one event (resolve result_event_id). |
GET /sessions/:id/events/:eventId/content | Fetch a blob-backed body (large outputs). |
GET /sessions/:id/messages?after=<seq>&limit=<n> | User-message history (alias for level=user + type=*.message). |
after resumes from a seq; level is a visibility threshold — user returns only user-facing events, progress adds work updates, internal adds everything (see levels). Omitting level defaults to internal (you get everything). Switch on type, don’t parse prose.
Steer
| Method · Path | Purpose |
|---|---|
POST /sessions/:id/messages | Append an input message; wakes the session. Body: { text, idempotency_key? } or { envelope }. 202 (or 200 on an idempotent replay) → { event: { id, seq }, session: { id, status, head } }. |
Destinations
| Method · Path | Purpose |
|---|---|
POST /sessions/:id/destinations | Register a webhook. Body: url, secret?, level? (user), types?[] (event-type filter; exact or prefix.*), include_raw? (false), enabled? (true). |
GET /sessions/:id/destinations · GET …/:did | List / fetch. |
PATCH /sessions/:id/destinations/:did | Pause/resume (enabled), retune level/types, rotate secret. |
DELETE /sessions/:id/destinations/:did | Remove. |
Deliveries
| Method · Path | Purpose |
|---|---|
GET /sessions/:id/deliveries?destination=&status= | List deliveries — status, attempts, last response/error. |
GET /sessions/:id/deliveries/:id | One delivery, in detail. |
POST /sessions/:id/deliveries/:id/redeliver | Re-send any delivery (not just dead-lettered). |
Agents
| Method · Path | Purpose |
|---|---|
POST /agents | Create a reusable agent. Body: name, prompt, model, runtime? (claude), key? (Anthropic key — creates + attaches a credential), credential? (reference an existing one), limits?: { tokens?, turn_seconds?, turns? }. Idempotent by (owner, name). |
GET /agents/:id · GET /agents | Fetch / list. |
PATCH /agents/:id | Update prompt? / model? / key? (rotate) / credential? / limits?. Never affects existing sessions (snapshots are pinned). |
key or credential (or neither → org default). The agent’s limits are the defaults for its sessions; a session’s own limits override. Each agent has a monotonic revision (bumped on PATCH) that sessions pin in agent_snapshot.revision, so you can tell which version produced a run.
Credentials
| Method · Path | Purpose |
|---|---|
POST /credentials | Add a provider key (Anthropic). Body: provider, key, name?, is_default?. Key is write-only. Required — sessions run on your key (no platform billing yet). |
GET /credentials · DELETE /credentials/:id | List / remove. |
PUT /credentials/default | Set the org default to a credential (its provider is derived). Body: credential. |
Errors & rate limits
Errors use one envelope:{ "error": { "type", "message" } }. Cross-owner resources return 404 (not 403). Rate and concurrency limits are not enforced at launch (a 429 with a Retry-After header may be introduced later).