1. A message sent while the agent is busy queues; it does not steer
Sendinput.message during a running turn and it is accepted and queued.
The response says so:
input.steer with no turn running is a conflict rather than a new turn.
Why. Whether a turn is in flight is decided from two signals — the live
bridge and the durable session status — because reading only one of them
swallowed messages during a sandbox wake-up. Having paid for that certainty, we
will not spend it guessing which of two different acts a caller meant.
2. Deleting a session destroys its sandbox
DELETE /v1/sessions/{id} ends the compute.
Why. In the Agents API a sandbox can be your own infrastructure, so deleting
a session leaves it alone. Here the sandbox belongs to the session and is billed
to us; leaving it running would bill someone for a project they deleted.
If you want the transcript without the compute, that is what the session already
is once idle — lifecycle-worker pauses an idle sandbox and reclaims it at a
cap, while items, turns and artifacts stay readable.
3. The event stream is replayable
Reconnect withLast-Event-ID and you get everything persisted since that
point. A cursor always names a row that exists.
This is more than the API this one is measured against offers, and it is the
reason a dropped connection is not a lost conversation. Details in
events.md.
4. There is no sandbox-free mode
Every session has a workspace. There is no “just the model” configuration. Why. For a coding agent the workspace is the product, not an accessory. An agent that cannot read a file or run a test is a chat endpoint, and you already have one of those.5. Bring your own model
The API does not sell inference. A session runs against a model credential your organization connected — Anthropic, OpenAI, xAI, OpenRouter, MiniMax, DeepSeek, Qwen, Kimi, GLM, or any compatible endpoint. There is no provider field, nobase_url and no key in any request, because the
provider is a property of the credential. agent.model and
agent.model_credential_id choose which connected credential; they cannot
introduce a new one.
Consequence worth stating plainly: model spend is yours, on your account,
and we never see the key in a request. Sandbox compute is ours.
6. Human approval and questions are first-class
required_actions carries three types: function_call for your code, and
approval and question for a person.
An integration can therefore see that a human is holding up a session it cares
about, rather than watching it sit in requires_action for no visible reason. All
three are answerable through this API — input.approval and
input.question_answer for the two that are about a person — and a person can
still resolve either in the Console. Which of you gets there first is your
product’s decision rather than ours.
Why. Gobare had a human-in-the-loop path before it had this API, and
hiding it from integrations would have made the API’s picture of a session
incomplete.
7. No sub-agents
There is no API for spawning a sub-agent.ApiTurn.subagent_id exists in the
shape and is currently always null.
Why. The useful version of this lives in the agent runtime rather than in
the HTTP surface, and we have not convinced ourselves the API-level version
earns its complexity. It is an omission we may revisit, not a design we have
rejected.
Smaller things
-
The clone is owed, not done.
environment.repois recorded when the session is created and cloned when its workspace comes up. A 201 means the session exists;environment.repo.clone_erroris where a failure appears. -
environment.branchis refused rather than accepted. The clone reports the branch it landed on; it cannot be told which one to use. Storing the request would be a value that changed nothing. - Environment profiles are bind-only. Values are never returned and cannot be set through this API.
-
Errors carry a code, not a type. Sixteen codes, listed in
errors.md. Three share
429and recover differently. -
There is no client package, and there is a client. We publish
run-session.tsto copy rather than a library to install: a package is a second surface to keep in step with the first. It is real code — the end-to-end test runs through the same file — so it cannot quietly stop compiling. - An agent is a saved configuration, not a running thing. Creating one starts nothing and costs nothing; a session is what runs. Applying an agent copies it, so editing or deleting one never reaches into work already in flight.
-
Ids are ours. Session ids are UUIDs; turns are
turn_…; artifacts areart_5e2b9017c4d63a8f; webhook subscriptions arewhsub_6c1e40b9a72d58f3. Do not parse them. - Times are milliseconds since the epoch, as numbers.
Next
- troubleshooting — something behaves unexpectedly
- changelog — what changed recently