Sessions
Create, manage, and observe sessions in Orca Agent Engine - the running instances of an agent inside an environment.
A Session is a running instance of an agent. Sessions are created in two steps: first you create the session itself, which records the agent, the environment, and the resources to mount; then you send events that drive the agent to act. Creating a session provisions nothing - it starts idle with no container and no start time. The sandbox is acquired when the first event is dispatched, so until you send one, the session exists only as a row.
Get your registry endpoint
Registry endpoint
Examples on this page target your registry endpoint - the deployment host root, with no path
suffix. For CLI, set ORCA_REGISTRY_URL and exactly one of ORCA_ACCESS_TOKEN (Bearer) or
ORCA_API_KEY (x-api-key). For TypeScript SDK, set ORCA_BASE_URL / ORCA_API_KEY (Bearer).
To find the endpoint, see Connect to the registry.
Create a session
Create a session by POSTing a CreateSessionRequest to /v1/sessions. Sessions are a top-level resource: the agent is named in the request body, not in the path.
Two fields are required:
agent- the agent that runs the session. Pass anagt_ID as a bare string, or an object for more control (see Pinning an agent version).environment_id- the environment the session's container runs in. Omitting it returns400withenvironment_id is required; there is no default.
Everything else - title, metadata, vault_ids, resources, and initial_events - is optional.
$AGENT_ID / agentId below is the id of an agent, and $ENVIRONMENT_ID / environmentId the id of an environment. Each example then captures the new session's id as $SESSION_ID / sessionId.
session=$(ork agent sessions create \
--agent "$AGENT_ID" \
--environment-id "$ENVIRONMENT_ID" \
--title "ticket #4821" \
--metadata channel=web \
-o json)
SESSION_ID=$(jq -r '.id' <<< "$session")A successful create returns 200 OK with the new session:
{
"id": "ses_01H8...",
"type": "session",
"agent": { "id": "agt_01H8...", "type": "agent", "version": 1, "name": "support-triage" },
"environment_id": "env_01H8...",
"vault_ids": [],
"status": "idle",
"title": "ticket #4821",
"stats": { "active_seconds": 0.0, "duration_seconds": 0.0 },
"usage": { "input_tokens": 0, "output_tokens": 0 },
"resources": [],
"metadata": { "channel": "web" },
"created_at": "2026-05-11T17:24:08Z",
"updated_at": "2026-05-11T17:24:08Z"
}Choose model egress for this session
For a harness in separate mode, set metadata.orca_llm_egress to gateway or direct to
override the deployment's LLM_EGRESS_DEFAULT setting. The default is direct unless the operator
changes it. Gateway egress requires the registry and LLM_GATEWAY_URL to be configured in the
harness. A colocated Cloud harness always uses gateway egress, regardless of this metadata.
Other values return 400. See Use the gateway with Agent Engine.
Pinning an agent version
The agent field accepts three shapes:
| Shape | Behavior |
|---|---|
"agt_01H8..." | Bare ID. The session uses the agent's latest version at the moment of creation. |
{ "type": "agent", "id": "agt_01H8...", "version": 2 } | Pins the session to one version. Omit version to take the latest. |
{ "type": "agent_with_overrides", "id": "agt_01H8...", ... } | Pins a version and overrides parts of the agent for this session only. |
session=$(curl -fsS "$ORCA_REGISTRY_URL/v1/sessions" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg agent "$AGENT_ID" --arg env "$ENVIRONMENT_ID" '{
agent: { type: "agent", id: $agent, version: 2 },
environment_id: $env
}')")
SESSION_ID=$(jq -r '.id' <<< "$session")The session retains that version for its entire lifetime even if the underlying agent is updated.
Overriding an agent for one session
agent_with_overrides lets one session diverge from the published agent without creating a new agent version. It accepts model, system, tools, mcp_servers, and skills, each replacing the pinned version's value in full. The same limits apply as on the agent: at most 128 tools and 20 MCP servers. It also accepts guardrail_ids, which adds guardrails to the agent's own rather than replacing them.
session=$(curl -fsS "$ORCA_REGISTRY_URL/v1/sessions" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg agent "$AGENT_ID" --arg env "$ENVIRONMENT_ID" '{
agent: {
type: "agent_with_overrides",
id: $agent,
version: 2,
system: "You triage support tickets for the EU region only."
},
environment_id: $env
}')")
SESSION_ID=$(jq -r '.id' <<< "$session")MCP authentication via vaults
If the agent calls MCP servers that require per-user credentials, reference one or more vaults when creating the session. The runtime injects the vault's credentials into MCP requests on the agent's behalf.
session=$(curl -fsS "$ORCA_REGISTRY_URL/v1/sessions" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg agent "$AGENT_ID" --arg env "$ENVIRONMENT_ID" --arg vault "$VAULT_ID" '{
agent: $agent,
environment_id: $env,
vault_ids: [$vault]
}')")
SESSION_ID=$(jq -r '.id' <<< "$session")$VAULT_ID is the id of a vault you created earlier.
A vault has to belong to the same Workspace and not be archived - that is the whole check - and vault_ids is fixed at creation, so it cannot be changed later. See Vaults for how to create vaults and add credentials.
Start the session
A session does not start the agent until you send it an event. Send a user.message event to drive the agent's first turn. content is an array of content blocks, not a string.
curl -fsS "$ORCA_REGISTRY_URL/v1/sessions/$SESSION_ID/events" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"type": "user.message",
"content": [{ "type": "text", "text": "Triage this ticket: customer cannot log in." }]
}
]
}'To create the session and start it in the same call, pass the events as initial_events instead. It takes up to 50 events, each a user.message or a user.define_outcome. No other event type is accepted at creation time:
session=$(curl -fsS "$ORCA_REGISTRY_URL/v1/sessions" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg agent "$AGENT_ID" --arg env "$ENVIRONMENT_ID" '{
agent: $agent,
environment_id: $env,
initial_events: [
{
type: "user.message",
content: [{ type: "text", text: "Triage this ticket: customer cannot log in." }]
}
]
}')")
SESSION_ID=$(jq -r '.id' <<< "$session")The session comes back already running. The CLI takes the same events through --initial-event-json, which is repeatable:
session=$(ork agent sessions create \
--agent "$AGENT_ID" \
--environment-id "$ENVIRONMENT_ID" \
--initial-event-json '{"type":"user.message","content":[{"type":"text","text":"Triage this ticket: customer cannot log in."}]}' \
-o json)
SESSION_ID=$(jq -r '.id' <<< "$session")Open the event stream to receive the agent's response as it runs.
Session statuses
The registry exposes the session status field returned by the agent provider. The status reflects the runtime state of the session and updates as events flow through.
| Status | Description |
|---|---|
idle | Waiting for input. New sessions start here, and return here when a turn ends. |
running | The agent is executing a turn. |
rescheduling | Declared for Anthropic compatibility, but no session record enters this state. The default harness emits a separate session.status_rescheduled event while it retries a transient provider failure. |
terminated | A thread that was explicitly archived. Threads only, and not an error state. The session.thread_status_terminated event retains stop_reason: "archived" only with orca-beta; the default response omits it. |
Inspect the session at GET /v1/sessions/{sessionId} to check the current value.
A session's own status is only ever idle or running. Those are the only two values the
runtime writes to a session, and a failed run is left idle and resumable rather than marked - so
no status means "this failed". Look for a session.error event instead. terminated describes a
thread that was archived, read from
GET /v1/sessions/{sessionId}/threads; rescheduling is a compatibility value for the session
record, distinct from the retry event of the same name. The statuses query parameter on the list endpoint accepts
all four names, so filtering sessions by terminated returns 200 with an empty data array
rather than an error. Archiving a session does not change its status either; it sets
archived_at.
Session resources
A session's resources array holds everything mounted into its container. Pass resources at creation time, or manage them afterward through the session's resources sub-resource. Three types are supported:
type | Required fields | Description |
|---|---|---|
file | file_id | Mounts an uploaded file. |
memory_store | memory_store_id | Mounts a memory store as a directory. |
github_repository | url, authorization_token | Clones a GitHub repository. checkout is accepted but not reliably applied - see the caveat on Repositories. |
All three also accept an optional access mode of read_only or read_write and instructions (up to 4096 characters). instructions is stored and returned but never reaches the agent - nothing in the harness reads it - so put anything the agent needs to know about a resource in the system prompt or a user.message instead. Only file and github_repository take a mount_path. A memory store's mount path is server-derived: it comes back on the resource but is rejected on the way in, and an update that sets it returns 400 memory_store mount_path is output-only and cannot be updated.
$MEMORY_STORE_ID / memoryStoreId below is the id of a store you created earlier.
ork agent sessions resources list --session "$SESSION_ID"
ork agent sessions resources add \
--session "$SESSION_ID" \
--type memory-store \
--memory-store-id "$MEMORY_STORE_ID" \
--access read_writeUpdating a resource accepts authorization_token, mount_path, access, instructions, and
mount_strategy. The token is rotated; the other four are written to the resource. Not every field
applies to every type - a memory_store's mount_path is output-only and returns
400 memory_store mount_path is output-only and cannot be updated. To change anything not in that
list, remove the resource and add it again.
The published OpenAPI specification is behind the running route here: it declares
authorization_token as the only accepted property. A client generated from that spec will not
expose the other four fields even though the endpoint accepts them.
Session threads
A session has one primary thread plus zero or more child threads. On the default Claude Managed Agents wire format, threads are produced by the coordinator as the session runs - there is no endpoint that creates one, and clients cannot spawn them. A multiagent coordinator delegating work to a sub-agent is what causes a child thread to appear.
orca-beta exposes legacy thread controls. A client event with a nonempty subpath creates or targets a child thread, and session_thread_id targets a control event at an existing thread. Those fields and the full transcript envelope are Orca extensions, not part of the default Claude Managed Agents event contract.
Each thread carries its own status, stats, usage, and the agent configuration it ran with:
| Field | Description |
|---|---|
id | Thread identifier, prefixed sth_. |
session_id | The session the thread belongs to. |
parent_thread_id | The thread that spawned this one, or null for the primary thread. |
agent | The agent configuration the thread ran with. |
status | running, idle, rescheduling, or terminated. |
stats, usage | Per-thread timing and token accounting. May be null. |
Threads are read-only apart from archive. You can list them, retrieve one, archive one, and read or stream its events. $THREAD_ID / threadId is an sth_ ID taken from the thread list:
threads=$(ork agent sessions threads list --session "$SESSION_ID" -o json)
THREAD_ID=$(jq -r '.data[0].id' <<< "$threads")
ork agent sessions threads events list \
--session "$SESSION_ID" \
--thread "$THREAD_ID"Manage a session
Retrieving, listing and filtering, updating, interrupting, archiving, and deleting a session are covered on their own page:
Session operations
Every operation on an existing session, plus cursor pagination and the read-modify-write rule for replaced arrays.
Permissions
Treat every Workspace API key as full access to its Workspace's resources, and separate access with Workspaces. See Control registry access.
What's next
Overview
Start sessions in Orca Agent Engine, stream their output, choose the sandbox an agent executes in, and supply the credentials and events it runs on.
Session operations
Retrieve, list, filter, update, interrupt, archive, and delete sessions in Orca Agent Engine, and page through results correctly.