Skip to main content
A session is the durable unit of an agent at work: an append-only event log, the pinned agent snapshot, and a lifecycle status. Compute attaches to it, detaches when idle, and reattaches on the next message — the log is what persists.

How a session works

  1. You create a session from an agent (and an Anthropic credential — both required). The session starts immediately.
  2. The runtime executes the agent in a sandbox, appending events to the log as it works.
  3. With nothing left to do, the session goes idle and the sandbox hibernates (see durability).
  4. A steer message wakes it; it resumes with its prior context. Repeat.
The runtime is managed and self-healing: if it crashes we restart it and it continues from its on-box state; if it hangs, a turn deadline ends the turn and you steer to continue; an idle session survives even if its sandbox is reclaimed. In-flight work since the last logged event may repeat, so make side effects idempotent. Details: durability.

Lifecycle

StatusMeaning
queuedScheduled; a turn hasn’t started running yet.
runningA turn is executing.
awaiting_inputA turn ended asking you a question — steerable; reply to continue.
idleDone for now; quiescent and steerable; the sandbox is hibernated.
failedThe session errored out.
archivedClosed; read-only.
A session also carries last_turn = { id, state, yield_reason?, result_event_id? } and usage; the fuller turn record (started_at, completed_at, error, active_seconds, usage) comes from GET …/result and …/turns. The yield_reason tells you why the last turn ended — completed, needs_input (the agent asked a question — the session is now awaiting_input; answer by steering), budget_exceeded / deadline_exceeded / max_turns (a limit tripped), or canceled.

Get the result

Don’t sniff prose for “is it done.” Await the turn.completed event (on the stream or a webhook), then fetch the answer:
curl https://api.opencomputer.dev/v3/sessions/$ID/result \
  -H "Authorization: Bearer $OPENCOMPUTER_API_KEY"
# → { "last_turn": { "id": "trn_…", "state": "ok", "yield_reason": "completed", "result_event_id": "evt_…" },
#     "result": { "type": "agent.message", "level": "user", "body": { "text": "…" } } }

Limits

Cap a session at create (or default it on the agent) with limits: { tokens, turn_seconds, turns } — a token budget, per-turn wall-clock, and auto-run count. These are non-monetary (no dollar caps — we don’t bill model usage yet; you run on your own key). Hitting one ends the turn with the matching yield_reason. (usage is observed-only.)

Stop a session

POST /sessions/:id/cancel requests a cooperative stop: the turn ends at its next checkpoint with a turn.completed (yield_reason: "canceled"), so an in-flight model call may run to its timeout — billing for that turn stops when it actually exits, not the instant you call. POST /sessions/:id/archive cancels any active turn, then closes the session read-only. archive is not delete — the session’s log is retained, just read-only. Hard delete (DELETE /sessions/:id) and export are coming soon.
Blocking on input mid-turn (the formal ask loop) is coming soon. Today the agent signals it needs input by ending the turn with yield_reason: "needs_input" (status awaiting_input); you reply by steering.
No cross-session memory (yet). Each session starts fresh from the agent’s prompt + that session’s input — a durable log is session history, not memory the agent carries between sessions. A dedicated memory surface is on the roadmap.