Skip to content
Subako Docs
Esc
navigateopen⌘Jpreview
On this page

Sessions and runs

A session is an append-only event log. A run is one pass of the engine over it. Everything you can observe about an agent is an event.

A session is one unit of work: a conversation, a ticket, a background job. It belongs to a workspace, binds an agent version at creation, and holds an append-only log of everything that happened.

A run is one pass of the engine over that log. Appending user input starts a run; the run appends its own events as it goes and ends in exactly one terminal event.

The distinction matters because a session outlives its runs. A run can fail, be cancelled, or lose the connection you were watching it on, and the session is still there with its log intact.

Creating a session

{
  "agent_id": "…",
  "display_name": "ticket-4192",
  "vault_ids": ["…"]
}
PropType
agent_iduuid

The agent to run. Its newest live version is bound now and never re-bound.

Typeuuid
display_name?string

A human label, up to 200 characters. Empty when omitted.

Typestring
vault_ids?uuid[]

Vaults this session may draw tool credentials from — up to 10, each a live vault in the same workspace.

Typeuuid[]

The response carries the session and its first session token, shown once.

Two credentials, two jobs

API key Session token
Scope A workspace One session
Carries The permissions it was minted with No permissions at all
Lives On your server Wherever you need it — a browser tab, a worker
Expires When you revoke it, or at expires_at At session_token_expires_at

A session token can read its own session, append input to it, and register clients on it. It cannot list sessions, create one, or touch anything else in the workspace — so handing one to a front end gives that front end exactly one session and nothing more.

Mint more of them as you need them:

POST /v1/sessions/{session_id}/tokens

The event log

Every event carries a sequence number, and the log is the whole truth about a session. Runs are events, messages are events, tool calls and their results are events, a client joining is an event.

GET  /v1/sessions/{session_id}/events          # paged, newest first by default
GET  /v1/sessions/{session_id}/events/stream   # SSE, tail and resume
POST /v1/sessions/{session_id}/events          # append user input, starting a run
POST /v1/sessions/{session_id}/cancel          # ask the current run to stop

See Streaming events for the tailing and resumption rules, and the event reference for every kind.

What a run touches

When a run is claimed, the engine is handed three things, all scoped to that run alone:

The committed log

The engine rebuilds its state from the events already stored, so a run that follows a failed one starts from what actually happened, not from what the previous attempt thought was happening.

A model proxy binding

A URL and a run token, minted fresh at claim time. Your provider key is never handed to the engine — the proxy holds it. A stale attempt’s token stops working the moment the run is re-claimed.

A tool broker binding

A URL, a run token, and the list of server names the bound version grants. Never credentials, never upstream URLs, never policy — the broker resolves all three itself when a call arrives.

Terminal states

Event What it means
run_completed The model finished its turn with nothing left to do.
run_failed The run stopped on an error; error carries the text.
run_cancelled A cancel request was honored.

A session with no run in flight is idle, not finished. Append more input and a new run starts against the same log.

Was this page helpful?