Session Lifecycle
processing → canceling → idle
Cancelling a running Session transitions through
canceling and then back to idle. The Session remains reusable.| State | Description | Transitions to |
|---|---|---|
idle | Idle, awaiting a user message | processing |
processing | The Agent is executing | canceling, idle |
canceling | Cancel requested, waiting for the turn to abort | idle |
archived | Archived | — (terminal) |
Field Reference
| Field | Type | Description |
|---|---|---|
id | string | System-generated, prefixed with sess_ |
type | string | Always "session" |
agent | string/object | Bound Agent. String = latest version; object {id, version} = pinned version. Creation requests only accept this field. The response always returns the full Agent object snapshot |
agent_id | string | Returned in responses only, always equals the bound Agent ID; kept for backward compatibility |
environment_id | string | The bound Environment ID |
status | string | Current state: idle / processing / canceling |
turn_status | string | Current turn status: idle / running / canceling |
title | string | Optional Session title; defaults to "" |
memory_store_ids | array | Memory Store IDs referenced; defaults to [] |
vault_ids | array | Vault IDs referenced; defaults to [] |
resources | array | Resources attached to the Session (files etc.); defaults to [] |
created_at | string | Creation timestamp |
updated_at | string | Last update timestamp |
Token usage data (
usage) is not returned by REST endpoints — it is only emitted in the SSE session.status_idle event at the end of each turn.Create a Session
A Session needs bothagent and environment_id.
Option 1: Pass an Agent ID (string)
Binds the latest version of the Agent:Option 2: Pass an Agent Object (pin a version)
Binds a specific version of the Agent for behavioral consistency:In production, prefer Option 2 (pinned version) so Agent updates do not change Session behavior unexpectedly.
agent Field Format
| Format | Example | Behavior |
|---|---|---|
| String | "agent_019e5ce0bf307a1a8f952eb814aea3d5" | Uses the latest version of the Agent |
| Object | {"id": "agent_019e5ce0bf307a1a8f952eb814aea3d5", "version": 2} | Pins to the specified version |
State Transitions
Event request body format
POST /sessions/{id}/events requests must wrap events in an events array, and content is an array of content blocks:
| Field | Type | Required | Description |
|---|---|---|---|
events | array | Yes | Event array — one or more events per request |
events[].type | string | Yes | Event type, e.g. user.message |
events[].content | array | Yes | Content block array |
events[].content[].type | string | Yes | Content block type, e.g. text |
events[].content[].text | string | Yes | Text content |
idle → processing
Sending a user.message event moves the Session from idle to processing:
processing → idle
When the Agent finishes a turn the Session returns to idle. You will receive a session.status_idle event on the stream.
Cancel a Session
Interrupt a running Session:Cancel only actually interrupts the Agent when the Session is
processing. The Session moves to canceling, then back to idle once the turn aborts. The Session remains reusable — just send the next user.message. Cancelling an already-idle Session is a no-op: the call still returns 200 and the status stays idle.Read Sessions
Usage Stats
Per-turn token usage is not returned by REST endpoints. To inspect token usage, listen for the SSEsession.status_idle event at the end of each turn — the usage field carries cumulative counters:
| Field | Description |
|---|---|
usage.input_tokens | Input tokens consumed by the turn |
usage.output_tokens | Output tokens produced by the turn |
usage.cache_read_input_tokens | Input tokens served from cache |
usage.cache_creation_input_tokens | Input tokens written into cache |
Session and Agent Version Binding
A Session snapshots its Agent configuration at creation time:- The string form
"agent": "agent_xxx"binds the latest version at creation time. - The object form
"agent": {"id": "agent_xxx", "version": N}pins to an exact version. - Once a Session exists, modifying the Agent does not change the Session.
- To use a new Agent version, create a new Session.
Session A — bound to Agent v1
Created before the update. Continues to use v1 even after the Agent has been updated to v2.
Session B — bound to Agent v2
Created after the update. Uses the new v2 configuration.
Multi-Turn Conversations
Sessions support multi-turn conversations. After each message, wait forsession.status_idle before sending the next:
State-Related Errors
Common state-related errors when sending events to a Session:| HTTP | Type | Trigger |
|---|---|---|
| 409 | conflict_error | Sending a message to a processing Session (cancel the current turn or wait for idle first) |
| 404 | not_found_error | Session does not exist or has been deleted |
Best Practices
- Pin versions — always create production Sessions with
{"id": ..., "version": ...}. - Cancel promptly — cancel Sessions you no longer need to free resources.
- Watch usage — review
usageperiodically to catch unexpected token spend. - Use metadata — record business context (task ID, trigger source) in
metadata.
FAQ
Q: Do Sessions time out? A: Sessions stayidle for a while; long-inactive Sessions may be archived automatically. Create Sessions on demand and cancel them when work completes.
Q: What happens if I send a message to a processing Session?
A: The request returns HTTP 409 conflict_error with the message Session is currently processing a turn. Cancel the current turn or wait for completion. Either cancel the current turn or wait until the Session returns to idle before sending the next message.
Q: Is there a maximum number of turns per Session?
A: There is no hard limit on turns, but the model context window applies. Older content may be truncated as the conversation grows.
Q: How do I retrieve the full conversation history?
A: Use GET /sessions/{id}/events to fetch every event for the Session, including user messages and Agent responses.
Q: Can I keep using a Session after I cancel it?
A: Yes. After cancel, the status moves from canceling back to idle and the Session is ready for the next user.message. Only archived is terminal — archived Sessions cannot be resumed.
Q: Are files on the container disk preserved if a Session is idle for a long time?
A: Not necessarily. Container temporary storage is retained for 24 hours only; after that the disk may be reclaimed. The Session itself remains usable and you can continue the conversation, but files previously produced on disk (cloned code, intermediate artifacts, etc.) will be lost. To persist files across days, upload critical artifacts via the Files API at the end of each turn. See Container Reference — File Persistence for details.
Next Steps
- Overview — review the Cloud Agents architecture.
- Quickstart — full end-to-end example.
- Defining an Agent — Agent configuration in depth.
- Cloud Environments — customize the runtime.