Skip to content
Open Console

Sessions and runs

4 min readUpdated

A session is the continuity boundary for one enabled agent version: its workspace, files, and interactions. A run is one admitted unit of execution inside it. Keep both IDs: the session tells you where state lives; the run tells you what happened during one request.

One reusable sessionOne active run at a time
  1. SessionreadyAccepts work
  2. Run 1runningFirst request
  3. InteractionpendingRun 1 waits
  4. Run 1succeededTerminal
  5. SessionidleReusable
  6. Run 2runningLater request
  7. Run 2failedTerminal
  8. SessionidleCan run again

Session ready → Run 1 running → interaction pending (awaiting_input: true) → Run 1 succeeded → session idle → Run 2 running → Run 2 failed → session idle.

Run 2 starts only after Run 1 is terminal; the failed second run does not erase the first or end the session.

Choose When it fits Tradeoff
One-shot invocation One independent request where immediate streaming is the main goal. Tanomis creates a session and run and returns their IDs in X-Session-ID and X-Run-ID, but retrying the request creates a new session boundary.
Explicit session Retries, multiple runs, durable interaction, files, or reconnecting to events matter. Two requests to begin: create the session, then start the run.

One-shot still creates durable resources; record the IDs it returns. For anything your product depends on, create the session explicitly.

Session status describes whether the continuity boundary can accept or continue work:

Session status Meaning
creating Tanomis is provisioning the session.
ready The session is prepared and can accept a run.
running A run is active.
idle No run is active; the session can be reused.
stopping Stop is fencing new work and releasing the active runtime.
stopped The session was explicitly stopped and must be resumed before another run.
failed Session activation or runtime failed; explicit resume can attempt recovery.
expired The session reached its lifecycle limit; explicit resume can reactivate it.

Run status describes one execution attempt:

Run status Meaning
queued Admitted and waiting for dispatch.
running Executing or waiting on a durable human interaction.
succeeded Completed successfully.
failed Ended with an error; inspect error_code and error_message when present.
cancelled Ended after cancellation.

succeeded, failed, and cancelled are terminal. A terminal run stays readable through the run resource, and the session returns to idle for the next run.

One session admits at most one active run, where active means queued or running. Starting another run while one is active returns 409 Conflict. Wait for a terminal state, use another session for independent concurrency, or retry the same run idempotently. Terminal runs do not hold the slot, so a reused session is an ordered history:

session A
run 1: succeeded
run 2: failed
run 3: running

Files and durable interactions belong to the session. Attachments select session files for one run; they do not move the files anywhere.

Use a stable idempotency key for one logical operation and never recycle it for new intent. Keys are opaque, at most 255 bytes, and scoped differently at each boundary:

Operation Same key Changed intent or no key
Create session For the same authenticated caller, tenant, and provisioning inputs, returns the original non-terminal session with 200 OK. Changed provisioning inputs return 409 Conflict. Reusing the key after the original session is stopped, failed, or expired returns 412 Precondition Failed. Omitting the key creates a new session.
Start run Within the same session, returns the original active or terminal run; a JSON replay is 200 OK, while a streaming replay follows the original event stream. Changed input, model, or work does not replace the original run, so bind the key to one immutable request in your client. Attachment-set drift returns 409 Conflict. A new or absent key starts a new run only when no run is active; otherwise it returns 409 Conflict.

The run key is scoped to the session; the same string in another session refers to nothing. A one-shot retry creates another session first, so a run key in its body cannot make the whole one-shot operation retry-safe.

Resource reads are authoritative. A stream close, command exit, or accepted cancellation does not replace them.

Action Request Then
Read GET /v1/sessions/{session_id} and GET /v1/sessions/{session_id}/runs/{run_id} Use the run’s status; the session read carries awaiting_input.
Cancel POST /v1/sessions/{session_id}/runs/{run_id}/cancel Read the run until it is terminal. The session’s history is untouched.
Stop POST /v1/sessions/{session_id}/stop Stop fences new runs and settles active work before stopped. A conflict during admission means the boundary is still settling: inspect and retry.
Resume POST /v1/sessions/{session_id}/resume Resume only a stopped, failed, or expired session. It keeps the session ID and pinned version and returns to ready; on a live session it conflicts.

Availability: Durable interactions are on in hosted Tanomis and operator-enabled when self-hosted. See What is available where.

A pending interaction adds no run status. The run remains running; a session read exposes the derived signal awaiting_input: true. List the session’s pending interactions, answer by the stable interaction_key, and keep observing the same run. Tanomis may suspend and restore the runtime while it waits without changing the public model. The full first-answer-wins flow is in Approval-required actions.

A run may instead bind to durable settlement work that can continue from a later session; see Durable work and settlement.

A later run continues the same session. It is not a fork and it is not a delegated session; those create separate lineage and authority and have their own guides.