id. The optional max_steps and max_time_s caps bound how long it runs before the agent is asked for a final answer.
id, which you poll for progress and the answer as in the Quickstart. For a one-shot run, the helper below blocks until the agent finishes and hands back the result.
| You want to… | SDK call | You get back |
|---|---|---|
| Run and read the answer in one shot | client.run_session(...) / runSession | Blocks, then returns the final result |
| Watch or steer while it runs | client.start_session(...) / startSession | A handle bound to the id; read and steer, then wait_for_completion |
| Drive the loop yourself (raw HTTP, other languages) | POST /sessions, then long-poll changes | The session id; you poll |
Reading the answer
There are two ways to get the agent’s answer, and they solve different problems:- Snapshot, anytime, by id.
GET /sessions/{id}returnslatest_answer, the agent’s most recent final answer, ornulluntil it first answers. It needs no cursor and never goes stale, so it’s the simplest way to ask “is it answered yet, and what’s the answer?” once a run has settled. - Stream, while it runs.
GET /sessions/{id}/changescarries the sameansweralongside the live event feed.changesis a delta. It returns only what’s new since your cursor, and204 No Contentwhen nothing new has arrived. The answer rides the page that delivers the final events, so you must keep polling until the session reaches a terminal state and you’ve drained the remaining events. A204means “no new events yet,” not “no answer.” The SDK helpers (run_session/wait_for_session) run this loop and drain to the end for you.
changes; to simply fetch a finished run’s result, read latest_answer. Don’t poll status for the answer: it never carries one.
Session object
| Field | Description |
|---|---|
id | The session’s UUID, the handle for every follow-up call. |
request | Echoes what you submitted, with agent resolved to its full spec even if you passed a catalog id. |
status | Carries the live status, step count, per-model token usage (usage_per_model), any error, and subagent_session_ids. See Session status for the breakdown. |
agent_view_url | Link to the session’s Agent View page for live viewing and replay. |
latest_answer | The agent’s most recent final answer, mirrored from changes; null until it first answers. |
created_at / started_at / finished_at | Track the run’s timeline; the latter two are null until they happen. |
Lifecycle
The agent perceives and acts in its environment step by step, moving through the same state machine regardless of which agent runs it. While it runs you can steer with messages or lifecycle controls.| Status | Meaning | Terminal |
|---|---|---|
pending | Session created, agent is launching. | No |
running | Agent is actively working on the task. | No |
paused | Manually paused via the API. State is preserved. | No |
idle | Interactive agent finished a task and is waiting for your next message. | No |
awaiting_tool_results | Agent is blocked on custom tool calls your code must answer. | No |
completed | Agent finished the task successfully. | Yes |
timed_out | Agent exceeded the maximum allowed time. | Yes |
interrupted | Session was canceled via DELETE. | Yes |
failed | An unrecoverable error occurred. | Yes |
Overrides
Reuse a catalog agent but adjust it for a single run withoverrides, a map on the create-session body. Rather than defining a new agent, you point at fields of the resolved request. Each key is a dotted path, and its value replaces whatever that path resolves to, applied after agent is expanded from its catalog id.
- Dots walk into objects.
agent.instructionssets behavior,agent.modelswaps the serving model, andagent.answer_formatpins a structured answer. - A
[field=value]selector picks a list member.agent.environments[kind=web]selects the web environment, soagent.environments[kind=web].start_urlsets just its start page andagent.environments[kind=web].modeswitches how it reads the page. - Values are type-checked. Each value must match the type of the field its path targets. An unknown path or a wrong type is rejected with
422at creation, before the agent runs.
Structured output
By default the agent’s answer is free-form text. Set ananswer_format (a JSON Schema) on the agent, or pass a Pydantic / Zod schema to the SDKs, and the final answer comes back as typed, validated data instead. See Structured output.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v2/sessions | Create a session |
GET | /api/v2/sessions | List sessions |
GET | /api/v2/sessions/{id} | Retrieve a session |
GET | /api/v2/sessions/{id}/status | Get session status |
DELETE | /api/v2/sessions/{id} | Cancel a session |
POST | /api/v2/sessions/{id}/messages | Send a message |
POST | /api/v2/sessions/{id}/tool_results | Send tool results |
POST | /api/v2/sessions/{id}/pause | Pause a session |
POST | /api/v2/sessions/{id}/resume | Resume a session |
POST | /api/v2/sessions/{id}/force_answer | Force final answer |
GET | /api/v2/sessions/{id}/changes | Long-poll for changes |
GET | /api/v2/sessions/{id}/events | List events |
GET | /api/v2/sessions/quota | Get quota |
POST | /api/v2/sessions/{id}/feedback | Submit session feedback |
POST / DELETE | /api/v2/sessions/{id}/share | Share / unshare a session |
GET | /api/v2/sessions/{id}/resources/{bucket}/{key} | Get a session resource |