# Click API - **OpenAPI Version:** `3.2.1` - **API Version:** `0.1.0` ### Introduction #### An agent primitive for your application Click provides an agents API that you build application logic on top of and connect tools to. Configure an agent's model, instructions and tools, then give it work through stateful sessions. Your application decides when the agent runs, what it can access and how its results become part of your product. Click manages agent execution, conversation state and tool dispatch, and exposes messages, events and files through the API. #### What Click provides, what your application owns | Responsibility | Click | Your application | | ----------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | | Agent execution | Model invocation, the agent loop and execution controls. | Instructions, model selection, when to start work and coordination between sessions. | | Conversation and results | Durable conversation history, event streaming and saved outputs. | Product experience, interpreting results and application records. | | Tools | Tool dispatch, built-in tools, sandbox tools and MCP calls. | Implementing application functions and connecting external services. | | Identity and access | Project isolation and enforcement of configured session tool grants. | End-user authentication, authorization, tool permissions and approvals. | | Credentials | Storage and use of supplied model keys and MCP credentials. | Supplying provider keys and acquiring or refreshing MCP credentials. | | External actions and spending | Execution outcomes and recorded tool results. | Reconciling uncertain external effects and enforcing application spending controls. | #### How it fits together Configure an agent → create a session → submit input → receive messages, tool requests and results. Send follow-up input to the same session to continue the conversation. - **Agent:** a reusable, versioned configuration of model, instructions and tools. - **Session:** the stateful handle for conversation and execution. It fixes an agent version, subject, environment and MCP bindings at creation. - **Input:** content submitted to a session to start work, steer active work or queue follow-up work. - **Run:** one execution started by an input, including steering applied while active. It can span multiple model generations and tool calls; a session has at most one active run. - **Connection:** a remote MCP endpoint and its authentication configuration. Grant a session access to specific tools when binding it. #### What persists when execution stops Recorded conversation history and saved output files survive execution loss and sandbox loss, subject to retention and deletion. Durable history does not guarantee resumable execution: a deliberately paused run can continue, but an interrupted run cannot resume. Unsaved sandbox files and processes have no continuity guarantee after sandbox loss. See Guides → Recovery for the next steps in each case. Retention periods, purge deadlines, sandbox lifetime, availability and numeric rate limits are not specified; do not rely on indefinite retention of sessions, history or files. #### Hand it to your coding agent A platform API key is a prerequisite for coding-agent integrations. A human must sign in to the dashboard, create a platform API key and provide their coding agent with: - The platform API key. - The API base URL, including `/v1`. - This reference page. Coding agents start after this handoff; a platform API key cannot create or manage other platform API keys. Authenticate backend requests with `Authorization: Bearer ` and keep the key out of end-user clients. Model requests also require your own stored OpenAI or Anthropic API key; Click supplies no model credentials. After receiving the required credentials, your coding agent can store a model API key, configure an agent and create sessions. The quick start below walks through the first conversation. ### Quick start Start with a text-only conversation: no tools, MCP connections or sandbox. You need Python 3, a human-provided platform API key and API base URL (including `/v1`), and either an Anthropic API key with access to `anthropic/claude-sonnet-5-5` or an OpenAI API key with access to `openai/gpt-6.1-sol`. Set `PLATFORM_API_BASE_URL`, `PLATFORM_API_KEY` and `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` in your backend environment, save the following as `quick_start.py`, and run `python3 quick_start.py`. It uses Anthropic when `ANTHROPIC_API_KEY` is set, otherwise OpenAI. The keys stay in your backend; never put them in browser code. The sequence is: store a model key → create an agent → create an empty session → open its event stream → submit input → read authoritative messages and the run outcome → send a follow-up in the same session. Every returned ID is captured from the actual response. Open the stream before submitting input so previews can cover the new message. This example consumes `message.completed`; previews are optional and are not authoritative. ```python import json import os import urllib.request base = os.environ["PLATFORM_API_BASE_URL"].rstrip("/") headers = {"Authorization": "Bearer " + os.environ["PLATFORM_API_KEY"]} def request(method, path, body=None, expected=200): data = None if body is None else json.dumps(body).encode("utf-8") req = urllib.request.Request(base + path, data=data, method=method, headers={**headers, "Content-Type": "application/json"}) with urllib.request.urlopen(req, timeout=30) as response: if response.status != expected: raise RuntimeError(f"Unexpected HTTP status: {response.status}") return json.load(response) def events(response): data = [] for raw in response: line = raw.decode("utf-8").rstrip("\r\n") if not line: if data: yield json.loads("\n".join(data)) data = [] elif line.startswith("data:"): data.append(line[5:].lstrip(" ")) provider = "anthropic" if os.environ.get("ANTHROPIC_API_KEY") else "openai" default_model = {"anthropic": "anthropic/claude-sonnet-5-5", "openai": "openai/gpt-6.1-sol"}[provider] key = request("POST", "/model-api-keys", { "name": "Quick start " + provider, "provider": provider, "key": os.environ[provider.upper() + "_API_KEY"], }, expected=201) print("model_api_key_id=" + key["id"]) agent = request("POST", "/agents", {"name": "Chat assistant", "config": { "model": os.environ.get("MODEL", default_model), "model_api_key_id": key["id"], "instructions": "Answer the user's questions helpfully.", "tools": [], }}, expected=201) print("agent_id=" + agent["id"]) session = request("POST", "/sessions", { "agent": {"id": agent["id"], "version": agent["latest_version"]}, "subject_id": "example/user_123", "environment": {"type": "none"}, }, expected=201) sid = session["id"] print("session_id=" + sid) stream_request = urllib.request.Request( base + f"/sessions/{sid}/events/stream?include_deltas=true", headers={**headers, "Accept": "text/event-stream"}) with urllib.request.urlopen(stream_request, timeout=60) as stream: frames = events(stream) for prompt in ["Hello! What can you help me with?", "What did I just ask you?"]: receipt = request("POST", f"/sessions/{sid}/inputs", { "mode": "queue", "content": [{"type": "text", "text": prompt}], }, expected=202) print("input_id=" + receipt["id"]) run_id = receipt["run_id"] for event in frames: kind = event["type"] if kind == "message.delta": continue # Previews have a different shape; wait for authoritative text. data = event["data"] if kind == "input.cancelled" and data["input"]["id"] == receipt["id"]: raise RuntimeError(f"Input {receipt['id']} cancelled: {data['input']['cancellation_reason']}") if kind.startswith("run.") and data["run"]["initial_input_id"] == receipt["id"]: run_id = data["run"]["id"] if kind == "input.applied" and data["input"]["id"] == receipt["id"]: run_id = data["input"]["run_id"] if kind == "message.completed" and data["run_id"] == run_id: print("assistant=" + "".join(block["text"] for block in data["message"]["content"] if block["type"] == "text")) if kind in {"run.completed", "run.failed", "run.interrupted", "run.stopped"}: if data["run"]["id"] != run_id: continue run = request("GET", f"/sessions/{sid}/runs/{run_id}") if run["status"] != "completed": raise RuntimeError(f"Run {run_id}: {run['status']}: {run['error']}") print("completed_run_id=" + run_id) break else: raise RuntimeError("Stream closed before a run outcome; see Guides → Recovery") ``` HTTP errors raise instead of triggering automatic retries. The stream read timeout is a client limit, not a platform run deadline: a timeout does not stop the agent. Save the session and input IDs before recovering. The sample leaves its resources in place for inspection. Normal completion means execution ended normally; evaluate the answer's correctness separately. Use the same session for follow-ups; `queue` gives each input its own run, while `steer` can join active work. Set `MODEL` to choose another registered model of the same provider. See `GET /sessions/{session_id}/events/stream` for a standalone streaming consumer and replay rules. ### Guides #### Recovery Read `GET /sessions/{session_id}` and, when known, `GET /sessions/{session_id}/runs/{run_id}` before deciding how to recover. Session status controls whether execution is allowed; run status records execution progress and outcome. An idle session, a completed message, or a closed connection alone does not prove success. | Situation | Action | What continues or survives | | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Client or event stream disconnected | Reopen the stream with the last committed event ID as `after` or `Last-Event-ID`; deduplicate by event ID. | Disconnecting never stops execution. Deltas are not replayed; restore authoritative messages from history. | | Event cursor expired (`410`) | Open a live stream and buffer it, read current session and history, reconcile by event ID, then apply buffered events. | Retention is unspecified; store application records needed beyond retained history. | | Deliberately paused session | Wait until `paused`, then `POST /sessions/{session_id}/resume`. | The retained run can continue. Pending application calls keep their original deadlines while paused. | | Failed run | Repair the cause, reconcile uncertain external effects, then resume the session and send fresh input or allow retained queued input to start. | Resume never retries the failed run. Queued input is retained; cancel unwanted queued inputs before resuming. | | Selected model key deleted or a different key is needed | Store a replacement model key, create an agent version selecting it, and create a new session with that version. | Existing sessions keep their original key reference; resume cannot change it. | | Interrupted run | Reconcile uncertain external effects, `POST /sessions/{session_id}/stop` with the interrupted `run_id`, then resume the session. | Interrupted execution cannot resume. History, pending calls, receipts and queued input survive; stop cancels pending calls and unapplied steering. | | Lost sandbox | Create a new session and attach any saved output files needed as inputs. | The sandbox is never recreated. Saved outputs and history survive; unsaved files and processes have no continuity guarantee. | | MCP authentication, credential expiry or an unavailable endpoint | Replace the connection's credentials and renew downstream authorization separately when required, or repair the endpoint. The affected calls fail without failing the run. | Later calls, including in the active run, use the current credentials and retry setup. Replacement does not retry failed calls or refresh downstream tokens. | A stop, failure, timeout or interruption never proves that dispatched tools had no external effects. Reconcile in the system that owns those effects; do not rerun an uncertain operation merely because its response was lost. ##### Retries | Request or operation | After an ambiguous response | | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Create a key, model key, agent/version, connection, session, upload, or submit input | No idempotency keys or duplicate suppression. Inspect any known resources and IDs before resubmitting; the API supplies no general way to prove whether an unidentified write committed. Matching text or names is not proof. | | Submit application tool results | Resend the stored, structurally identical result for the same `run_id` and `call_id`. Accepted results return the original receipt without new events, even after the run ended or session was archived. A deleted session returns `404`; a changed result returns `409 tool_result_conflict`. | | Stop a run | Repeat with the same `run_id`. A terminal target is acknowledged without stopping newer work. | | Pause or resume a session | Repeating the desired control is supported, but it operates on the session's current work. Read state first if other callers can change it; it is not scoped to a particular run. Conflicting states can return `409`. | | Archive a session or cancel queued input | Repetition is supported. Archival is irreversible; input cancellation can race dispatch and return `409` once assigned to a run. | | Execute an application function | Deduplicate by session, run and call ID; persist its result. Idempotent result submission does not make your external effects exactly-once. Reconcile uncertain execution instead of blindly repeating it. | #### Application functions Use application functions to connect agents to operations inside your own SaaS. One agent definition can serve many users; each user's session selects that definition, while your backend executes its functions under the session user's identity. Function declarations grant operation names, not access to particular records. ##### User and session authorization Authenticate the user through your application's existing authentication, derive a tenant-qualified `subject_id` on the backend, and create a separate session with `environment: {type: none}`. Persist the session ID with your application's tenant and user ownership record. Never accept `subject_id` from the browser or model as proof of identity. The platform key grants project-wide access. Before forwarding any session read, input, stream, control, history or file-download request, verify that the authenticated application user can access the session and related resource. A `subject_id` filter is a lookup convenience, not an end-user authorization boundary. The same user mapping must also authorize every function's record and action, using current permissions. ##### Tool execution and confirmation Create an agent with a function declaration such as the following `config.tools` entry. Your backend implements the function; no callback URL or sandbox is involved. ```json {"type":"function","name":"get_customer","description":"Look up a customer visible to the authenticated session user.","parameters":{"type":"object","properties":{"customer_id":{"type":"string"}},"required":["customer_id"],"additionalProperties":false}} ``` Open the stream and submit input. On `tool.requested`, read the current session, confirm the call is still in `pending_tool_calls`, and resolve its immutable `subject_id` to your authenticated application principal. Pass that principal to the same business service that enforces permissions for your normal product operations. Model arguments select the requested record and action; they never select the acting user. If the model supplies another user's record ID, deny access without exposing that user's data. For a write requiring confirmation, persist the session, run and call IDs with the exact requested arguments and show the action to the authorized user. Accept confirmation through your application's authenticated interface, bound to that specific call. A model statement that the user approved is not confirmation. Re-read the pending call and recheck current permissions and its deadline before executing; return an application error if the user declines. Pause does not extend the ten-minute deadline, and stop or expiry can race execution. A platform control never undoes a business operation. Deduplicate execution by session, run and call ID. Persist the output or error before submitting it to `POST /sessions/{session_id}/tool-results`: ```json {"run_id":"run_demo","results":[{"call_id":"call_customer","success":true,"output":{"customer_id":"customer_123","name":"Example Customer"}}]} ``` Substitute IDs from the actual pending call. An identical result retry is safe; executing the function twice may not be. Each call has a ten-minute deadline, which pause does not extend. A result receipt does not mean the agent has finished; continue consuming events through the run outcome. ##### Recovering pending calls After a stream reconnect or application-worker restart, read current session state and inspect `pending_tool_calls` before processing historical requests. Reuse the stored result for a completed local execution; never execute its business effect again just because delivery or the receipt was lost. Rediscover unresolved calls from session state even if their stream event was missed. Keep durable pending confirmations so a restart does not turn them into automatic approvals. Interrupted runs retain pending calls, but submitting results does not resume their execution; follow Guides → Recovery. When the business mutation and result ledger share a database, commit them in one transaction. For an external service, use its own idempotency or operation-status mechanism and reconcile uncertain effects. The platform's identical-result retry does not provide exactly-once execution of your business operation. ##### Runnable SaaS example [Download saas.py](/reference/examples/saas.py). This Python 3.11+ standard-library backend gives Alice and Bob separate tickets and sessions with one shared agent definition. It implements `list_tickets` and `rename_ticket`, checks record ownership, requires an authenticated confirmation for each rename, and stores business changes and tool results atomically in SQLite. Repeated result delivery and process restarts reuse that ledger. Supply `PLATFORM_API_BASE_URL` (including `/v1`), `PLATFORM_API_KEY` and `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` as in the quick start. Create two distinct local application bearer tokens of at least 32 characters as `SAAS_ALICE_TOKEN` and `SAAS_BOB_TOKEN`; for example, generate each with `python3 -c 'import secrets; print(secrets.token_urlsafe(32))'`. These local tokens represent the demo users; in your product, connect the principal mapping to your existing authentication. Keep the platform and model keys in the backend. Save the downloaded source as `saas.py` and run `python3 saas.py --database saas.sqlite3 --port 8090`. First startup stores the model key and creates a shared agent using `anthropic/claude-sonnet-5-5` or `openai/gpt-6.1-sol`, as in the quick start; `MODEL` selects another registered model of that provider. The database retains its selected agent/version, session ownership, pending confirmations and result ledger across restarts. `SAAS_AGENT_ID` and optional `SAAS_AGENT_VERSION` can select an existing agent with these function definitions instead. An incomplete initial setup blocks automatic setup retries: inspect the saved IDs and reconcile any ambiguous creates before proceeding. The sample leaves platform resources in place for inspection. Run this client in another terminal with the same application-token environment. It checks cross-user session rejection, submits work for both users, shows each requested rename, and asks for explicit confirmation. Polling current sessions recovers pending calls; this example reads authoritative run messages and does not display text previews. ```python import json import os import time import urllib.error import urllib.request origin = os.environ.get("SAAS_URL", "http://127.0.0.1:8090") tokens = {"alice": os.environ["SAAS_ALICE_TOKEN"], "bob": os.environ["SAAS_BOB_TOKEN"]} def call(user, method, path, body=None): data = None if body is None else json.dumps(body).encode() request = urllib.request.Request(origin + path, data=data, method=method, headers={"Authorization": "Bearer " + tokens[user], "Content-Type": "application/json"}) with urllib.request.urlopen(request, timeout=20) as response: return json.load(response) sessions = {user: call(user, "POST", "/sessions", {})["id"] for user in tokens} print("sessions=" + json.dumps(sessions)) try: call("bob", "GET", "/sessions/" + sessions["alice"]) raise RuntimeError("Cross-user access was unexpectedly allowed") except urllib.error.HTTPError as error: if error.code != 404: raise for user, sid in sessions.items(): print(user, "tickets:", call(user, "GET", "/tickets")) receipt = call(user, "POST", f"/sessions/{sid}/inputs", { "text": "List my tickets, then request to rename my first ticket to Reviewed.", }) print(user, "input_id:", receipt["id"]) while True: state = call(user, "GET", f"/sessions/{sid}") for pending in state["approvals"]: print(user, "requested action:", pending["tool"], pending["arguments"]) approved = input("Approve this exact change? Type yes: ").strip().lower() == "yes" path = f"/sessions/{sid}/runs/{pending['run_id']}/calls/{pending['call_id']}/decision" call(user, "POST", path, {"approved": approved}) run = state["run"] if run and run["status"] in {"completed", "failed", "stopped", "interrupted"}: print(user, "run outcome:", run["status"], "messages:", run["messages"], "error:", run["error"]) break time.sleep(0.5) ``` The example's local API exposes only owned tickets, session creation, input submission, session/run status and per-call decisions. Your product must apply the same authorization checks when adding streaming, controls or file downloads. Its polling executor can be replaced with `tool.requested` handling plus session-state recovery. It never automatically resubmits input. After an ambiguous response, reuse known session/input IDs and inspect state. Local SQLite atomicity covers only these demo ticket changes; it is not a guarantee for external services or effects racing platform cancellation. #### Research files Create an agent with `tools: [web_search, web_fetch, read_file, apply_patch]` and instructions to research the request and save a cited report under `/workspace/outputs/`. Create an empty session with `environment: {type: sandbox}` and no MCP connections, open the stream, then submit a text request. Built-in web search and fetch do not require sandbox egress grants. After `run.completed`, retrieve the run and use its `output_file_ids`; each listed file is ready to download. Retrieve metadata with `GET /files/{file_id}` and bytes with `GET /files/{file_id}/content`, using the platform bearer key. Judge the report and its citations independently of run completion. Stopped and failed runs save no new outputs. Saved outputs survive sandbox loss and archival, subject to retention; unsaved sandbox files do not. #### API conventions Every operation is under the base URL's `/v1` path; other paths return 404 `not_found`. A method that a path does not support returns 405 `method_not_allowed` with an `Allow` header listing the supported methods. The `Bearer` authentication scheme name is case-insensitive. Send JSON request bodies with `Content-Type: application/json`; media type parameters such as `charset=utf-8` are allowed. A non-empty body with another or no media type returns 415 `unsupported_media_type`. Uploads use `multipart/form-data`. Creation and input submission have no idempotency keys or duplicate suppression: do not blindly resubmit an ambiguous request. Identical tool-result submissions return stored receipts, and some control operations allow repeated requests; see Guides → Recovery for the retry rules. Strings in JSON request bodies, including object keys, must not contain the NUL character (U+0000); such requests return 400 `invalid_request`. NUL characters produced by the agent or its tools, in messages, tool arguments, results and errors, are recorded as U+FFFD. List pages follow a stable order, and `next_cursor` continues after the last record of its page. Deleting records or changing their status between requests never invalidates a cursor: records that left the collection are skipped and later records are returned. ##### Error codes Errors use the `Error` envelope: a stable `code`, a human-readable `message` and the `request_id` to quote when reporting a problem. Branch on `code`, never on `message`. Operations describe when each code applies. Run and tool failures are not HTTP errors; their codes are documented on `GET /sessions/{session_id}/runs/{run_id}` and with each tool on `POST /agents`. | Status | Code | Meaning | | ------ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 400 | `invalid_request` | The body does not match the operation's schema, contains a NUL character or has an invalid value. | | 400 | `invalid_json` | The body is not valid JSON. | | 400 | `request_too_large` | A JSON body exceeds 16 MiB. | | 400 | `invalid_parameter` | A path, query or header parameter does not match its schema. | | 400 | `invalid_cursor` | A pagination cursor is malformed or belongs to another endpoint or filter, or a stream's event ID is unknown or belongs to another session. | | 400 | `conflicting_cursor` | A stream received different `after` and `Last-Event-ID` values. | | 400 | `invalid_model` | The model is not a registered `openai/` or `anthropic/` model. | | 400 | `model_api_key_provider_mismatch` | The model API key belongs to another provider. | | 400 | `invalid_tools` | Tool names repeat, or a function uses a built-in tool name. | | 400 | `invalid_schema` | A function's `parameters` is not a valid JSON Schema, references an external schema, has an unresolvable reference or contains an invalid regular expression. | | 400 | `invalid_url` | An MCP endpoint is not an HTTPS URL without credentials or a fragment. | | 400 | `duplicate_connection` | A session binds the same `connection_id` twice. | | 400 | `invalid_network_policy` | An allowed host is not an exact DNS hostname. | | 400 | `unsupported_image` | The sandbox `image` is not `managed-default`. | | 400 | `files_require_sandbox` | File content was sent to a session without a sandbox. | | 400 | `unsupported_reasoning_effort` | The session's model does not support the requested reasoning effort. | | 400 | `unsupported_image_input` | The session's model does not accept images. | | 400 | `invalid_image` | Image content is not a static PNG, JPEG or WebP. | | 400 | `image_limits_exceeded` | Image content exceeds the model's image limits. | | 400 | `invalid_upload` | The upload is not exactly one multipart `file` field. | | 400 | `duplicate_call_id` | A tool-result batch repeats a `call_id`. | | 400 | `invalid_tool_result` | A result names a call that the platform executes. | | 401 | `unauthorized` | The bearer credential is missing, invalid, expired or revoked. | | 403 | `forbidden` | The credential cannot perform this operation, such as a project API key managing API keys. | | 403 | `connection_subject_mismatch` | A bound connection belongs to another `subject_id`. | | 404 | `not_found` | The path, or a resource that it or the body names, does not exist in this project. | | 405 | `method_not_allowed` | The path does not support the method; see the `Allow` header. | | 409 | `session_active` | The session has an active or stopping run. | | 409 | `session_archived` | The session is archived and read-only. | | 409 | `session_paused` | Steering was sent while the session is pausing or paused. | | 409 | `session_pausing` | Resume was requested before the session finished pausing. | | 409 | `run_interrupted` | The session's run is interrupted; stop it before steering or resuming. | | 409 | `run_stopping` | The session's run is stopping. | | 409 | `run_not_active` | A stop named a run of this session that is neither active nor finished. | | 409 | `input_not_queued` | The input already has a run, so it cannot be cancelled. | | 409 | `connection_session_scoped` | A session-owned connection cannot be bound to another session. | | 409 | `tool_call_not_pending` | The call no longer accepts new results. | | 409 | `tool_call_run_mismatch` | The call belongs to another run. | | 409 | `tool_result_conflict` | The call already has a different accepted result. | | 410 | `cursor_expired` | The cursor or event is no longer retained under the retention policy. | | 413 | `file_too_large` | The upload exceeds 16 MiB. | | 415 | `unsupported_media_type` | A JSON body was sent without `Content-Type: application/json`. | | 429 | `rate_limited` | The service request rate limit was reached. | | 500 | `internal_error` | A platform error; no automatic resubmission or tool replay is promised. | | 500 | `image_preparation_failed` | Accepted image bytes could not be read or prepared. | | 500 | `stream_unavailable` | Text previews could not be set up for a stream. | The dashboard manages project API keys, model API keys, agents and session logs. Each signed-in user owns an isolated project; organization membership does not share projects. Signing out ends the dashboard session but does not revoke API keys. Dashboard access tokens remain valid until their expiry; deleted project API keys cannot authenticate new requests. Existing requests and event streams are not cancelled by credential revocation. ## Contents **Operations** - [GET /api-keys](#scalar-operation-get-api-keys) - [POST /api-keys](#scalar-operation-post-api-keys) - [DELETE /api-keys/{api_key_id}](#scalar-operation-delete-api-keysapi-key-id) - [GET /model-api-keys](#scalar-operation-get-model-api-keys) - [POST /model-api-keys](#scalar-operation-post-model-api-keys) - [GET /model-api-keys/{model_api_key_id}](#scalar-operation-get-model-api-keysmodel-api-key-id) - [DELETE /model-api-keys/{model_api_key_id}](#scalar-operation-delete-model-api-keysmodel-api-key-id) - [POST /agents](#scalar-operation-post-agents) - [GET /agents](#scalar-operation-get-agents) - [PATCH /agents/{agent_id}](#scalar-operation-patch-agentsagent-id) - [DELETE /agents/{agent_id}](#scalar-operation-delete-agentsagent-id) - [GET /agents/{agent_id}](#scalar-operation-get-agentsagent-id) - [POST /agents/{agent_id}/versions](#scalar-operation-post-agentsagent-idversions) - [GET /agents/{agent_id}/versions/{version}](#scalar-operation-get-agentsagent-idversionsversion) - [POST /connections](#scalar-operation-post-connections) - [GET /connections](#scalar-operation-get-connections) - [GET /connections/{connection_id}](#scalar-operation-get-connectionsconnection-id) - [DELETE /connections/{connection_id}](#scalar-operation-delete-connectionsconnection-id) - [PUT /connections/{connection_id}/credentials](#scalar-operation-put-connectionsconnection-idcredentials) - [POST /sessions](#scalar-operation-post-sessions) - [GET /sessions](#scalar-operation-get-sessions) - [GET /sessions/{session_id}](#scalar-operation-get-sessionssession-id) - [DELETE /sessions/{session_id}](#scalar-operation-delete-sessionssession-id) - [POST /sessions/{session_id}/stop](#scalar-operation-post-sessionssession-idstop) - [POST /sessions/{session_id}/pause](#scalar-operation-post-sessionssession-idpause) - [POST /sessions/{session_id}/resume](#scalar-operation-post-sessionssession-idresume) - [POST /sessions/{session_id}/archive](#scalar-operation-post-sessionssession-idarchive) - [POST /sessions/{session_id}/tool-results](#scalar-operation-post-sessionssession-idtool-results) - [POST /sessions/{session_id}/inputs](#scalar-operation-post-sessionssession-idinputs) - [GET /sessions/{session_id}/inputs](#scalar-operation-get-sessionssession-idinputs) - [GET /sessions/{session_id}/inputs/{input_id}](#scalar-operation-get-sessionssession-idinputsinput-id) - [DELETE /sessions/{session_id}/inputs/{input_id}](#scalar-operation-delete-sessionssession-idinputsinput-id) - [GET /sessions/{session_id}/runs](#scalar-operation-get-sessionssession-idruns) - [GET /sessions/{session_id}/runs/{run_id}](#scalar-operation-get-sessionssession-idrunsrun-id) - [GET /sessions/{session_id}/events](#scalar-operation-get-sessionssession-idevents) - [GET /sessions/{session_id}/events/stream](#scalar-operation-get-sessionssession-ideventsstream) - [POST /files](#scalar-operation-post-files) - [GET /sessions/{session_id}/files](#scalar-operation-get-sessionssession-idfiles) - [GET /files/{file_id}](#scalar-operation-get-filesfile-id) - [DELETE /files/{file_id}](#scalar-operation-delete-filesfile-id) - [GET /files/{file_id}/content](#scalar-operation-get-filesfile-idcontent) **Schemas** - [CreateModelApiKey](#scalar-schema-createmodelapikey) - [ModelApiKey](#scalar-schema-modelapikey) - [ModelApiKeyList](#scalar-schema-modelapikeylist) - [CreateApiKey](#scalar-schema-createapikey) - [ApiKey](#scalar-schema-apikey) - [CreatedApiKey](#scalar-schema-createdapikey) - [ApiKeyList](#scalar-schema-apikeylist) - [UpdateAgent](#scalar-schema-updateagent) - [TextContent](#scalar-schema-textcontent) - [FileContent](#scalar-schema-filecontent) - [ImageContent](#scalar-schema-imagecontent) - [Content](#scalar-schema-content) - [ErrorDetail](#scalar-schema-errordetail) - [Error](#scalar-schema-error) - [ConnectionGrant](#scalar-schema-connectiongrant) - [InlineConnectionGrant](#scalar-schema-inlineconnectiongrant) - [SessionConnectionConfig](#scalar-schema-sessionconnectionconfig) - [AgentConfig](#scalar-schema-agentconfig) - [CreateAgent](#scalar-schema-createagent) - [CreateAgentVersion](#scalar-schema-createagentversion) - [Agent](#scalar-schema-agent) - [AgentVersion](#scalar-schema-agentversion) - [AgentSelection](#scalar-schema-agentselection) - [ResolvedAgent](#scalar-schema-resolvedagent) - [NetworkPolicy](#scalar-schema-networkpolicy) - [NoEnvironment](#scalar-schema-noenvironment) - [SandboxEnvironment](#scalar-schema-sandboxenvironment) - [Environment](#scalar-schema-environment) - [ReasoningEffort](#scalar-schema-reasoningeffort) - [InitialInput](#scalar-schema-initialinput) - [CreateSession](#scalar-schema-createsession) - [Session](#scalar-schema-session) - [SendInput](#scalar-schema-sendinput) - [Input](#scalar-schema-input) - [AssistantMessage](#scalar-schema-assistantmessage) - [RunFailure](#scalar-schema-runfailure) - [Run](#scalar-schema-run) - [StopRun](#scalar-schema-stoprun) - [ToolCall](#scalar-schema-toolcall) - [CreateConnection](#scalar-schema-createconnection) - [Connection](#scalar-schema-connection) - [FileMetadata](#scalar-schema-filemetadata) - [UploadedFileMetadata](#scalar-schema-uploadedfilemetadata) - [OutputFileMetadata](#scalar-schema-outputfilemetadata) - [File](#scalar-schema-file) - [UploadFile](#scalar-schema-uploadfile) - [SessionCreatedEvent](#scalar-schema-sessioncreatedevent) - [InputAcceptedEvent](#scalar-schema-inputacceptedevent) - [InputAppliedEvent](#scalar-schema-inputappliedevent) - [InputCancelledEvent](#scalar-schema-inputcancelledevent) - [RunStartedEvent](#scalar-schema-runstartedevent) - [RunCompletedEvent](#scalar-schema-runcompletedevent) - [RunFailedEvent](#scalar-schema-runfailedevent) - [RunInterruptedEvent](#scalar-schema-runinterruptedevent) - [RunStoppedEvent](#scalar-schema-runstoppedevent) - [SessionUpdatedEvent](#scalar-schema-sessionupdatedevent) - [SessionArchivedEvent](#scalar-schema-sessionarchivedevent) - [MessageCompletedEvent](#scalar-schema-messagecompletedevent) - [ToolStartedEvent](#scalar-schema-toolstartedevent) - [ToolCompletedEvent](#scalar-schema-toolcompletedevent) - [ToolFailedEvent](#scalar-schema-toolfailedevent) - [SandboxProvisionedEvent](#scalar-schema-sandboxprovisionedevent) - [SandboxLostEvent](#scalar-schema-sandboxlostevent) - [OutputFileCreatedEvent](#scalar-schema-outputfilecreatedevent) - [Event](#scalar-schema-event) - [MessageDelta](#scalar-schema-messagedelta) - [SSECommittedEvent](#scalar-schema-ssecommittedevent) - [SSEMessageDelta](#scalar-schema-ssemessagedelta) - [StreamItem](#scalar-schema-streamitem) - [AgentList](#scalar-schema-agentlist) - [ConnectionList](#scalar-schema-connectionlist) - [SessionList](#scalar-schema-sessionlist) - [InputList](#scalar-schema-inputlist) - [RunList](#scalar-schema-runlist) - [EventList](#scalar-schema-eventlist) - [OutputFileList](#scalar-schema-outputfilelist) - [SecretHeaders](#scalar-schema-secretheaders) - [ReplaceConnectionCredentials](#scalar-schema-replaceconnectioncredentials) - [SubjectId](#scalar-schema-subjectid) - [SessionConnectionBinding](#scalar-schema-sessionconnectionbinding) - [BuiltinTool](#scalar-schema-builtintool) - [ApplyPatchArguments](#scalar-schema-applypatcharguments) - [ApplyPatchResult](#scalar-schema-applypatchresult) - [ViewImageArguments](#scalar-schema-viewimagearguments) - [ViewImageResult](#scalar-schema-viewimageresult) - [ShellArguments](#scalar-schema-shellarguments) - [ShellResult](#scalar-schema-shellresult) - [FunctionTool](#scalar-schema-functiontool) - [AgentTool](#scalar-schema-agenttool) - [PendingToolCall](#scalar-schema-pendingtoolcall) - [ToolResultError](#scalar-schema-toolresulterror) - [SuccessfulToolResult](#scalar-schema-successfultoolresult) - [FailedToolResult](#scalar-schema-failedtoolresult) - [ToolResult](#scalar-schema-toolresult) - [SubmitToolResults](#scalar-schema-submittoolresults) - [ToolResultsReceipt](#scalar-schema-toolresultsreceipt) - [ToolRequestedEvent](#scalar-schema-toolrequestedevent) - [ToolCancelledEvent](#scalar-schema-toolcancelledevent) - [ApplicationResultCall](#scalar-schema-applicationresultcall) ## Servers - **URL:** `https://api.useclick.ai/v1` - **Description:** Platform instance ## Authentication - **ProjectToken**: HTTP bearer Project API key created from the dashboard. Keys grant full project access, including model API key management, except project API key management. The local development instance also accepts `dev-key`, and `dev-key-other` for a second project; these projects are separate from signed-in dashboard projects. Every resource belongs to one project: IDs from another project, in paths or request bodies, return 404 `not_found`. The key does not identify end users; your backend authenticates them and supplies `subject_id`. Keep the key in your backend: the platform never forwards it to sandboxes or MCP servers. Or: - **DashboardSession**: HTTP bearer (`JWT`) A valid, unexpired dashboard login access token. It identifies the signed-in user's project and authorizes API key management as well as normal project operations. ## Tags ### API keys Project credentials managed from a signed-in dashboard session. ### Model API keys Your project-scoped OpenAI and Anthropic credentials for model requests. ### Agents Reusable, versioned agent configurations. ### Connections Remote MCP endpoints and their authentication credentials. ### Sessions Durable agent sessions and execution controls. ### Inputs Session input submission, inspection and cancellation. ### Tools Durable requests and results for tools executed by customer applications. ### Runs Execution outcomes and failure details. ### Events Committed session history and live event streams. ### Files Input uploads and saved output files. ## Operations ### List API keys - **Method:** `GET` - **Path:** `/api-keys` - **Operation ID:** `get_api_keys` - **Tags:** API keys List this project's API keys, newest first. Secret values are never returned. Requires a dashboard session; project API keys return 403. **Servers:** [Inherited servers](#scalar-context-global-servers) #### Authentication - **DashboardSession**: HTTP bearer (`JWT`) A valid, unexpired dashboard login access token. It identifies the signed-in user's project and authorizes API key management as well as normal project operations. #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. #### Responses ##### 200 Project API keys. **Content type:** `application/json` [ApiKeyList](/reference/schemas/ApiKeyList.md) ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Create an API key - **Method:** `POST` - **Path:** `/api-keys` - **Operation ID:** `post_api_keys` - **Tags:** API keys Create a key granting full access to this project's model API keys, agents, sessions, connections and files. Copy the secret from this response; it cannot be retrieved again. Requires a dashboard session; project API keys cannot create project API keys. Duplicate names are allowed. **Servers:** [Inherited servers](#scalar-context-global-servers) #### Authentication - **DashboardSession**: HTTP bearer (`JWT`) A valid, unexpired dashboard login access token. It identifies the signed-in user's project and authorizes API key management as well as normal project operations. #### Request body **Required:** `true` **Content type:** `application/json` [CreateApiKey](/reference/schemas/CreateApiKey.md) **Example:** ```json { "name": "Backend integration" } ``` #### Responses ##### 201 API key and its one-time secret. **Content type:** `application/json` [CreatedApiKey](/reference/schemas/CreatedApiKey.md) ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Delete an API key - **Method:** `DELETE` - **Path:** `/api-keys/{api_key_id}` - **Operation ID:** `delete_api_keys_api_key_id` - **Tags:** API keys Permanently revoke a key. New requests using it return 401 immediately after this operation succeeds; already-authorized requests and streams may finish. Requires a dashboard session. A missing or another project's key returns 404. **Servers:** [Inherited servers](#scalar-context-global-servers) #### Authentication - **DashboardSession**: HTTP bearer (`JWT`) A valid, unexpired dashboard login access token. It identifies the signed-in user's project and authorizes API key management as well as normal project operations. #### Path parameters - **`api_key_id` (required)**: `string`, pattern: `^key_[A-Za-z0-9]+$` #### Responses ##### 204 API key revoked. ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### List model API keys - **Method:** `GET` - **Path:** `/model-api-keys` - **Operation ID:** `get_model_api_keys` - **Tags:** Model API keys List this project's stored model API keys, newest first. Returns metadata and only the first and last four characters of each key. Full keys are never returned. Available to project API keys and dashboard sessions. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. #### Responses ##### 200 Stored model API key metadata. **Content type:** `application/json` [ModelApiKeyList](/reference/schemas/ModelApiKeyList.md) ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Store a model API key - **Method:** `POST` - **Path:** `/model-api-keys` - **Operation ID:** `post_model_api_keys` - **Tags:** Model API keys Store your own key for the direct OpenAI or Anthropic model API. Available to project API keys and dashboard sessions. The key is encrypted at rest and never returned, including in this response. Only its first and last four characters are exposed for identification. It is used only to authenticate model requests and is not included in model context, sandbox environments, session history or traces. Name, provider and key are immutable. To rotate a key, store a new one, select it in a new agent version and delete the old key. Existing sessions retain their original key selection. Duplicate names and keys are allowed. Storage does not verify the key with the provider or guarantee model access; provider rejections fail runs with `model_error`. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Request body **Required:** `true` **Content type:** `application/json` [CreateModelApiKey](/reference/schemas/CreateModelApiKey.md) **Example:** ```json { "name": "Production OpenAI", "provider": "openai", "key": "sk-EXAMPLE_CUSTOMER_KEY" } ``` #### Responses ##### 201 Stored model API key metadata; the full key is not returned. **Content type:** `application/json` [ModelApiKey](/reference/schemas/ModelApiKey.md) **Example:** ```json { "id": "mkey_demo", "name": "Production OpenAI", "provider": "openai", "prefix": "sk-E", "suffix": "_KEY", "created_at": "2026-10-09T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve model API key metadata - **Method:** `GET` - **Path:** `/model-api-keys/{model_api_key_id}` - **Operation ID:** `get_model_api_keys_model_api_key_id` - **Tags:** Model API keys Retrieve metadata and only the first and last four key characters. A missing or another project's key returns 404. The full key cannot be retrieved. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`model_api_key_id` (required)**: `string`, pattern: `^mkey_[A-Za-z0-9]+$` #### Responses ##### 200 Stored model API key metadata. **Content type:** `application/json` [ModelApiKey](/reference/schemas/ModelApiKey.md) **Example:** ```json { "id": "mkey_demo", "name": "Production OpenAI", "provider": "openai", "prefix": "sk-E", "suffix": "_KEY", "created_at": "2026-10-09T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Delete a model API key - **Method:** `DELETE` - **Path:** `/model-api-keys/{model_api_key_id}` - **Operation ID:** `delete_model_api_keys_model_api_key_id` - **Tags:** Model API keys Delete the stored key and its metadata. A missing or another project's key returns 404. The ID is never reused. Agent versions and sessions keep their key reference; they do not receive a replacement key. Future runs using that reference fail with `model_api_key_unavailable`. A run that already loaded the key may finish, including subsequent model requests in that run. Deleting a key does not revoke it at OpenAI or Anthropic. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`model_api_key_id` (required)**: `string`, pattern: `^mkey_[A-Za-z0-9]+$` #### Responses ##### 204 Stored model API key deleted. ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Create an agent - **Method:** `POST` - **Path:** `/agents` - **Operation ID:** `post_agents` - **Tags:** Agents Create a project agent and its immutable version 1. A configuration holds the model, base instructions and tools. To change it, create a new version; existing sessions keep the version they selected. MCP connections are granted per session, not on agents. Models are registered `openai/model-id` or `anthropic/model-id` values. Set `model_api_key_id` to one of your project's stored keys for the same provider; there are no platform-supplied model credentials. An omitted key returns 400 `invalid_request`, a missing or another project's key returns 404 `not_found`, and a provider mismatch returns 400 `model_api_key_provider_mismatch`. An unregistered model in a valid request shape returns 400 `invalid_model` before an agent or version is created. Registration does not guarantee provider access: unrecoverable provider authorization, availability and request failures fail the run with `model_error`. Transient model failures may be retried within the active run; see "Failures" on `GET /sessions/{session_id}/runs/{run_id}`. ### Tools Each `tools` entry is a built-in name or a function definition (`{type: function, name, description, parameters}`). Omitted `tools` means none; only declared tools can execute. The platform executes built-ins and MCP tools. A built-in call whose arguments do not match its documented schema is never dispatched: it fails with `invalid_tool_arguments` as a tool error the agent can handle, and the run continues. The model calls tools through one JavaScript tool that every agent has, including one without `tools`. Each script runs as the body of an async function in an isolated runtime without filesystem, network, imports or timers, with 32 MiB of memory and the CPU budget described on `POST /sessions`, and calls granted tools as `await tools.(args)`. A script can keep JSON values for later scripts with `store(key, value)` and `load(key)`: they persist for the session, including across runs, are never shared with another session or exposed by the API, and are limited to 262,144 characters of JSON per value and 1,048,576 characters per session, keys included. A failing script stores nothing. Scripts are not tool calls in session history; the tool calls they make are. - `shell` runs a command in the session sandbox and waits for it to finish; see `ShellArguments` and `ShellResult`. - `read_file` reads a UTF-8 text file of at most 4 MiB beneath `/workspace/`, given as an absolute path or one relative to `/workspace/`. Symlinks are never followed. Larger files fail with `file_too_large` (use `shell` to read part of them), non-text bytes with `not_utf8`, and paths outside the workspace, missing files and symlinks with `invalid_request`. `apply_patch` creates, edits and deletes files using standard unified text diffs (see `ApplyPatchArguments` and `ApplyPatchResult`). Attachment files are writable sandbox copies; editing them never changes the durable upload or saved input copy. Save deliverables under `/workspace/outputs/`. - `view_image` reads a static PNG, JPEG or WebP at a workspace path, resolved as for `read_file`, and delivers its pixels to the model. See `ViewImageArguments` and `ViewImageResult`. The harness automatically includes the image in the tool result after the agent's script finishes, even if the script does not print or return anything. The script and public `ToolCall.result` receive only metadata; public events and traces never contain these image bytes. Native model history retains the image independently of subsequent sandbox file changes or loss, subject to the same compaction behavior as image inputs. - `web_search` searches the public web with platform-provided credentials; no customer search key is required. It accepts `{query: string}` and returns JSON search results with URLs, titles and available highlights. It is not governed by the sandbox network allowlist. Provider request failures and non-success responses fail with `web_search_failed`; HTTP failures report the status without the provider response body. Results are limited to 4 MiB (`response_too_large`); invalid JSON fails with `web_search_failed`. If platform search credentials are unavailable, the call fails with `web_search_unconfigured`. - `web_fetch` sends a GET with a `ClickAgent` User-Agent to a public HTTPS URL and returns the response body as text, limited to 4 MiB. It is not governed by the sandbox network allowlist, and private or special destinations fail with `destination_not_allowed`. Redirects are not followed: any non-success response fails with `web_fetch_failed`, whose message gives the HTTP status and, for a redirect, its absolute target. An unresolvable host fails with `host_unresolved`; connection failures and timeouts fail with `web_fetch_failed`. `view_image` requires an image-capable model; otherwise its call fails with `unsupported_image_input`. It uses the same static-image decoding and per-image limits as image inputs, with `invalid_image` and `image_limits_exceeded` returned as recoverable tool errors. It does not resize or convert files. Aggregate image-count and serialized request-size limits still apply before each model request and may fail the run with `model_error`. Tools are platform contracts; executables and libraries are environment dependencies. The `managed-default` sandbox includes Python 3, Poppler (`pdftotext`, `pdftoppm`) and `rsvg-convert`. A plain `pip install` installs into the workspace user site with its console scripts on `PATH`; downloading packages requires the package index hosts in the network allowlist. Use `shell` to extract PDF text or render PDF/SVG pages to PNG, then `read_file` or `view_image` to inspect the results. There are no dedicated PDF or SVG tools. Other document formats require utilities available in the environment; a filename or mounted path alone does not give the model file contents. ### Functions executed by your application A function has a `name` that is unique and differs from built-in names, a `description` and a JSON Schema 2020-12 for its argument object (see `FunctionTool`). Invalid schemas, external schema references and duplicate or built-in names return 400. A definition contains no implementation or callback URL. When the agent requests functions, the platform validates the whole batch of arguments first: an invalid batch fails the run with `invalid_tool_arguments` and creates no requests. Valid requests are persisted, emitted as `tool.requested` and listed in the session's `pending_tool_calls`, and the run waits in `waiting_for_tools`. Your backend executes them and submits results to `POST /sessions/{session_id}/tool-results`, and the same run continues; calls that depend on those results form another batch in the same run. There are no webhooks or callbacks, and no sandbox is involved: an attached sandbox never executes functions. Authorize each call with the session's immutable `subject_id` and your own user mapping, never with model-supplied arguments. Keep application credentials in your backend and redact secrets from outputs and errors, which enter model context and session history. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Request body **Required:** `true` **Content type:** `application/json` [CreateAgent](/reference/schemas/CreateAgent.md) **Example: builtins** Built-in tools ```json { "name": "Research assistant", "config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] } } ``` **Example: application_functions** Tool implemented in your application ```json { "name": "Customer assistant", "config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] } } ``` #### Responses ##### 201 Create an agent. **Content type:** `application/json` [Agent](/reference/schemas/Agent.md) **Example:** ```json { "id": "agt_demo", "name": "Research assistant", "latest_version": 1, "created_at": "2026-09-29T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### List agents - **Method:** `GET` - **Path:** `/agents` - **Operation ID:** `get_agents` - **Tags:** Agents List the project's agents, newest first (ties broken by ID). Retrieve a version for its configuration. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. #### Responses ##### 200 List agents. **Content type:** `application/json` [AgentList](/reference/schemas/AgentList.md) **Example:** ```json { "data": [ { "id": "agt_demo", "name": "Research assistant", "latest_version": 1, "created_at": "2026-09-29T17:00:00Z" } ], "next_cursor": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Rename an agent - **Method:** `PATCH` - **Path:** `/agents/{agent_id}` - **Operation ID:** `patch_agents_agent_id` - **Tags:** Agents Update the agent's name. To change its configuration, create a new immutable version. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`agent_id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` #### Request body **Required:** `true` **Content type:** `application/json` [UpdateAgent](/reference/schemas/UpdateAgent.md) #### Responses ##### 200 Updated agent. **Content type:** `application/json` [Agent](/reference/schemas/Agent.md) **Example:** ```json { "id": "agt_demo", "name": "Research assistant", "latest_version": 1, "created_at": "2026-09-29T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Delete an agent - **Method:** `DELETE` - **Path:** `/agents/{agent_id}` - **Operation ID:** `delete_agents_agent_id` - **Tags:** Agents Remove an agent and its versions from API visibility. New sessions cannot select it. Existing sessions keep their selected configuration, continue executing, and retain their logs. A repeated delete returns 404. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`agent_id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` #### Responses ##### 204 Agent deleted. ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve an agent - **Method:** `GET` - **Path:** `/agents/{agent_id}` - **Operation ID:** `get_agents_agent_id` - **Tags:** Agents Read an agent's identity and latest version number. Retrieve a version for its configuration. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`agent_id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` #### Responses ##### 200 Retrieve an agent. **Content type:** `application/json` [Agent](/reference/schemas/Agent.md) **Example:** ```json { "id": "agt_demo", "name": "Research assistant", "latest_version": 1, "created_at": "2026-09-29T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Create an agent version - **Method:** `POST` - **Path:** `/agents/{agent_id}/versions` - **Operation ID:** `post_agents_agent_id_versions` - **Tags:** Agents Create the agent's next immutable version from a complete configuration, which replaces the previous one rather than merging with it. Configuration rules are those of `POST /agents`. Versions are allocated sequentially per agent, so concurrent requests receive distinct versions. The new version becomes `latest_version`; existing sessions and their pending tool requests keep the version they snapshotted at creation. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`agent_id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` #### Request body **Required:** `true` **Content type:** `application/json` [CreateAgentVersion](/reference/schemas/CreateAgentVersion.md) **Example: builtins** Built-in tools ```json { "config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] } } ``` **Example: application_functions** Tool implemented in your application ```json { "config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] } } ``` #### Responses ##### 201 Create an agent version. **Content type:** `application/json` [AgentVersion](/reference/schemas/AgentVersion.md) **Example:** ```json { "agent_id": "agt_demo", "version": 1, "config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "created_at": "2026-09-29T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve an agent version - **Method:** `GET` - **Path:** `/agents/{agent_id}/versions/{version}` - **Operation ID:** `get_agents_agent_id_versions_version` - **Tags:** Agents Read an immutable agent version. Sessions that selected it keep it when newer versions are created. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`agent_id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` - **`version` (required)**: `integer`, minimum: `1` #### Responses ##### 200 Retrieve an agent version. **Content type:** `application/json` [AgentVersion](/reference/schemas/AgentVersion.md) **Example:** ```json { "agent_id": "agt_demo", "version": 1, "config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "created_at": "2026-09-29T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Register a remote MCP connection - **Method:** `POST` - **Path:** `/connections` - **Operation ID:** `post_connections` - **Tags:** Connections Register a reusable MCP connection for one `subject_id`: an immutable HTTPS endpoint with optional write-only authentication headers. Registration only stores configuration; it does not contact the endpoint, discover tools or check authorization, and grants no session access. Bind it when creating sessions, with exact `allowed_tools`. For a single session, configure the endpoint inline in `POST /sessions` instead. ### Ownership Your backend authenticates the end user and supplies `subject_id` (see `SubjectId`). A session can bind only reusable connections with the identical `subject_id`; a mismatch returns 403 `connection_subject_mismatch`. The platform does not authenticate end users or infer identity from provider credentials, and connections cannot be shared across subjects. The project token is a backend credential and is never forwarded to MCP servers. ### Credentials You obtain and maintain the endpoint's credentials, for example through Composio, Merge Agent Handler, your own gateway or the endpoint's own OAuth (`authorization: Bearer ...`). The platform has no provider-specific fields, OAuth consent flow, token refresh or reconnect UI, and stores only the endpoint credentials you supply, never downstream refresh tokens. Renew both the downstream authorization and the endpoint credential itself: refreshing a Slack token does not renew a gateway API key. Prefer credentials restricted to the intended user and tools, since neither a user-specific URL nor `allowed_tools` narrows what a broad gateway key can do. Headers (see `SecretHeaders`) are encrypted at rest and sent only to the registered endpoint. The credential configuration is never returned or exposed to the model, the sandbox or session history. Reflected header values and authorization tokens are removed from tool text, descriptions and opaque response data. Protocol identifiers, schema validation rules and encoded media retain their meaning, including coincidental matches with short header values; providers must keep credentials out of those fields. Redirects are not followed. Omitted or empty headers mean no authentication. `expires_at` declares when the credentials expire (null means unknown); known-expired credentials block dispatch, and empty headers reset it to null. Replace credentials for the same account with `PUT /connections/{connection_id}/credentials`; a different account or endpoint needs a new connection. Revoke with `DELETE /connections/{connection_id}`. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Request body **Required:** `true` **Content type:** `application/json` [CreateConnection](/reference/schemas/CreateConnection.md) A reusable MCP connection; see `POST /connections`. **Example:** ```json { "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "headers": { "x-api-key": "EXAMPLE_PROVIDER_KEY" }, "expires_at": null, "subject_id": "tenant_acme/user_demo" } ``` #### Responses ##### 201 Register a remote MCP connection. **Content type:** `application/json` [Connection](/reference/schemas/Connection.md) An MCP connection, without its credentials. Its `subject_id`, `url`, `scope` and owning `session_id` never change. **Example:** ```json { "id": "conn_demo", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": null, "updated_at": "2026-09-29T17:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "reusable", "session_id": null } ``` **Example:** ```json { "id": "conn_inline", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": null, "updated_at": "2026-09-29T17:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "session", "session_id": "ses_demo" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### List connections - **Method:** `GET` - **Path:** `/connections` - **Operation ID:** `get_connections` - **Tags:** Connections List the project's reusable connections, newest first, optionally filtered by exact `subject_id`. Session-owned connections are omitted; their IDs are in the owning session's `connections`. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. - **`subject_id`**: `string`, minLength: `1`, maxLength: `256`, pattern: `^[^\x00-\x1f\x7f]+$(?![\s\S])` Filter by exact application subject ID. This filter is not end-user authentication; the trusted backend controls access. Opaque, case-sensitive end-user identity within the project, supplied by your backend after it authenticates the user; include the tenant when user IDs are only unique per tenant. It is not a credential or proof of authentication. Immutable on sessions and connections. #### Responses ##### 200 List connections. **Content type:** `application/json` [ConnectionList](/reference/schemas/ConnectionList.md) **Example:** ```json { "data": [ { "id": "conn_demo", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": null, "updated_at": "2026-09-29T17:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "reusable", "session_id": null } ], "next_cursor": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve a connection - **Method:** `GET` - **Path:** `/connections/{connection_id}` - **Operation ID:** `get_connections_connection_id` - **Tags:** Connections Retrieve a reusable or session-owned connection, without its credentials. `authentication` and `expires_at` describe stored configuration, not authorization health: this does not contact the endpoint, and MCP failures are recorded in session history. A session-owned connection returns 404 once its session is deleted. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`connection_id` (required)**: `string`, pattern: `^conn_[A-Za-z0-9]+$` #### Responses ##### 200 Retrieve a connection. **Content type:** `application/json` [Connection](/reference/schemas/Connection.md) An MCP connection, without its credentials. Its `subject_id`, `url`, `scope` and owning `session_id` never change. **Example:** ```json { "id": "conn_demo", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": null, "updated_at": "2026-09-29T17:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "reusable", "session_id": null } ``` **Example:** ```json { "id": "conn_inline", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": null, "updated_at": "2026-09-29T17:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "session", "session_id": "ses_demo" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Revoke a connection - **Method:** `DELETE` - **Path:** `/connections/{connection_id}` - **Operation ID:** `delete_connections_connection_id` - **Tags:** Connections Revoke a reusable or session-owned connection: delete its stored credentials and block further MCP dispatch from every bound session. Already-dispatched calls may finish. Revocation does not undo external effects, replay calls or revoke downstream provider authorization. The record is removed (retrieval returns 404 and listing omits it) and its ID is never reused, but session bindings and history keep the ID. Revoking a session-owned connection does not delete its session. Later calls to its tools fail with `connection_revoked` as `tool.failed` with `call.connection_id`; the run continues. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`connection_id` (required)**: `string`, pattern: `^conn_[A-Za-z0-9]+$` #### Responses ##### 204 Revoke a connection. ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Replace connection credentials - **Method:** `PUT` - **Path:** `/connections/{connection_id}/credentials` - **Operation ID:** `put_connections_connection_id_credentials` - **Tags:** Connections Atomically replace the entire header map and declared expiry of a reusable or session-owned connection; this is not a merge. Omitted `expires_at` resets the expiry to unknown, and an empty header map clears authentication and expiry. Concurrent replacements are serialized and the last one wins. After the response, dispatch from every bound session uses the new credentials; already-dispatched calls may finish with the old ones. The ID, endpoint, subject, scope, bindings and tool grants do not change. Supply credentials for the same account, since the platform cannot tell whose they are; a different account or endpoint requires a new connection and session. The response confirms storage only: the endpoint is not contacted. Replacement does not retry failed calls; later calls, including in the active run, use the new credentials. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`connection_id` (required)**: `string`, pattern: `^conn_[A-Za-z0-9]+$` #### Request body **Required:** `true` **Content type:** `application/json` [ReplaceConnectionCredentials](/reference/schemas/ReplaceConnectionCredentials.md) The complete new credentials; see `PUT /connections/{connection_id}/credentials`. **Example:** ```json { "headers": { "authorization": "Bearer EXAMPLE_REPLACEMENT_TOKEN" }, "expires_at": "2026-10-01T18:00:00Z" } ``` **Example:** ```json { "headers": {} } ``` #### Responses ##### 200 Sanitized connection metadata after atomic credential replacement. **Content type:** `application/json` [Connection](/reference/schemas/Connection.md) An MCP connection, without its credentials. Its `subject_id`, `url`, `scope` and owning `session_id` never change. **Example:** ```json { "id": "conn_demo", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": "2026-10-01T18:00:00Z", "updated_at": "2026-09-29T18:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "reusable", "session_id": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Create a session - **Method:** `POST` - **Path:** `/sessions` - **Operation ID:** `post_sessions` - **Tags:** Sessions Create a session for an authenticated end user (`subject_id`), optionally with its first input. The whole request is validated first, then the session, its inline connections and its initial input are committed atomically before the response; an invalid request creates nothing. The session snapshots the agent version (the latest, resolved once, when `agent.version` is omitted), `subject_id`, environment and MCP bindings. None of these change during the session, including when the agent gets a new version. ### Input and runs Without `input`, the session starts active and idle with no sandbox. With `input`, `mode` (`steer` or `queue`) is required and either one starts the first run. Initial input follows the rules of `POST /sessions/{session_id}/inputs`: file attachments require a `sandbox` environment (otherwise 400 `files_require_sandbox`), while text and image content work with `none`. Image validation or preparation failure rejects the entire creation without storing a session, input or inline connections. A successful response does not mean the run has started or will succeed. A session has at most one active run, assigned atomically. A run is the whole agent execution started by one input, including steering applied while it is active, and can span many model generations and tool calls. The platform uses the registered model's native context window and maximum output budget, constrained by the context remaining in each request. Reasoning tokens can share the output budget with the answer. Older model context is compacted automatically; compaction can lose detail, and does not modify or delete durable history. Conversation history is durable and can outgrow the model's context window. An input or tool result that cannot fit within provider limits can still fail the run with `model_error`. Durable state does not guarantee uninterrupted execution (see "Execution loss" on `GET /sessions/{session_id}/runs/{run_id}`), but disconnecting a client or event stream never stops it. A typical run emits `session.created`, `input.accepted`, `run.started` and `input.applied`, then message, tool and file events, then `run.completed` and `session.updated` (idle). ### MCP connections Each `connections` entry either references a registered connection by `connection_id` or configures an endpoint inline (`url` with optional `headers`, `expires_at` and `name`, which defaults to `MCP tools`). Both forms require exact `allowed_tools` (remote tool names, no wildcards) and may be mixed. Omitted or empty `connections` grants no MCP access, and tools a server adds later are never granted. An entry combining both forms, or a repeated `connection_id`, returns 400. - A referenced connection must have the session's exact `subject_id` (otherwise 403 `connection_subject_mismatch`) and must be reusable: a session-owned connection cannot be bound to another session (409 `connection_session_scoped`). Reusable connections are unaffected by session deletion. - Each inline entry creates a distinct session-owned connection (endpoints and credentials are not deduplicated) that inherits `subject_id`. Use its ID with the connection retrieval, credentials and revocation endpoints. It persists across idle periods, disconnects, execution restarts and archival, cannot be bound to another session, and is revoked and removed when the session is deleted. The response's `connections` lists each binding's `connection_id`, `scope` and `allowed_tools` in request order, without credentials. Credential handling is described on `POST /connections`; replace credentials before they expire for long-lived sessions. MCP endpoints must resolve to public network addresses and use Streamable HTTP, with a 30-second timeout for each MCP request. Private and special network destinations are blocked at dispatch, so calls to their tools fail with `mcp_connection_failed`; registration does not verify reachability. The platform opens a server-to-client event stream when the endpoint supports it. After a transient stream failure, it makes up to five consecutive reconnect attempts. A response stream with event IDs can resume from the last received ID, subject to the request timeout. Reconnecting resumes response delivery without resubmitting the tool request, automatically refreshing tokens or replaying failed calls. A timeout or lost response can leave external effects uncertain; see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`. ### Tool access The platform enforces granted built-ins, declared functions and MCP grants at dispatch; any other tool call returns an error result to the agent. MCP tools are identified by connection and remote name, so they may share names with functions: the agent sees each granted MCP tool, and `ToolCall.tool` records it, as `mcp_{connection_id}_{remote_name}`, for example `mcp_conn_9f2c41d07ab84e6d8c3b5a1e2f7d6c90_search_documents` with `connection_id` `conn_9f2c41d07ab84e6d8c3b5a1e2f7d6c90`; the remote name is everything after that prefix. Each run connects to its bound endpoints and discovers their tools before its first model request. Granted tools an endpoint does not offer are not exposed. An endpoint that cannot be set up never fails the run: the agent still sees each of that connection's granted tools, without the server's description or argument schema, and each call retries setup and fails with its error code (see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`) while setup keeps failing. If a retried setup succeeds, the call proceeds; a granted tool the endpoint does not offer then fails with `mcp_tool_error`. Dispatch uses a connection's current credentials, so replacement and revocation apply to later calls. Neither the project token nor connection credentials ever reach the sandbox. The sandbox network allowlist does not grant MCP tools, and MCP grants do not give the sandbox network access. Function calls are executed by your application (see `POST /sessions/{session_id}/tool-results`); while they are pending, the run stays active in `waiting_for_tools` and queued input keeps waiting. There are no webhooks, per-call approval or permission callbacks, budget controls, or agent-spawning, delegation or session-coordination primitives; coordinate sessions from your backend. ### Sandbox `environment` defaults to `{type: sandbox}`: an isolated sandbox is provisioned lazily on first use and reused while available. The environment is a per-session recipe; there is no reusable environment resource. Shell and file tools run in the sandbox. With `{type: none}`, no sandbox is ever provisioned, and a granted `shell`, `read_file`, `apply_patch` or `view_image` call fails with `sandbox_required` as a tool error the agent can handle (viewing images also requires an image-capable model). Sandbox files, memory, background processes and sockets have no continuity guarantee after loss or expiry; a lost sandbox is not recreated and interrupted commands are not resumed. Code the agent runs to coordinate tool calls has no wall-clock deadline but has a CPU budget, 30,000 ms by default and set by the platform operator, that excludes time spent waiting for tools. Exhausting it interrupts the code and its pending waits, keeps output already emitted and returns a tool error the agent can handle. Interruption does not undo effects or establish whether dispatched operations stopped. Shell commands and application requests keep their own deadlines. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Request body **Required:** `true` **Content type:** `application/json` [CreateSession](/reference/schemas/CreateSession.md) Omitted `environment` means `{type: sandbox}`. See `POST /sessions`. **Example: chat** Empty text-only session ```json { "agent": { "id": "agt_demo", "version": 1 }, "title": "First conversation", "environment": { "type": "none" }, "subject_id": "example/user_123" } ``` **Example: research** Research with saved outputs ```json { "agent": { "id": "agt_demo", "version": 1 }, "title": "Research report", "environment": { "type": "sandbox", "network": { "allowed_hosts": [] } }, "subject_id": "example/user_123" } ``` **Example: mcp** Session with remote MCP tools ```json { "agent": { "id": "agt_demo", "version": 1 }, "environment": { "type": "none" }, "connections": [ { "url": "https://mcp.example.com/users/user_demo/mcp", "headers": { "authorization": "Bearer EXAMPLE_USER_SCOPED_MCP_TOKEN" }, "allowed_tools": [ "search_documents" ] } ], "subject_id": "example/user_123" } ``` #### Responses ##### 201 Session with resolved MCP connection IDs and exact tool grants. Inline credentials are never returned. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example:** ```json { "id": "ses_demo", "title": "First conversation", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Answer the user's questions helpfully.", "tools": [] }, "environment": { "type": "none" }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "example/user_123", "pending_tool_calls": [] } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### List sessions - **Method:** `GET` - **Path:** `/sessions` - **Operation ID:** `get_sessions` - **Tags:** Sessions List the project's sessions, newest first (ties broken by ID), optionally filtered by exact `subject_id`. Session `status` describes activity, not outcome; runs record outcomes. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. - **`subject_id`**: `string`, minLength: `1`, maxLength: `256`, pattern: `^[^\x00-\x1f\x7f]+$(?![\s\S])` Filter by exact application subject ID. This filter is not end-user authentication; the trusted backend controls access. Opaque, case-sensitive end-user identity within the project, supplied by your backend after it authenticates the user; include the tenant when user IDs are only unique per tenant. It is not a credential or proof of authentication. Immutable on sessions and connections. #### Responses ##### 200 List sessions. **Content type:** `application/json` [SessionList](/reference/schemas/SessionList.md) **Example:** ```json { "data": [ { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } ], "next_cursor": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve a session - **Method:** `GET` - **Path:** `/sessions/{session_id}` - **Operation ID:** `get_sessions_session_id` - **Tags:** Sessions Read the session's configuration snapshot, session status, active run and pending application tool calls. State changes and run assignment are serialized, with at most one active run. ### Session and run state | `status` | Meaning | | ---------- | --------------------------------------------------------------------------------------------- | | `active` | Agent execution is allowed. With null `active_run_id`, the session is idle. | | `pausing` | Pause was requested; already-started model and platform tool work is settling. | | `paused` | No further agent execution starts until resume. The active run and queued input are retained. | | `archived` | Read-only, with no active run. | `active_run_status` is null without an active run, otherwise `running`, `waiting_for_tools`, `interrupted` or `stopping`. A paused run may still have unresolved application tool calls; results and their deadlines continue to be accepted and enforced. Run state describes the retained work, while session status controls whether more work may execute. Normal completion starts the oldest queued input only while the session is active. Stop, failure or execution loss pauses the session and retains queued input. Execution loss leaves an interrupted active run with uncertain tool outcomes; stop it before resume. `POST /sessions/{session_id}/resume` continues a deliberately paused run or starts queued input in a new run after stop/failure. ### Pending application tool calls `pending_tool_calls` lists the active run's unresolved application calls in request order; it is empty unless `active_run_status` is `waiting_for_tools` or `interrupted`. Requests, their deadlines and the move to `waiting_for_tools` are committed together before `tool.requested` is emitted. Resolved, expired and cancelled calls leave the list but remain in history. When results or expiry have resolved every call of a waiting run, the run returns to `running` (with `session.updated`). An interrupted run stays interrupted even after every call resolves. Reading or replaying events never executes tools. Pending calls and their deadlines survive disconnects of clients, event streams and your workers, so recover them from this response after reconnecting. Before executing a request you saw earlier, check that it is still listed here, and deduplicate execution by call ID. Results, deadlines and cancellation are described on `POST /sessions/{session_id}/tool-results`. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Responses ##### 200 Retrieve a session. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example: idle** Idle session ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } ``` **Example: waiting_for_application** Recover an application tool request ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_customer", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] }, "environment": { "type": "none" }, "status": "active", "active_run_id": "run_demo", "active_run_status": "waiting_for_tools", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 20, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Delete a session - **Method:** `DELETE` - **Path:** `/sessions/{session_id}` - **Operation ID:** `delete_sessions_session_id` - **Tags:** Sessions Delete a session with no active run; while a run is active or stopping, return 409. Before the 204 response, access to the session, its history and its output files is removed, and its session-owned connections are revoked and removed with their credentials. Later reads of any of them return 404, and open event streams close without a final event. The session's sandbox is released. Reusable connections, uploads, agents and output copies already attached to other sessions' inputs are unaffected; this session's own copies of attached files are removed. Deletion does not revoke downstream provider authorization or undo external effects. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Responses ##### 204 Delete a session. ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Stop the active run - **Method:** `POST` - **Path:** `/sessions/{session_id}/stop` - **Operation ID:** `post_sessions_session_id_stop` - **Tags:** Sessions Stop the run named by `run_id`. If it is the active run (`running` or `waiting_for_tools`), one transition moves the run to `stopping`, requests a pause and cancels the run's unresolved tool calls, both pending application calls and running platform tools (`tool.cancelled` with `tool_call_cancelled`), and the response is 202; repeating the stop while it is stopping also returns 202. If the run is interrupted, stopping it synchronously cancels its pending calls and unapplied steering, marks it `stopped`, leaves the session paused with no active run, and returns 200. If the run has already finished, the response is 200 with no change, so retrying a stop never affects newer work. A run of another session returns 404, and any other run returns 409. While stopping, steer input returns 409 and queue input is retained until resume. The stop completes asynchronously with `run.stopped`, also if execution is lost after the stop was accepted. The session is then paused with no active run and queued input retained; steering not yet applied is cancelled. A stop never starts queued input: `POST /sessions/{session_id}/resume` starts the oldest queued input in a new run, and never retries the stopped run. After `run.stopped`, the platform dispatches no more model calls or tools for the run. A cancelled platform tool's later outcome is discarded; cancellation does not establish whether it ran or had effects. New application results return 409, while identical retries of results accepted earlier still return their receipts. Stop does not undo effects, delete history, stop code already running in your application, or guarantee that background sandbox processes end. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Request body **Required:** `true` **Content type:** `application/json` [StopRun](/reference/schemas/StopRun.md) The run to stop, named so that a retried request cannot stop newer work. **Example:** ```json { "run_id": "run_demo" } ``` #### Responses ##### 200 The interrupted run was stopped synchronously, or the target run was already terminal. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } ``` **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_customer", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] }, "environment": { "type": "none" }, "status": "active", "active_run_id": "run_demo", "active_run_status": "waiting_for_tools", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 20, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` ##### 202 Stop the active run. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "pausing", "active_run_id": "run_demo", "active_run_status": "stopping", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Pause a session - **Method:** `POST` - **Path:** `/sessions/{session_id}/pause` - **Operation ID:** `post_sessions_session_id_pause` - **Tags:** Sessions Suspend further agent execution while retaining the active run and queued input. An idle session becomes `paused` immediately (200). With an active run, the response is 202 with `pausing`; already-started model calls and platform tools settle before the session becomes `paused`, reported by `session.updated`. Once paused, no new model calls, platform tools or application tool requests start until resume. Pause can wait indefinitely for an in-flight operation; stop remains available to abandon the run. Queued input and application tool results remain accepted while pausing or paused. Existing application tool deadlines continue to run; resolved results are retained without starting further agent execution. Steering returns 409 `session_paused`. A pause does not freeze sandbox background processes, terminate application code or undo external effects. If the run completes while pausing, the session still becomes paused and queued input stays retained. Repeating pause returns the current state (202 while pausing, otherwise 200). Archived sessions return 409. Pause retains execution capacity; many paused runs can delay other sessions. Execution loss still interrupts the run; resume cannot recover interrupted execution. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Responses ##### 200 The session is paused. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example:** ```json { "id": "ses_demo", "title": "First conversation", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Answer the user's questions helpfully.", "tools": [] }, "environment": { "type": "none" }, "status": "paused", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 2, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "example/user_123", "pending_tool_calls": [] } ``` ##### 202 Pause is pending a safe execution boundary. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example:** ```json { "id": "ses_demo", "title": "First conversation", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a visible customer.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" } }, "required": [ "customer_id" ], "additionalProperties": false } } ] }, "environment": { "type": "none" }, "status": "pausing", "active_run_id": "run_demo", "active_run_status": "waiting_for_tools", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 5, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "example/user_123", "pending_tool_calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Resume a session - **Method:** `POST` - **Path:** `/sessions/{session_id}/resume` - **Operation ID:** `post_sessions_session_id_resume` - **Tags:** Sessions Change a paused session to `active`. Its retained active run continues with the same run ID and original tool call IDs, without replaying settled tools. If there is no active run, the oldest queued input starts a new run; without queued input, the session becomes active and idle. Subsequent queued inputs start one run each in acceptance order. Repeating resume on an active session succeeds without changing execution. Returns 409 while pausing or stopping, for archived sessions, and for interrupted runs (`run_interrupted`). Stop an interrupted run before resuming. Resume never retries stopped or failed runs or recreates lost sandboxes. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Responses ##### 200 The session is active. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } ``` **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_customer", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] }, "environment": { "type": "none" }, "status": "active", "active_run_id": "run_demo", "active_run_status": "waiting_for_tools", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 20, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Archive a session - **Method:** `POST` - **Path:** `/sessions/{session_id}/archive` - **Operation ID:** `post_sessions_session_id_archive` - **Tags:** Sessions Make an idle session read-only; while a run is active or stopping, return 409. Archiving atomically cancels queued inputs (reason `session_archived`), and event streams close after `session.archived`. The sandbox is released without collecting further outputs, so unsaved sandbox files and processes are lost. Repeating the request succeeds; there is no unarchive. An archived session rejects input, pause, resume and other new work, but still acknowledges identical retries of tool results accepted earlier. History, output files, accepted input file copies and connections are kept, including session-owned connections and their credentials; revoke those explicitly or delete the session to remove them. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Responses ##### 200 Archive a session. **Content type:** `application/json` [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "archived", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Submit application tool results - **Method:** `POST` - **Path:** `/sessions/{session_id}/tool-results` - **Operation ID:** `post_sessions_session_id_tool_results` - **Tags:** Tools Submit results of application function calls of run `run_id`. Your application executes the functions: find requests in `tool.requested` events or in the session's `pending_tool_calls`. Only application function results are accepted here, never built-in or MCP results. ### Validation Each result names a pending call by `call_id` (the call's `id`) and has either `success: true` with `output` (any JSON value, including null) or `success: false` with `error`. The whole batch is validated before anything is stored; a rejected batch stores nothing and changes nothing. - 400 for a duplicate `call_id` in the batch, and 400 `invalid_tool_result` for a platform-executed call. - 404 `not_found` for a call outside this session. - 409 `tool_call_run_mismatch` for a call of another run. - 409 `tool_call_not_pending` for a new result when the call is no longer requested by the active `waiting_for_tools` or `interrupted` run, or the server time is not strictly before its `deadline_at`. - 409 `tool_result_conflict` for a result that differs from one already accepted. ### Acceptance Before the 200 response, accepted results and their receipts are stored, `tool.completed` or `tool.failed` is emitted for each newly resolved call, and the call leaves `pending_tool_calls`. While the run is executing, each result is available to the agent without waiting for other pending calls, so the agent may request dependent tools while some calls are still pending. Interrupted runs retain accepted results without restarting execution. The same run continues when executing: no new run is created and queued input stays queued. An application error is a tool error the agent can handle without failing the run. A 200 response does not mean the agent has used the result, will generate immediately or will finish uninterrupted. Result acceptance, stop, expiry, execution loss and other run transitions are serialized. If the run stops or fails first, its pending calls are cancelled and new results return 409 `tool_call_not_pending`. A result accepted first keeps a valid receipt even if the run then fails before using it; neither the result nor its retry restarts the run. ### Deadlines and cancellation A request expires ten minutes after it is persisted, at `deadline_at`. Disconnects, worker restarts, new input and credential replacement do not extend it. Expiry fails the call with `tool_result_timeout` (`tool.failed`); the agent receives that error without waiting for other calls and may continue the same run. Stop or any other run termination cancels pending calls with `tool_call_cancelled` (`tool.cancelled`). Expiry and cancellation neither stop your code nor undo its effects, and do not establish whether it ran. ### Retries and duplicate execution Resubmitting an accepted result with structurally identical JSON (object key order is ignored; array order is not) returns the original receipt without new events, even after the run has ended or the session was archived; a deleted session returns 404. A batch may mix such retries with new results and remains atomic. The platform never reissues a request: call IDs are stable. Execution loss retains pending requests and their original deadlines; accepting results or expiring requests never resumes an interrupted run. Events may be delivered more than once, so deduplicate execution by session, run and call ID, store each output or error, and resubmit the stored result after an ambiguous response. Idempotent submission does not make your side effects exactly-once; reconcile uncertain external operations in your system instead of rerunning them. ### Authorization Authorize each call with the session's `subject_id` and your own user mapping, never with model-generated user IDs or arguments. Keep application credentials in your backend. Arguments, outputs and errors enter model context and session history, so redact secrets. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Request body **Required:** `true` **Content type:** `application/json` [SubmitToolResults](/reference/schemas/SubmitToolResults.md) Results for calls of run `run_id`, each `call_id` at most once; see `POST /sessions/{session_id}/tool-results`. **Example: success** Successful application result ```json { "run_id": "run_demo", "results": [ { "call_id": "call_customer", "success": true, "output": { "customer_id": "customer_123", "name": "Example Customer" } } ] } ``` **Example: failure** Application error result ```json { "run_id": "run_demo", "results": [ { "call_id": "call_customer", "success": false, "error": { "code": "customer_not_found", "message": "No visible customer matched the requested ID." } } ] } ``` #### Responses ##### 200 Results durably accepted or identical stored results acknowledged. **Content type:** `application/json` [ToolResultsReceipt](/reference/schemas/ToolResultsReceipt.md) The stored call records of this submission, in the order of the submitted results. An identical retry returns the same records. **Example:** ```json { "session_id": "ses_demo", "run_id": "run_demo", "calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "completed", "result": { "customer_id": "customer_123", "name": "Example Customer" }, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` **Example:** ```json { "session_id": "ses_demo", "run_id": "run_demo", "calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "failed", "result": null, "error": { "code": "customer_not_found", "message": "No visible customer matched the requested ID." }, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Send or queue input - **Method:** `POST` - **Path:** `/sessions/{session_id}/inputs` - **Operation ID:** `post_sessions_session_id_inputs` - **Tags:** Inputs Send input to the session. `mode` (`steer` or `queue`) is required and has no default; a missing or invalid mode returns 400. The input is durably recorded before the 202 response, and acceptance is serialized with other inputs and session transitions. Acceptance does not mean the input has been applied or will succeed: the input record and `input.*` events report its `status` (`accepted`, `applied` or `cancelled`) and `run_id`. ### Modes | Session state | `steer` | `queue` | | --------------------------------------- | ------------------------------------------------------------------------------------------ | -------------------------------------- | | `active`, with a running or waiting run | Bound to the active run; applied at the next input boundary, possibly after pending tools. | Waits for a later run of its own. | | `active`, no active run | Starts a run. | Starts a run. | | `pausing` or `paused` | 409 `session_paused`; resume first. | Retained until resume. | | Interrupted active run | 409 `run_interrupted`; stop and resume first. | Retained without restarting execution. | | Stopping active run | 409 `run_stopping`. | Retained until resume. | | `archived` | 409 | 409 | A run applies all steering bound to it before it completes normally; if it stops or fails first, unapplied steering is cancelled with a recorded reason. Queued inputs start one run each, in acceptance order, while the session is active. Stop, failure and interruption keep queued input and pause the session. Interruption also retains unapplied steering already bound to the run. ### Reasoning effort `reasoning_effort` is optional and applies to this input. A level unsupported by the session's model returns 400 `unsupported_reasoning_effort`, with nothing accepted. When omitted, the platform resolves a supported default at acceptance: `medium` for reasoning models that support it, otherwise a supported model default, and `off` for models without reasoning. The returned `Input` and its events always include the resolved level; omission does not inherit a previous input's effort. Effort takes effect when the input is applied. A model request already in progress keeps its effort. Subsequent model requests, including those after tool results, use the last applied input's effort until another input is applied. If several inputs are incorporated before one model request, the last in acceptance order wins. Queued input changes effort only for its own run, and cancelled input never changes effort. The platform uses the model's native reasoning mode, including adaptive thinking when required, and applies effort changes at model boundaries that support them. ### Image inputs Send `{type: image, file_id: ...}` to give an uploaded or saved output image directly to the session's model. Images work with either environment, including `none`, and never provision a sandbox or create a mounted path. Image-only input is supported. The model receives text and images in their `content` order; `file` content continues to give it a sandbox path. To provide both visual input and filesystem access, include separate `image` and `file` blocks referencing the same file. Image support and the per-image encoded payload limit are listed on `AgentConfig.model`. A model without image support returns 400 `unsupported_image_input`. Image bytes must decode as a static PNG, JPEG or WebP; the upload's declared `media_type` and filename do not determine validity or the MIME type sent to the model. Corrupt data, animation and other formats return 400 `invalid_image`. The platform does not resize or recompress images, and the original downloadable bytes stay unchanged. GIF, PDF, image URLs, inline base64 and an image-detail setting are not supported. Image input exceeding its catalog's per-image base64 payload limit, image count or request-size budget returns 400 `image_limits_exceeded`. The encoded payload limit is a platform limit drawn from Pi's catalog preprocessing profile, rather than a provider's hard image-file limit. For the registered image models it is currently 4,718,592 base64 bytes (4.5 MiB), independent of the 16 MiB upload limit. Decoded image data is also limited to 64,000,000 pixels and a 268,435,456-byte (256 MiB) pixel buffer; exceeding either returns the same error. Current registered catalog limits for image-capable OpenAI models are 1,500 images and 512 MiB of serialized payload per request. Registered Anthropic models allow 600 images and 32 MiB per request, except `anthropic/claude-haiku-4-5`, `anthropic/claude-haiku-4-5-20251001`, `anthropic/claude-opus-4-5` and `anthropic/claude-opus-4-5-20251101`, which allow 100 images and the same 32 MiB. Admission estimates request size from the input, agent configuration, encoded image data and a 4 KiB reserve; the complete provider payload is checked before each model request. Images are validated before acceptance. A missing or another project's file returns 404. A failure reading or preparing image bytes returns 500 `image_preparation_failed`. Rejection leaves no input, run or input events. Source files and attachment snapshots have the same retention and deletion rules as file attachments below, including cancelled inputs and source output deletion. Returned inputs and events retain the source `file_id`; they never contain image bytes or internal storage locations. Each model request also checks the selected catalog's aggregate image-count and serialized request-size limits, including earlier context and coalesced steering. Exceeding those limits fails the run with `model_error`; acceptance does not reserve space in a future model request. Images remain in durable history, but automatic compaction summarizes conversational text rather than image pixels, so visual detail can leave the model's active context after compaction. If accepted image content cannot be loaded before application, the run fails with `image_input_failed` and that input stays unapplied: it and the run's other unapplied steering are cancelled, already applied input stays applied, and queued input is kept with the session paused. ### File attachments File content requires a `sandbox` environment: with `none`, the request returns 400 `files_require_sandbox` before any file ID is checked, and nothing is stored. Attachments are validated at acceptance. Acceptance retains immutable attachment content and metadata for this session and is serialized with source deletion: a source deleted first returns 404 with nothing accepted. The retained attachment lasts as long as this session, including after archival, input cancellation or deletion of the source upload or output file. The input keeps the source `file_id` (which may later return 404); the attachment is not a separate `File`. Before an input is applied, each `file` block is copied to `/workspace/inputs/{input_id}/{attachment_index}/{filename}`, where `attachment_index` is its zero-based position in the whole `content` array (text and images included) and `filename` is the sanitized basename. Each path is a writable working copy: shell and file tools may change or remove it without changing the immutable upload, saved output source or durable input copy. Copies at different attachment positions are independent. The model receives each file attachment's `file_id`, index, filename and sandbox path with the applied input. A cancelled input may never be copied to the sandbox. If a sandbox copy fails, including because the sandbox was lost (it is never recreated), the run fails with `input_mount_failed` and the input is never applied: it and the run's other unapplied steering are cancelled, already applied input stays applied, and queued input is kept with the session paused. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Request body **Required:** `true` **Content type:** `application/json` [SendInput](/reference/schemas/SendInput.md) Input for an existing session; `mode` is required. See `POST /sessions/{session_id}/inputs` for how each mode behaves. **Example:** ```json { "mode": "queue", "reasoning_effort": "medium", "content": [ { "type": "text", "text": "Afterwards, run the findings into a checklist." } ] } ``` #### Responses ##### 202 Send or queue input. **Content type:** `application/json` [Input](/reference/schemas/Input.md) `accepted` means durably recorded; `applied` means the agent has taken it into model context. Steering is bound to its run on acceptance and never reassigned; queued input gets a `run_id` when its run starts. **Example:** ```json { "id": "inp_demo", "session_id": "ses_demo", "content": [ { "type": "text", "text": "Afterwards, run the findings into a checklist." } ], "mode": "queue", "reasoning_effort": "medium", "status": "accepted", "run_id": null, "created_at": "2026-09-29T17:00:00Z", "applied_at": null, "cancelled_at": null, "cancellation_reason": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 415 The request body is not sent as the operation's media type. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unsupported_media_type", "message": "Send the request body as application/json.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### List inputs - **Method:** `GET` - **Path:** `/sessions/{session_id}/inputs` - **Operation ID:** `get_sessions_session_id_inputs` - **Tags:** Inputs List the session's inputs in acceptance order, optionally filtered by `status`. Cancelled inputs remain listed with their reason. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. - **`status`**: `string`, possible values: `"accepted", "applied", "cancelled"` #### Responses ##### 200 List inputs. **Content type:** `application/json` [InputList](/reference/schemas/InputList.md) **Example:** ```json { "data": [ { "id": "inp_demo", "session_id": "ses_demo", "content": [ { "type": "text", "text": "Review the onboarding flow and save your findings under /workspace/outputs/." } ], "mode": "steer", "reasoning_effort": "medium", "status": "accepted", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z", "applied_at": null, "cancelled_at": null, "cancellation_reason": null } ], "next_cursor": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve an input - **Method:** `GET` - **Path:** `/sessions/{session_id}/inputs/{input_id}` - **Operation ID:** `get_sessions_session_id_inputs_input_id` - **Tags:** Inputs Read an input's status, run assignment and any cancellation reason. Steering is bound to its run on acceptance; queued input gets a `run_id` when its run starts. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`input_id` (required)**: `string`, pattern: `^inp_[A-Za-z0-9]+$` #### Responses ##### 200 Retrieve an input. **Content type:** `application/json` [Input](/reference/schemas/Input.md) `accepted` means durably recorded; `applied` means the agent has taken it into model context. Steering is bound to its run on acceptance and never reassigned; queued input gets a `run_id` when its run starts. **Example:** ```json { "id": "inp_demo", "session_id": "ses_demo", "content": [ { "type": "text", "text": "Review the onboarding flow and save your findings under /workspace/outputs/." } ], "mode": "steer", "reasoning_effort": "medium", "status": "accepted", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z", "applied_at": null, "cancelled_at": null, "cancellation_reason": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Cancel queued input - **Method:** `DELETE` - **Path:** `/sessions/{session_id}/inputs/{input_id}` - **Operation ID:** `delete_sessions_session_id_inputs_input_id` - **Tags:** Inputs Cancel a queued input that has no run yet. Cancellation is serialized with dispatch: once the input has a run, the response is 409; use `POST /sessions/{session_id}/stop` to stop running work. The record remains with status `cancelled` and `input.cancelled` is emitted. Repeating the cancellation succeeds. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`input_id` (required)**: `string`, pattern: `^inp_[A-Za-z0-9]+$` #### Responses ##### 204 Cancel queued input. ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 409 Operation conflicts with current state. Inspect error.code. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "state_conflict", "message": "Operation conflicts with current state. Inspect error.code.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### List runs - **Method:** `GET` - **Path:** `/sessions/{session_id}/runs` - **Operation ID:** `get_sessions_session_id_runs` - **Tags:** Runs List the session's runs, oldest first. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. #### Responses ##### 200 List runs. **Content type:** `application/json` [RunList](/reference/schemas/RunList.md) **Example:** ```json { "data": [ { "id": "run_demo", "session_id": "ses_demo", "status": "running", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": null } ], "next_cursor": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve a run - **Method:** `GET` - **Path:** `/sessions/{session_id}/runs/{run_id}` - **Operation ID:** `get_sessions_session_id_runs_run_id` - **Tags:** Runs Read a run's status, messages, output files and error. `completed` means execution ended normally, not that every tool succeeded or that the objective was met; `failed` carries an `error` code; `interrupted` records execution loss and stays active until stopped; `stopped` follows an accepted stop. An idle session alone says nothing about the outcome. ### Failures Every run uses the model API key selected in its session configuration. If that stored key was deleted or cannot be loaded, the run fails with `model_api_key_unavailable` and no model request is made. There is no fallback credential. Create a new agent version and session to select another key. Transient model provider failures may be retried up to three times within the active run, with exponential backoff starting at two seconds. A provider failure that cannot be retried or persists after those attempts fails the run with `model_error`. Retrying a model request does not replay completed tool calls. A failed tool call does not necessarily fail the run: the agent may report it or continue with other tools. When a run fails, one transition records the failure, cancels its unresolved tool calls and unapplied steering, and leaves the session idle with queued input kept and the session paused. Failed runs and tools are not retried or replayed automatically, and repairing credentials neither resumes the run nor releases the queue. Resume the session, then send fresh input or start retained queued input in a new run. External operations can have uncertain results after connection failures; tool failures report that uncertainty where known. The platform makes no exactly-once, rollback or task-correctness guarantee for external effects. When a run stops, fails or completes, platform tools still running are cancelled with `tool_call_cancelled` and their later outcomes are discarded; cancellation does not establish whether they ran or had effects. ### Execution loss If the platform detects that a `running` or `waiting_for_tools` run's execution was lost, one transition marks the run `interrupted`, pauses the session, records `harness_lost` and emits `run.interrupted`. The run keeps its active run ID and null `ended_at`. A run whose stop was already accepted is finalized as `stopped` instead, and finished runs are unaffected. Interrupted runs never resume automatically. Resume cannot recover interrupted execution. Stop the interrupted run to abandon it, then resume the session before sending fresh steer input or starting queued input in a new run. Neither queued input, application results, request expiry nor credential replacement restarts execution. Committed history, accepted tool-result receipts, pending application calls and their original deadlines, unapplied steering, queued input, connection credentials and saved files survive. Platform tools dispatched before the loss stay `running` with unknown outcomes. Stop cancels remaining pending and running calls and unapplied steering. Disconnects of clients, event streams or your application workers never cause `harness_lost`. Interruption does not establish whether dispatched tools had external effects, and does not stop code running in your application. A stopped interrupted script is not replayed when fresh work starts. ### Output files On normal completion, files under `/workspace/outputs/` are saved before `run.completed` and listed in `output_file_ids`; see `GET /sessions/{session_id}/files`. Stopped and failed runs save no new outputs. ### MCP failures A failed MCP tool call is recorded as `tool.failed` with `call.connection_id` and a sanitized `call.error.code`. MCP failures never fail the run: when initialization or tool discovery fails, the connection's calls fail with the codes below, and the agent may report the failure or continue with other tools. Transient event-stream failures may reconnect to resume response delivery as described on `POST /sessions`; failed calls are not resubmitted and credentials are not refreshed automatically. These codes are unrelated to the API's own 401 and 403 responses, which concern your project token. | Code | Meaning and caller action | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `connection_credentials_expired` | The declared expiry has passed; replace the endpoint credentials before submitting further work. | | `mcp_authentication_failed` | The MCP endpoint returned HTTP 401; repair its credential or complete the provider's reconnect flow. | | `mcp_permission_denied` | The MCP endpoint returned HTTP 403; inspect the provider's permissions. Reconnecting alone may not fix it. | | `connection_revoked` | This connection was deleted; it cannot be used again. | | `mcp_connection_failed` | MCP initialization or discovery could not complete for a non-authentication reason, such as a transport failure or a blocked destination. Inspect the endpoint before submitting more work. | | `mcp_tool_error` | The server returned an MCP tool error result or a JSON-RPC error for the tool request. Numeric JSON-RPC codes are normalized to this string code. A provider may report downstream authorization problems this way; there is no universal reconnect signal. Use the sanitized result and the provider's account-status API to decide whether renewed consent is needed. | ### Sandbox loss A lost sandbox emits `sandbox.lost`, and affected tool calls fail. The agent may report the error or finish with tools that do not need the sandbox; otherwise the run fails with the session paused. The sandbox is never recreated, interrupted commands are not resumed, and later use of it fails. History and saved output files remain; unsaved files, memory, background processes and sockets are not restored. To continue, create a new session and attach the saved output files. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` #### Responses ##### 200 Retrieve a run. **Content type:** `application/json` [Run](/reference/schemas/Run.md) One agent execution, started by one input and including steering applied while it is active; it can span many model generations and tool calls. `running`, `waiting_for_tools`, `interrupted` and `stopping` are active states with null `ended_at`; `completed`, `failed` and `stopped` are terminal. See `GET /sessions/{session_id}/runs/{run_id}`. **Example:** ```json { "id": "run_demo", "session_id": "ses_demo", "status": "running", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": null } ``` **Example:** ```json { "id": "run_demo", "session_id": "ses_demo", "status": "waiting_for_tools", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Read committed history - **Method:** `GET` - **Path:** `/sessions/{session_id}/events` - **Operation ID:** `get_sessions_session_id_events` - **Tags:** Events List the session's committed events in strictly increasing `sequence`, starting from the earliest retained event; new events appear on later pages. The log is append-only, and event IDs and sequences are stable across pages and stream reconnects. There is no ordering across sessions. History excludes secrets, private model reasoning and `message.delta` previews; `message.completed` holds the authoritative message. Reading history never re-executes or retries anything, and an event such as `tool.requested` does not mean any work has run. Pagination cursors differ from the event IDs that resume a stream; an expired cursor returns 410. A deleted session returns 404 and leaves no final event. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. #### Responses ##### 200 Read committed history. **Content type:** `application/json` [EventList](/reference/schemas/EventList.md) **Example:** ```json { "data": [ { "id": "evt_1", "session_id": "ses_demo", "sequence": 1, "created_at": "2026-09-29T17:00:00Z", "type": "session.created", "data": { "session": { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } } } ], "next_cursor": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Stream session events - **Method:** `GET` - **Path:** `/sessions/{session_id}/events/stream` - **Operation ID:** `get_sessions_session_id_events_stream` - **Tags:** Events Stream the session's events as `text/event-stream`. To resume, pass a committed event ID as `after` or `Last-Event-ID` (different values in both return 400): retained events after it are replayed, then live events follow without a gap. An unknown event ID, or one from another session, returns 400; an expired one returns 410. Without a cursor, the stream starts with live events. Each committed event is sent as a frame whose `id` is the event ID, `event` is its type and `data` is the JSON-encoded event (see `StreamItem`). Frames can repeat across reconnects, so deduplicate by event ID. Replay never re-executes or retries anything: before executing a replayed `tool.requested`, check that the call is still in the session's `pending_tool_calls`. Heartbeat comments carry no event data. ### Text previews With `include_deltas=true`, the stream also carries `message.delta` frames: text previews without an `id`, which are never stored or replayed and never advance the resume cursor. For each message on a connection, delivered chunks start at `index` 0 and are contiguous; if a chunk is lost or a bounded buffer overflows, previews for that message stop. Previews cover only messages that begin after the response headers are sent, so open the stream before submitting input. Text arrives in chunks as generation progresses; previews can be missing under overload or transport failure, and no latency is guaranteed. Secrets, tool arguments and private reasoning are never previewed. Append each delta's `text` to content block `content_index` of message `message_id`. When `message.completed` arrives for that ID, replace the preview with its content; no more deltas follow for it. A message is completed as soon as its generation finishes, before its requested tools run, and stays valid if the run later fails or stops. An interrupted generation can leave a preview that never completes: discard unfinished previews on `run.completed`, `run.failed`, `run.interrupted` or `run.stopped`. After reconnecting, restore messages from history; partial previews are not replayed. ### Lifetime The stream stays open while the session is idle and closes after `session.archived` or deletion. Disconnecting never affects execution, and neither a disconnect nor an idle session indicates success. Errors before streaming starts are ordinary JSON responses; a failure after the response headers closes the connection. To reconnect, reopen the stream with the last committed event ID; preview frames never change it. If that cursor has expired, open a live stream and buffer its events, read the current session and history, reconcile by event ID, then apply the buffered events. ### Python streaming consumer Select the **Python (streaming)** code sample. It uses `requests` with `stream=True` and parses SSE incrementally; a generic `requests.get()` snippet buffers the response and cannot consume this long-lived stream. Install `requests` in your application's Python environment and set `PLATFORM_API_BASE_URL`, `PLATFORM_API_KEY` and `SESSION_ID`. Open the consumer before submitting input from another backend request. The sample prints both previews and committed events. Only committed event IDs advance its resume cursor. Its cursor and deduplication set are in memory; for an application, replace printing with event application and persist the committed cursor atomically with your application state. Restore that cursor with `LAST_EVENT_ID` after a process restart. On `410`, use the recovery procedure above instead of repeatedly retrying the expired cursor. Replace previews with `message.completed` and discard unfinished previews on run completion, failure, interruption or stopping. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Query parameters - **`after`**: `string`, pattern: `^evt_[A-Za-z0-9]+$` Exclusive durable event ID cursor. - **`include_deltas`**: `boolean`, default: `false` Include best-effort text previews. #### Header parameters - **`Last-Event-ID`**: `string`, pattern: `^evt_[A-Za-z0-9]+$` Exclusive durable event ID; standard SSE reconnect header. #### Responses ##### 200 Stream session events. **Headers:** - **`Cache-Control`** Do not cache or transform the event stream. `string`, const: `"no-cache, no-transform"` - **`X-Accel-Buffering`** Disable buffering in compatible reverse proxies. `string`, const: `"no"` **Content type:** `text/event-stream` **Example:** ```json "id: evt_1\nevent: session.created\ndata: {\"id\":\"evt_1\",\"session_id\":\"ses_demo\",\"sequence\":1,\"created_at\":\"2026-09-29T17:00:00Z\",\"type\":\"session.created\",\"data\":{\"session\":{\"id\":\"ses_demo\",\"title\":\"Review the onboarding flow\",\"agent\":{\"id\":\"agt_demo\",\"version\":1},\"agent_config\":{\"model\":\"openai/gpt-6.1-sol\",\"model_api_key_id\":\"mkey_demo\",\"instructions\":\"Research the request and save a report under /workspace/outputs/.\",\"tools\":[\"read_file\",\"apply_patch\",\"web_search\"]},\"environment\":{\"type\":\"sandbox\",\"image\":\"managed-default\",\"network\":{\"allowed_hosts\":[]}},\"status\":\"active\",\"active_run_id\":null,\"active_run_status\":null,\"pending_input_count\":0,\"sandbox_id\":null,\"last_event_sequence\":1,\"created_at\":\"2026-09-29T17:00:00Z\",\"updated_at\":\"2026-09-29T17:00:00Z\",\"connections\":[],\"subject_id\":\"tenant_acme/user_demo\",\"pending_tool_calls\":[]}}}\n\n\n" ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Upload an input file - **Method:** `POST` - **Path:** `/files` - **Operation ID:** `post_files` - **Tags:** Files Upload one immutable file of at most 16 MiB to the project; larger files return 413 `file_too_large`. The 201 response is sent once the bytes and metadata are durably stored and ready to download. Uploads are project resources that outlive sessions. Attach the file to session input as `file` or `image` content; see `POST /sessions/{session_id}/inputs` for how the agent receives it. Upload acceptance stores arbitrary bytes and does not certify a valid image; image validation happens when an input references it as `image`. The upload never changes and may be deleted with `DELETE /files/{file_id}`; already accepted inputs retain their attachment content. Agents produce downloadable files differently; see `GET /sessions/{session_id}/files`. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Request body **Required:** `true` **Content type:** `multipart/form-data` [UploadFile](/reference/schemas/UploadFile.md) #### Responses ##### 201 Upload an input file. **Content type:** `application/json` [UploadedFileMetadata](/reference/schemas/UploadedFileMetadata.md) A project upload from `POST /files`; `path`, `session_id` and `run_id` are null. **Example:** ```json { "id": "file_demo", "kind": "upload", "path": null, "filename": "source.md", "media_type": "text/markdown", "size_bytes": 1420, "session_id": null, "run_id": null, "created_at": "2026-09-29T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 413 Upload exceeds the service upload limit. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "file_too_large", "message": "Upload exceeds the service upload limit.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### List session output files - **Method:** `GET` - **Path:** `/sessions/{session_id}/files` - **Operation ID:** `get_sessions_session_id_files` - **Tags:** Files List the session's saved output files, oldest first. These are immutable copies, not a view of the live sandbox. ### Producing outputs The agent saves deliverables by writing them under `/workspace/outputs/` with `apply_patch` or `shell`. The platform creates this directory in each sandbox and tells the agent to use it; no extra tool grant or publish step is needed. Files elsewhere in the sandbox are never exposed through the file APIs. When a run completes normally, every regular file beneath `/workspace/outputs/` is collected recursively. Symlinks are not followed, and directories, symlinks and other non-regular entries are skipped. A collected file is saved only if it is new or its bytes differ from the session's latest saved copy at the same path; a file whose latest saved copy was deleted is saved again. Each saved file gets a new file ID and an immutable copy recording its `session_id`, `run_id` and capture `path` (provenance only, not a live location or mount path); `filename` is its basename and `media_type` is inferred from its format, defaulting to `application/octet-stream`. Unchanged files keep their existing saved copy and ID and are not listed in the later run's `output_file_ids`. Later sandbox changes never alter saved copies. Finish writing before the run ends: collection does not wait for background writers and is not a point-in-time snapshot. The run's files, their `file.created` events, its `output_file_ids` and `run.completed` are committed atomically, with the file events first. Every file is ready to download when its `file.created` event is committed. Deleted files are omitted from listings and current `output_file_ids`; historical events retain their original file IDs. Collection fails the run with `output_collection_failed`, keeping `output_file_ids` empty, saving none of the run's files and pausing the session, if reading or storing fails or a limit is exceeded: at most 1024 files and 32 MiB in total beneath `/workspace/outputs/`, unchanged files included, and at most 1024 entries in any one directory. A stop accepted before the completion commit wins; stopped and failed runs save no outputs. A run without a sandbox, with a lost sandbox or with no new or changed files completes with no new outputs, since collection never provisions or recreates a sandbox. Earlier outputs are unaffected. ### Lifetime Saved outputs survive sandbox loss and archival, and are removed with their session or by `DELETE /files/{file_id}`. Deleting a saved output does not remove the sandbox file; a later completed run saves it again under a new ID. Attaching an output file to an input gives the receiving session its own copy (see `POST /sessions/{session_id}/inputs`), which survives deletion of the source file. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` #### Query parameters - **`limit`**: `integer`, default: `20`, minimum: `1`, maximum: `100` Maximum records in this page. - **`cursor`**: `string` Opaque next_cursor from the previous page. It continues after that page's last record, even if records were deleted or changed status since. Cursors bind to endpoint and filters; changing them returns 400. An expired cursor returns 410. #### Responses ##### 200 List session output files. **Content type:** `application/json` [OutputFileList](/reference/schemas/OutputFileList.md) **Example:** ```json { "data": [ { "id": "file_demo", "kind": "output", "path": "/workspace/outputs/findings.md", "filename": "findings.md", "media_type": "text/markdown", "size_bytes": 1420, "session_id": "ses_demo", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z" } ], "next_cursor": null } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 410 History or pagination cursor is no longer available under retention policy. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "cursor_expired", "message": "History or pagination cursor is no longer available under retention policy.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Retrieve file metadata - **Method:** `GET` - **Path:** `/files/{file_id}` - **Operation ID:** `get_files_file_id` - **Tags:** Files Read the metadata of an upload (`kind: upload`) or a saved output file (`kind: output`). Every returned file is committed and ready to download. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`file_id` (required)**: `string`, pattern: `^file_[A-Za-z0-9]+$` #### Responses ##### 200 Retrieve file metadata. **Content type:** `application/json` [File](/reference/schemas/File.md) An immutable, ready-to-download project upload or session output file. **Example:** ```json { "id": "file_demo", "kind": "output", "path": "/workspace/outputs/findings.md", "filename": "findings.md", "media_type": "text/markdown", "size_bytes": 1420, "session_id": "ses_demo", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z" } ``` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Delete a file - **Method:** `DELETE` - **Path:** `/files/{file_id}` - **Operation ID:** `delete_files_file_id` - **Tags:** Files Delete an upload or saved output file, including one already attached to an input. Its metadata and content endpoints return 404 after deletion; deleting it again returns 404. Deleted outputs disappear from the session's file list and from the run's current `output_file_ids`. Historical events and input content retain their original file IDs. Accepted inputs retain their attachment copies, so queued inputs and restored conversation history continue to work after the source file is deleted. New inputs cannot reference a deleted file. Deleting a saved output does not remove its source path from the live sandbox. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`file_id` (required)**: `string`, pattern: `^file_[A-Za-z0-9]+$` #### Responses ##### 204 Delete a file. ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ### Download file content - **Method:** `GET` - **Path:** `/files/{file_id}/content` - **Operation ID:** `get_files_file_id_content` - **Tags:** Files Download the immutable bytes of an upload or saved output file. **Servers:** [Inherited servers](#scalar-context-global-servers) **Authentication:** [Global authentication](#scalar-context-global-authentication) #### Path parameters - **`file_id` (required)**: `string`, pattern: `^file_[A-Za-z0-9]+$` #### Responses ##### 200 Download file content. **Headers:** - **`Content-Disposition`** `attachment` with the original name as `filename*` (UTF-8, percent-encoded) and an ASCII `filename` fallback in which other characters, quotes, backslashes and percent signs become `_`. `string` **Content type:** `application/octet-stream` ##### 400 Invalid request or cursor. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "invalid_request", "message": "Invalid request or cursor.", "request_id": "req_example" } } ``` ##### 401 Missing, invalid, expired or revoked bearer credential. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "unauthorized", "message": "A valid bearer credential is required.", "request_id": "req_example" } } ``` ##### 403 The credential lacks permission for this operation. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "forbidden", "message": "The credential lacks permission for this operation.", "request_id": "req_example" } } ``` ##### 404 Resource does not exist or is not visible in this project. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "not_found", "message": "Resource does not exist or is not visible in this project.", "request_id": "req_example" } } ``` ##### 429 Service request rate limit reached; this is not a session budget. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "rate_limited", "message": "Service request rate limit reached; this is not a session budget.", "request_id": "req_example" } } ``` ##### 500 Platform error. No automatic resubmission or tool replay is promised. **Content type:** `application/json` [Error](/reference/schemas/Error.md) **Example:** ```json { "error": { "code": "internal_error", "message": "Platform error. No automatic resubmission or tool replay is promised.", "request_id": "req_example" } } ``` ## Schemas ### CreateModelApiKey **Type:** `object`, no additional properties - **`key` (required)**: `string`, minLength: `9`, maxLength: `4096`, pattern: `^[!-~]+$(?![\s\S])`, writeOnly The full model API key, containing visible ASCII characters without whitespace. Never returned. - **`name` (required)**: `string`, minLength: `1`, maxLength: `100`, pattern: `\S` - **`provider` (required)**: `string`, possible values: `"openai", "anthropic"` The direct model API that issued the key. ### ModelApiKey **Type:** `object`, no additional properties - **`created_at` (required)**: `string`, format: `date-time` - **`id` (required)**: `string`, pattern: `^mkey_[A-Za-z0-9]+$` - **`name` (required)**: `string` - **`prefix` (required)**: `string`, minLength: `4`, maxLength: `4` First four characters of the stored key. - **`provider` (required)**: `string`, possible values: `"openai", "anthropic"` - **`suffix` (required)**: `string`, minLength: `4`, maxLength: `4` Last four characters of the stored key. **Example:** ```json { "id": "mkey_demo", "name": "Production OpenAI", "provider": "openai", "prefix": "sk-E", "suffix": "_KEY", "created_at": "2026-10-09T17:00:00Z" } ``` ### ModelApiKeyList **Type:** `object`, no additional properties - **`data` (required)**: array of [ModelApiKey](/reference/schemas/ModelApiKey.md) - **`next_cursor` (required)**: `string | null` ### CreateApiKey **Type:** `object`, no additional properties - **`name` (required)**: `string`, minLength: `1`, maxLength: `100`, pattern: `\S` ### ApiKey **Type:** `object`, no additional properties - **`created_at` (required)**: `string`, format: `date-time` - **`id` (required)**: `string`, pattern: `^key_[A-Za-z0-9]+$` - **`name` (required)**: `string` - **`prefix` (required)**: `string` Non-secret identifying prefix. ### CreatedApiKey **Type:** `object`, no additional properties - **`created_at` (required)**: `string`, format: `date-time` - **`id` (required)**: `string`, pattern: `^key_[A-Za-z0-9]+$` - **`name` (required)**: `string` - **`prefix` (required)**: `string` - **`secret` (required)**: `string` The bearer credential, returned only at creation. ### ApiKeyList **Type:** `object`, no additional properties - **`data` (required)**: array of [ApiKey](/reference/schemas/ApiKey.md) - **`next_cursor` (required)**: `string | null` ### UpdateAgent **Type:** `object`, no additional properties - **`name` (required)**: `string`, minLength: `1`, maxLength: `120`, pattern: `\S` ### TextContent **Type:** `object`, no additional properties - **`text` (required)**: `string`, minLength: `1` - **`type` (required)**: `string`, const: `"text"` ### FileContent **Type:** `object`, no additional properties An uploaded or saved output file of this project, attached to input. Requires a `sandbox` environment; see `POST /sessions/{session_id}/inputs`. - **`file_id` (required)**: `string`, pattern: `^file_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"file"` ### ImageContent **Type:** `object`, no additional properties A static PNG, JPEG or WebP from an uploaded or saved output file of this project, sent directly to an image-capable model. Works with either environment and has no sandbox path. See `POST /sessions/{session_id}/inputs` for validation, limits and retention. - **`file_id` (required)**: `string`, pattern: `^file_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"image"` **Example:** ```json { "type": "image", "file_id": "file_demo" } ``` ### Content **One of:** discriminated by `type` - [TextContent](/reference/schemas/TextContent.md) - [FileContent](/reference/schemas/FileContent.md) An uploaded or saved output file of this project, attached to input. Requires a `sandbox` environment; see `POST /sessions/{session_id}/inputs`. - [ImageContent](/reference/schemas/ImageContent.md) A static PNG, JPEG or WebP from an uploaded or saved output file of this project, sent directly to an image-capable model. Works with either environment and has no sandbox path. See `POST /sessions/{session_id}/inputs` for validation, limits and retention. ### ErrorDetail **Type:** `object`, no additional properties - **`code` (required)**: `string`, minLength: `1` - **`message` (required)**: `string`, minLength: `1` - **`request_id` (required)**: `string`, minLength: `1` ### Error **Type:** `object`, no additional properties - **`error` (required)**: [ErrorDetail](/reference/schemas/ErrorDetail.md) ### ConnectionGrant **Type:** `object`, no additional properties Bind a registered reusable connection with the session's `subject_id`, granting exactly `allowed_tools` (remote tool names, no wildcards). - **`allowed_tools` (required)**: `array`, minItems: `1`, uniqueItems: `true` **Items:** `string`, minLength: `1`, pattern: `^[^*]+$` - **`connection_id` (required)**: `string`, pattern: `^conn_[A-Za-z0-9]+$` ### InlineConnectionGrant **Type:** `object`, no additional properties Create a session-owned connection to this endpoint and bind it, granting exactly `allowed_tools`; see `POST /sessions`. - **`allowed_tools` (required)**: `array`, minItems: `1`, uniqueItems: `true` **Items:** `string`, minLength: `1`, pattern: `^[^*]+$` - **`url` (required)**: `string`, format: `uri`, pattern: `^https://[^/@?#\s]+(?:[/?][^#\s]*)?$(?![\s\S])` Immutable MCP endpoint. No embedded credentials, user information or fragments. Redirects are not followed. - **`expires_at`**: `string | null`, format: `date-time` Declared credential expiry; null or omitted means unknown. Known-expired credentials block dispatch. Empty headers reset it to null. - **`headers`**: [SecretHeaders](/reference/schemas/SecretHeaders.md), default: `{}` Secret headers sent only to the connection's endpoint, such as `authorization` for a bearer token or a provider field such as `x-api-key`. Names are lowercase HTTP field names other than routing and transport-controlled fields; values are nonempty and contain no CR or LF. An empty object means no authentication. The credential configuration is never returned or exposed to the model, the sandbox or session history; response sanitization and its limits are described on POST /connections. - **`name`**: `string`, default: `"MCP tools"`, minLength: `1` **Example:** ```json { "url": "https://mcp.example.com/users/user_demo/mcp", "headers": { "authorization": "Bearer EXAMPLE_USER_SCOPED_MCP_TOKEN" }, "expires_at": null, "allowed_tools": [ "search_documents" ] } ``` **Example:** ```json { "name": "Hosted MCP tools", "url": "https://mcp.example.com/session/session_demo/mcp", "headers": { "x-api-key": "EXAMPLE_PROVIDER_KEY" }, "allowed_tools": [ "search_documents" ] } ``` ### SessionConnectionConfig **Type:** [ConnectionGrant](/reference/schemas/ConnectionGrant.md) | [InlineConnectionGrant](/reference/schemas/InlineConnectionGrant.md) A registered connection reference or an inline endpoint, never both in one entry. **Example:** ```json { "connection_id": "conn_demo", "allowed_tools": [ "search_documents" ] } ``` **Example:** ```json { "url": "https://mcp.example.com/users/user_demo/mcp", "headers": { "authorization": "Bearer EXAMPLE_USER_SCOPED_MCP_TOKEN" }, "allowed_tools": [ "search_documents" ] } ``` ### AgentConfig **Type:** `object`, no additional properties Model, stored model API key reference, base instructions and tools of an agent version; see `POST /agents`. MCP connections are bound per session, not here. - **`instructions` (required)**: `string` - **`model` (required)**: `string`, minLength: `1` A registered `openai/model-id` or `anthropic/model-id`. Unsupported providers, malformed values and unregistered model IDs return 400 `invalid_model` at agent or version creation. Registered model IDs use native context, output and reasoning capabilities. Registration does not verify provider access; a provider rejection or request failure that cannot be recovered fails the run with `model_error`. Transient model failures may be retried within the active run; see "Failures" on `GET /sessions/{session_id}/runs/{run_id}`. Choose a registered model and an effort it supports from the table below. Omitted `reasoning_effort` resolves to the listed default for each accepted input. Models with an image payload limit accept static PNG, JPEG and WebP inputs up to that many base64 bytes; `unsupported` means text-only. See `POST /sessions/{session_id}/inputs` for validation, aggregate request limits and compaction behavior. | Model IDs | Supported reasoning efforts | Default effort | Image payload limit (base64 bytes) | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -------------- | ---------------------------------- | | `openai/gpt-5-pro` | `high` | `high` | 4,718,592 | | `openai/o3-mini` | `low`, `medium`, `high` | `medium` | unsupported | | `openai/o1`, `openai/o1-pro`, `openai/o3`, `openai/o3-pro`, `openai/o4-mini` | `low`, `medium`, `high` | `medium` | 4,718,592 | | `openai/gpt-5.3-codex-spark` | `low`, `medium`, `high`, `xhigh` | `medium` | 4,718,592 | | `anthropic/claude-haiku-5-5`, `anthropic/claude-opus-5-5`, `anthropic/claude-sonnet-5-5`, `openai/gpt-6-astra`, `openai/gpt-6.1-sol` | `low`, `medium`, `high`, `xhigh`, `max` | `medium` | 4,718,592 | | `openai/gpt-5.2-pro`, `openai/gpt-5.4-pro`, `openai/gpt-5.5-pro` | `medium`, `high`, `xhigh` | `medium` | 4,718,592 | | `openai/gpt-5.2-chat-latest` | `medium`, `xhigh` | `medium` | 4,718,592 | | `openai/gpt-5`, `openai/gpt-5-mini`, `openai/gpt-5-nano` | `minimal`, `low`, `medium`, `high` | `medium` | 4,718,592 | | `openai/gpt-realtime-2.1` | `minimal`, `low`, `medium`, `high`, `xhigh` | `medium` | 4,718,592 | | `anthropic/claude-fable-5`, `anthropic/claude-fable-5-1`, `anthropic/claude-opus-5` | `minimal`, `low`, `medium`, `high`, `xhigh`, `max` | `medium` | 4,718,592 | | `openai/gpt-4` | `off` | `off` | unsupported | | `openai/gpt-4-turbo`, `openai/gpt-4.1`, `openai/gpt-4.1-mini`, `openai/gpt-4.1-nano`, `openai/gpt-4o`, `openai/gpt-4o-2024-05-13`, `openai/gpt-4o-2024-08-06`, `openai/gpt-4o-2024-11-20`, `openai/gpt-4o-mini`, `openai/gpt-5-chat-latest`, `openai/gpt-5.3-chat-latest` | `off` | `off` | 4,718,592 | | `openai/gpt-5.1` | `off`, `low`, `medium`, `high` | `medium` | 4,718,592 | | `openai/gpt-5.2`, `openai/gpt-5.3-codex`, `openai/gpt-5.4`, `openai/gpt-5.4-mini`, `openai/gpt-5.4-nano`, `openai/gpt-5.5` | `off`, `low`, `medium`, `high`, `xhigh` | `medium` | 4,718,592 | | `openai/gpt-5.6-luna`, `openai/gpt-5.6-sol`, `openai/gpt-5.6-terra`, `openai/gpt-6-luna`, `openai/gpt-6-sol`, `openai/gpt-daybreak-blue-latest`, `openai/gpt-daybreak-red-latest` | `off`, `low`, `medium`, `high`, `xhigh`, `max` | `medium` | 4,718,592 | | `anthropic/claude-haiku-4-5`, `anthropic/claude-haiku-4-5-20251001`, `anthropic/claude-opus-4-5`, `anthropic/claude-opus-4-5-20251101`, `anthropic/claude-sonnet-4-5`, `anthropic/claude-sonnet-4-5-20250929` | `off`, `minimal`, `low`, `medium`, `high` | `medium` | 4,718,592 | | `anthropic/claude-opus-4-6`, `anthropic/claude-sonnet-4-6` | `off`, `minimal`, `low`, `medium`, `high`, `max` | `medium` | 4,718,592 | | `anthropic/claude-opus-4-7`, `anthropic/claude-opus-4-8`, `anthropic/claude-sonnet-5` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` | `medium` | 4,718,592 | - **`model_api_key_id` (required)**: `string`, pattern: `^mkey_[A-Za-z0-9]+$` Required for every OpenAI or Anthropic model. ID of this project's stored key for the model's provider. Only this reference is retained in agent versions and session configuration. The selected key is resolved when each run starts; deletion fails future runs with `model_api_key_unavailable`. Existing sessions keep this reference when new agent versions select another key. - **`tools`**: array of [AgentTool](/reference/schemas/AgentTool.md), default: `[]`, uniqueItems: `true` **Example:** ```json { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] } ``` ### CreateAgent **Type:** `object`, no additional properties - **`config` (required)**: [AgentConfig](/reference/schemas/AgentConfig.md) Model, stored model API key reference, base instructions and tools of an agent version; see `POST /agents`. MCP connections are bound per session, not here. - **`name` (required)**: `string`, minLength: `1`, maxLength: `120` ### CreateAgentVersion **Type:** `object`, no additional properties - **`config` (required)**: [AgentConfig](/reference/schemas/AgentConfig.md) Model, stored model API key reference, base instructions and tools of an agent version; see `POST /agents`. MCP connections are bound per session, not here. ### Agent **Type:** `object`, no additional properties - **`created_at` (required)**: `string`, format: `date-time` - **`id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` - **`latest_version` (required)**: `integer`, minimum: `1` - **`name` (required)**: `string`, minLength: `1` **Example:** ```json { "id": "agt_demo", "name": "Research assistant", "latest_version": 1, "created_at": "2026-09-29T17:00:00Z" } ``` ### AgentVersion **Type:** `object`, no additional properties - **`agent_id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` - **`config` (required)**: [AgentConfig](/reference/schemas/AgentConfig.md) Model, stored model API key reference, base instructions and tools of an agent version; see `POST /agents`. MCP connections are bound per session, not here. - **`created_at` (required)**: `string`, format: `date-time` - **`version` (required)**: `integer`, minimum: `1` **Example:** ```json { "agent_id": "agt_demo", "version": 1, "config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "created_at": "2026-09-29T17:00:00Z" } ``` ### AgentSelection **Type:** `object`, no additional properties Omit `version` to use the latest version, resolved once at session creation. - **`id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` - **`version`**: `integer`, minimum: `1` ### ResolvedAgent **Type:** `object`, no additional properties - **`id` (required)**: `string`, pattern: `^agt_[A-Za-z0-9]+$` - **`version` (required)**: `integer`, minimum: `1` ### NetworkPolicy **Type:** `object`, no additional properties Exact public DNS hostnames the sandbox may reach over HTTP (port 80) or HTTPS (port 443, with a matching TLS server name); empty by default. An entry that is not an exact DNS hostname, such as a wildcard or IP address, returns 400 `invalid_network_policy`. All other outbound traffic is denied, including direct IP destinations, private networks, other ports and direct sockets; a listed hostname that resolves to a private address is denied when the sandbox connects. The allowlist neither grants nor restricts built-in web tools and MCP tools, and exposes no connection credentials. - **`allowed_hosts`**: `array`, default: `[]`, uniqueItems: `true` **Items:** `string`, minLength: `1` ### NoEnvironment **Type:** `object`, no additional properties - **`type` (required)**: `string`, const: `"none"` ### SandboxEnvironment **Type:** `object`, no additional properties An isolated sandbox, provisioned lazily on first use and never reprovisioned after loss. `image` must be `managed-default` (otherwise 400 `unsupported_image`); omitted `network` allows no hosts. - **`type` (required)**: `string`, const: `"sandbox"` - **`image`**: `string`, default: `"managed-default"` - **`network`**: [NetworkPolicy](/reference/schemas/NetworkPolicy.md) Exact public DNS hostnames the sandbox may reach over HTTP (port 80) or HTTPS (port 443, with a matching TLS server name); empty by default. An entry that is not an exact DNS hostname, such as a wildcard or IP address, returns 400 `invalid_network_policy`. All other outbound traffic is denied, including direct IP destinations, private networks, other ports and direct sockets; a listed hostname that resolves to a private address is denied when the sandbox connects. The allowlist neither grants nor restricts built-in web tools and MCP tools, and exposes no connection credentials. ### Environment **One of:** discriminated by `type` - [NoEnvironment](/reference/schemas/NoEnvironment.md) - [SandboxEnvironment](/reference/schemas/SandboxEnvironment.md) An isolated sandbox, provisioned lazily on first use and never reprovisioned after loss. `image` must be `managed-default` (otherwise 400 `unsupported_image`); omitted `network` allows no hosts. ### ReasoningEffort **Type:** `string`, possible values: `"off", "minimal", "low", "medium", "high", "xhigh", "max"` A reasoning level supported by the selected model. Models without reasoning support only `off`; reasoning models may support a subset and may require reasoning. Unsupported levels return 400 `unsupported_reasoning_effort`. Omission resolves a supported default at input acceptance; see `POST /sessions/{session_id}/inputs`. ### InitialInput **Type:** `object`, no additional properties First input of a new session. Either `mode` starts the first run; the mode and resolved reasoning effort are recorded on the input. Unsupported reasoning effort or invalid image input rejects the entire session creation without creating a session. - **`content` (required)**: array of [Content](/reference/schemas/Content.md), minItems: `1` - **`mode` (required)**: `string`, possible values: `"steer", "queue"` - **`reasoning_effort`**: `string`, possible values: `"off", "minimal", "low", "medium", "high", "xhigh", "max"` A reasoning level supported by the selected model. Models without reasoning support only `off`; reasoning models may support a subset and may require reasoning. Unsupported levels return 400 `unsupported_reasoning_effort`. Omission resolves a supported default at input acceptance; see `POST /sessions/{session_id}/inputs`. ### CreateSession **Type:** `object`, no additional properties Omitted `environment` means `{type: sandbox}`. See `POST /sessions`. **One of:** - `object` - **`environment`**: [SandboxEnvironment](/reference/schemas/SandboxEnvironment.md) An isolated sandbox, provisioned lazily on first use and never reprovisioned after loss. `image` must be `managed-default` (otherwise 400 `unsupported_image`); omitted `network` allows no hosts. - `object` - **`environment` (required)**: [NoEnvironment](/reference/schemas/NoEnvironment.md) - **`input`**: `object` - **`content`**: array of ([TextContent](/reference/schemas/TextContent.md) | [ImageContent](/reference/schemas/ImageContent.md)) * **`agent` (required)**: [AgentSelection](/reference/schemas/AgentSelection.md) Omit `version` to use the latest version, resolved once at session creation. * **`subject_id` (required)**: `string`, minLength: `1`, maxLength: `256`, pattern: `^[^\x00-\x1f\x7f]+$(?![\s\S])` Opaque, case-sensitive end-user identity within the project, supplied by your backend after it authenticates the user; include the tenant when user IDs are only unique per tenant. It is not a credential or proof of authentication. Immutable on sessions and connections. * **`connections`**: array of [SessionConnectionConfig](/reference/schemas/SessionConnectionConfig.md), default: `[]` MCP connections to bind, inline or registered; omitted means no MCP access. * **`environment`**: [Environment](/reference/schemas/Environment.md) * **`input`**: [InitialInput](/reference/schemas/InitialInput.md) First input of a new session. Either `mode` starts the first run; the mode and resolved reasoning effort are recorded on the input. Unsupported reasoning effort or invalid image input rejects the entire session creation without creating a session. * **`title`**: `string`, maxLength: `200` **Example:** ```json { "agent": { "id": "agt_demo", "version": 1 }, "environment": { "type": "none" }, "subject_id": "example/user_123" } ``` **Example:** ```json { "agent": { "id": "agt_demo", "version": 1 }, "connections": [ { "url": "https://mcp.example.com/users/user_demo/mcp", "headers": { "authorization": "Bearer EXAMPLE_USER_SCOPED_MCP_TOKEN" }, "expires_at": null, "allowed_tools": [ "search_documents" ] } ], "input": { "mode": "steer", "reasoning_effort": "medium", "content": [ { "type": "text", "text": "Find the onboarding documents." } ] }, "subject_id": "tenant_acme/user_demo" } ``` **Example:** ```json { "agent": { "id": "agt_demo" }, "connections": [ { "connection_id": "conn_demo", "allowed_tools": [ "search_documents" ] } ], "subject_id": "tenant_acme/user_demo" } ``` ### Session **Type:** `object`, no additional properties A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. **One of:** - `object` - **`active_run_id`**: `string` - **`active_run_status`**: `string`, const: `"interrupted"` - **`status`**: `string`, const: `"paused"` - `object` - **`active_run_id`**: `string` - **`active_run_status`**: `string`, const: `"waiting_for_tools"` - **`pending_tool_calls`**: `array`, minItems: `1` - `object` - **`active_run_id`**: `string` - **`active_run_status`**: `string`, possible values: `"running", "stopping"` - **`pending_tool_calls`**: `array`, maxItems: `0` - `object` - **`active_run_id`**: `null` - **`active_run_status`**: `null` - **`pending_tool_calls`**: `array`, maxItems: `0` **Not:** **Any of:** - `object` - **`active_run_id`**: `string` - **`status`**: `string`, const: `"archived"` - `object` - **`active_run_id`**: `null` - **`status`**: `string`, const: `"pausing"` * **`active_run_id` (required)**: `string | null`, pattern: `^run_[A-Za-z0-9]+$` * **`active_run_status` (required)**: `string | null`, possible values: `"running", "waiting_for_tools", "interrupted", "stopping"` * **`agent` (required)**: [ResolvedAgent](/reference/schemas/ResolvedAgent.md) * **`agent_config` (required)**: [AgentConfig](/reference/schemas/AgentConfig.md) Model, stored model API key reference, base instructions and tools of an agent version; see `POST /agents`. MCP connections are bound per session, not here. * **`connections` (required)**: array of [SessionConnectionBinding](/reference/schemas/SessionConnectionBinding.md) MCP bindings fixed at creation, in request order, without credentials. * **`created_at` (required)**: `string`, format: `date-time` * **`environment` (required)**: [Environment](/reference/schemas/Environment.md) * **`id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` * **`last_event_sequence` (required)**: `integer`, minimum: `0` * **`pending_input_count` (required)**: `integer`, minimum: `0` Queued inputs not yet assigned to a run, waiting for dispatch. Steering is not counted. * **`pending_tool_calls` (required)**: array of [PendingToolCall](/reference/schemas/PendingToolCall.md) Unresolved application calls of the active run, in request order; empty unless `waiting_for_tools` or `interrupted`. See `GET /sessions/{session_id}`. * **`sandbox_id` (required)**: `string | null`, pattern: `^sbx_[A-Za-z0-9]+$` * **`status` (required)**: `string`, possible values: `"active", "pausing", "paused", "archived"` * **`subject_id` (required)**: `string`, minLength: `1`, maxLength: `256`, pattern: `^[^\x00-\x1f\x7f]+$(?![\s\S])` Opaque, case-sensitive end-user identity within the project, supplied by your backend after it authenticates the user; include the tenant when user IDs are only unique per tenant. It is not a credential or proof of authentication. Immutable on sessions and connections. * **`title` (required)**: `string | null` * **`updated_at` (required)**: `string`, format: `date-time` **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } ``` **Example:** ```json { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_customer", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] }, "environment": { "type": "none" }, "status": "active", "active_run_id": "run_demo", "active_run_status": "waiting_for_tools", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 20, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` ### SendInput **Type:** `object`, no additional properties Input for an existing session; `mode` is required. See `POST /sessions/{session_id}/inputs` for how each mode behaves. - **`content` (required)**: array of [Content](/reference/schemas/Content.md), minItems: `1` - **`mode` (required)**: `string`, possible values: `"steer", "queue"` - **`reasoning_effort`**: `string`, possible values: `"off", "minimal", "low", "medium", "high", "xhigh", "max"` A reasoning level supported by the selected model. Models without reasoning support only `off`; reasoning models may support a subset and may require reasoning. Unsupported levels return 400 `unsupported_reasoning_effort`. Omission resolves a supported default at input acceptance; see `POST /sessions/{session_id}/inputs`. **Example:** ```json { "mode": "steer", "content": [ { "type": "text", "text": "Describe the onboarding screen." }, { "type": "image", "file_id": "file_demo" } ] } ``` ### Input **Type:** `object`, no additional properties `accepted` means durably recorded; `applied` means the agent has taken it into model context. Steering is bound to its run on acceptance and never reassigned; queued input gets a `run_id` when its run starts. - **`applied_at` (required)**: `string | null`, format: `date-time` - **`cancellation_reason` (required)**: `string | null`, possible values: `"customer_cancelled", "session_archived", "run_completed", "run_failed", "run_stopped"` `customer_cancelled` for explicit cancellation, `session_archived` for archival, or `run_failed` or `run_stopped` when the assigned run ended before the input was applied. `run_completed` is never emitted, because a run applies all its steering before completing normally. Null unless cancelled. - **`cancelled_at` (required)**: `string | null`, format: `date-time` - **`content` (required)**: array of [Content](/reference/schemas/Content.md), minItems: `1` - **`created_at` (required)**: `string`, format: `date-time` - **`id` (required)**: `string`, pattern: `^inp_[A-Za-z0-9]+$` - **`mode` (required)**: `string`, possible values: `"steer", "queue"` - **`reasoning_effort` (required)**: `string`, possible values: `"off", "minimal", "low", "medium", "high", "xhigh", "max"` The model-supported effort resolved at acceptance, including when the request omitted it. It takes effect only when the input is applied. See `POST /sessions/{session_id}/inputs`. - **`run_id` (required)**: `string | null`, pattern: `^run_[A-Za-z0-9]+$` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`status` (required)**: `string`, possible values: `"accepted", "applied", "cancelled"` **Example:** ```json { "id": "inp_demo", "session_id": "ses_demo", "content": [ { "type": "text", "text": "Review the onboarding flow and save your findings under /workspace/outputs/." } ], "mode": "steer", "reasoning_effort": "medium", "status": "accepted", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z", "applied_at": null, "cancelled_at": null, "cancellation_reason": null } ``` ### AssistantMessage **Type:** `object`, no additional properties - **`content` (required)**: array of [Content](/reference/schemas/Content.md), minItems: `1` - **`created_at` (required)**: `string`, format: `date-time` - **`id` (required)**: `string`, pattern: `^msg_[A-Za-z0-9]+$` - **`role` (required)**: `string`, const: `"assistant"` **Example:** ```json { "id": "msg_demo", "role": "assistant", "content": [ { "type": "text", "text": "I reviewed the flow and saved findings.md under /workspace/outputs/." } ], "created_at": "2026-09-29T17:00:00Z" } ``` ### RunFailure **Type:** `object`, no additional properties Sanitized error of a run or tool call. Run error codes include `model_api_key_unavailable` (the selected stored model API key is no longer available; no model request was made), `harness_lost` (execution was lost; the run is interrupted and does not resume automatically), `harness_error` (the platform could not execute the run for another reason) and `model_error` (a model request failed after applicable retries or could not be retried, including a safety refusal; the message gives the HTTP status, provider error type and a bounded provider message, never the raw response). MCP failures are tool call errors, never run errors; see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`. - **`code` (required)**: `string`, minLength: `1` - **`message` (required)**: `string`, minLength: `1` **Example:** ```json { "code": "model_api_key_unavailable", "message": "The selected stored model API key is no longer available." } ``` ### Run **Type:** `object`, no additional properties One agent execution, started by one input and including steering applied while it is active; it can span many model generations and tool calls. `running`, `waiting_for_tools`, `interrupted` and `stopping` are active states with null `ended_at`; `completed`, `failed` and `stopped` are terminal. See `GET /sessions/{session_id}/runs/{run_id}`. **One of:** - `object` - **`ended_at`**: `null` - **`output_file_ids`**: `array`, maxItems: `0` - **`status`**: `string`, possible values: `"running", "waiting_for_tools", "stopping"` - `object` - **`ended_at`**: `null` - **`error`**: [RunFailure](/reference/schemas/RunFailure.md) Sanitized error of a run or tool call. Run error codes include `model_api_key_unavailable` (the selected stored model API key is no longer available; no model request was made), `harness_lost` (execution was lost; the run is interrupted and does not resume automatically), `harness_error` (the platform could not execute the run for another reason) and `model_error` (a model request failed after applicable retries or could not be retried, including a safety refusal; the message gives the HTTP status, provider error type and a bounded provider message, never the raw response). MCP failures are tool call errors, never run errors; see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`. - **`output_file_ids`**: `array`, maxItems: `0` - **`status`**: `string`, const: `"interrupted"` - `object` - **`ended_at`**: `string`, format: `date-time` - **`status`**: `string`, const: `"completed"` - `object` - **`ended_at`**: `string`, format: `date-time` - **`error`**: [RunFailure](/reference/schemas/RunFailure.md) Sanitized error of a run or tool call. Run error codes include `model_api_key_unavailable` (the selected stored model API key is no longer available; no model request was made), `harness_lost` (execution was lost; the run is interrupted and does not resume automatically), `harness_error` (the platform could not execute the run for another reason) and `model_error` (a model request failed after applicable retries or could not be retried, including a safety refusal; the message gives the HTTP status, provider error type and a bounded provider message, never the raw response). MCP failures are tool call errors, never run errors; see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`. - **`output_file_ids`**: `array`, maxItems: `0` - **`status`**: `string`, const: `"failed"` - `object` - **`ended_at`**: `string`, format: `date-time` - **`output_file_ids`**: `array`, maxItems: `0` - **`status`**: `string`, const: `"stopped"` * **`applied_input_ids` (required)**: `array` **Items:** `string`, pattern: `^inp_[A-Za-z0-9]+$` * **`ended_at` (required)**: `string | null`, format: `date-time` * **`error` (required)**: [RunFailure](/reference/schemas/RunFailure.md) | `null` Sanitized error of a run or tool call. Run error codes include `model_api_key_unavailable` (the selected stored model API key is no longer available; no model request was made), `harness_lost` (execution was lost; the run is interrupted and does not resume automatically), `harness_error` (the platform could not execute the run for another reason) and `model_error` (a model request failed after applicable retries or could not be retried, including a safety refusal; the message gives the HTTP status, provider error type and a bounded provider message, never the raw response). MCP failures are tool call errors, never run errors; see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`. * **`id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` * **`initial_input_id` (required)**: `string`, pattern: `^inp_[A-Za-z0-9]+$` * **`messages` (required)**: array of [AssistantMessage](/reference/schemas/AssistantMessage.md) * **`output_file_ids` (required)**: `array` Output files this run saved when it completed normally, being new or changed since the session's latest saved copy at each path, and not subsequently deleted; otherwise empty. All are ready to download once `run.completed` is visible. Historical events retain their original output IDs after file deletion. **Items:** `string`, pattern: `^file_[A-Za-z0-9]+$` * **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` * **`started_at` (required)**: `string`, format: `date-time` * **`status` (required)**: `string`, possible values: `"running", "waiting_for_tools", "interrupted", "stopping", "completed", "failed", "stopped"` **Example:** ```json { "id": "run_demo", "session_id": "ses_demo", "status": "running", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": null } ``` **Example:** ```json { "id": "run_demo", "session_id": "ses_demo", "status": "waiting_for_tools", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": null } ``` ### StopRun **Type:** `object`, no additional properties The run to stop, named so that a retried request cannot stop newer work. - **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` ### ToolCall **Type:** `object`, no additional properties A durable tool call record. Platform calls (built-ins, and MCP tools with their `connection_id`) are `running` until `completed` or `failed`, or `cancelled` when their run stops or ends first. Application calls are `requested` until they become `completed`, `failed` or `cancelled`. An MCP tool error result fails the call with `mcp_tool_error`. Connection credentials never appear in tool records. **Any of:** - `object` - **`status`**: `string`, possible values: `"requested", "running", "completed", "cancelled"` - `object` - **`error`**: [RunFailure](/reference/schemas/RunFailure.md) Sanitized error of a run or tool call. Run error codes include `model_api_key_unavailable` (the selected stored model API key is no longer available; no model request was made), `harness_lost` (execution was lost; the run is interrupted and does not resume automatically), `harness_error` (the platform could not execute the run for another reason) and `model_error` (a model request failed after applicable retries or could not be retried, including a safety refusal; the message gives the HTTP status, provider error type and a bounded provider message, never the raw response). MCP failures are tool call errors, never run errors; see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`. - **`status`**: `string`, const: `"failed"` **One of:** - `object` - **`deadline_at`**: `null` - **`execution`**: `string`, const: `"platform"` - **`result`**: `string | null` - **`status`**: `string`, possible values: `"running", "completed", "failed", "cancelled"` - `object` - **`connection_id`**: `null` - **`deadline_at`**: `string`, format: `date-time` - **`execution`**: `string`, const: `"application"` - **`status`**: `string`, possible values: `"requested", "completed", "failed", "cancelled"` * **`arguments` (required)**: [ShellArguments](/reference/schemas/ShellArguments.md) | `object` Arguments of the named tool: `ShellArguments` for `shell`, `ApplyPatchArguments` for `apply_patch`, `ViewImageArguments` for `view_image`, otherwise defined by the tool. * **`connection_id` (required)**: `string | null`, pattern: `^conn_[A-Za-z0-9]+$` * **`deadline_at` (required)**: `string | null`, format: `date-time` Result deadline of an application call: its persisted request time plus ten minutes, kept after it resolves. Null for platform tools. * **`error` (required)**: [RunFailure](/reference/schemas/RunFailure.md) | `null` Sanitized error of a run or tool call. Run error codes include `model_api_key_unavailable` (the selected stored model API key is no longer available; no model request was made), `harness_lost` (execution was lost; the run is interrupted and does not resume automatically), `harness_error` (the platform could not execute the run for another reason) and `model_error` (a model request failed after applicable retries or could not be retried, including a safety refusal; the message gives the HTTP status, provider error type and a bounded provider message, never the raw response). MCP failures are tool call errors, never run errors; see "MCP failures" on `GET /sessions/{session_id}/runs/{run_id}`. * **`execution` (required)**: `string`, possible values: `"platform", "application"` The platform executes built-in and MCP tools. The customer application executes declared functions. * **`id` (required)**: `string`, pattern: `^call_[A-Za-z0-9]+$` * **`result` (required)**: `string | any` A platform tool's sanitized string result (for `shell`, a JSON-encoded `ShellResult`; for `apply_patch`, a JSON-encoded `ApplyPatchResult`; for `view_image`, a JSON-encoded `ViewImageResult` containing metadata without image bytes), or an application function's output, which may be any JSON value including null. Null while requested or running, or when there is no result; `status` distinguishes a successful null output. * **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` * **`status` (required)**: `string`, possible values: `"requested", "running", "completed", "failed", "cancelled"` * **`tool` (required)**: `string`, minLength: `1` The built-in or function name, or `mcp_{connection_id}_{remote_name}` for an MCP tool; see "Tool access" on `POST /sessions`. ### CreateConnection **Type:** `object`, no additional properties A reusable MCP connection; see `POST /connections`. - **`name` (required)**: `string`, minLength: `1` - **`subject_id` (required)**: `string`, minLength: `1`, maxLength: `256`, pattern: `^[^\x00-\x1f\x7f]+$(?![\s\S])` Opaque, case-sensitive end-user identity within the project, supplied by your backend after it authenticates the user; include the tenant when user IDs are only unique per tenant. It is not a credential or proof of authentication. Immutable on sessions and connections. - **`url` (required)**: `string`, format: `uri`, pattern: `^https://[^/@?#\s]+(?:[/?][^#\s]*)?$(?![\s\S])` Immutable MCP endpoint. No embedded credentials, user information or fragments. Redirects are not followed. - **`expires_at`**: `string | null`, format: `date-time` Declared credential expiry; null or omitted means unknown. Known-expired credentials block dispatch. Empty headers reset it to null. - **`headers`**: [SecretHeaders](/reference/schemas/SecretHeaders.md), default: `{}` Secret headers sent only to the connection's endpoint, such as `authorization` for a bearer token or a provider field such as `x-api-key`. Names are lowercase HTTP field names other than routing and transport-controlled fields; values are nonempty and contain no CR or LF. An empty object means no authentication. The credential configuration is never returned or exposed to the model, the sandbox or session history; response sanitization and its limits are described on POST /connections. ### Connection **Type:** `object`, no additional properties An MCP connection, without its credentials. Its `subject_id`, `url`, `scope` and owning `session_id` never change. **One of:** - `object` - **`scope`**: `string`, const: `"reusable"` - **`session_id`**: `null` - `object` - **`scope`**: `string`, const: `"session"` - **`session_id`**: `string`, pattern: `^ses_[A-Za-z0-9]+$` * **`authentication` (required)**: `string`, possible values: `"none", "headers"` Whether authentication headers are configured; not authorization health. * **`created_at` (required)**: `string`, format: `date-time` * **`expires_at` (required)**: `string | null`, format: `date-time` Declared credential expiry; null means unknown. Known-expired credentials block dispatch. * **`id` (required)**: `string`, pattern: `^conn_[A-Za-z0-9]+$` * **`name` (required)**: `string`, minLength: `1` * **`scope` (required)**: `string`, possible values: `"reusable", "session"` `reusable` when registered with `POST /connections`; `session` when configured inline in `POST /sessions` and owned by that session. * **`session_id` (required)**: `string | null`, pattern: `^ses_[A-Za-z0-9]+$` Owning session for scope=session; null for reusable connections. * **`subject_id` (required)**: `string`, minLength: `1`, maxLength: `256`, pattern: `^[^\x00-\x1f\x7f]+$(?![\s\S])` Opaque, case-sensitive end-user identity within the project, supplied by your backend after it authenticates the user; include the tenant when user IDs are only unique per tenant. It is not a credential or proof of authentication. Immutable on sessions and connections. * **`updated_at` (required)**: `string`, format: `date-time` * **`url` (required)**: `string`, format: `uri` **Example:** ```json { "id": "conn_demo", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": null, "updated_at": "2026-09-29T17:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "reusable", "session_id": null } ``` **Example:** ```json { "id": "conn_inline", "name": "End-user tools", "url": "https://mcp.example.com/users/user_demo/mcp", "authentication": "headers", "created_at": "2026-09-29T17:00:00Z", "expires_at": null, "updated_at": "2026-09-29T17:00:00Z", "subject_id": "tenant_acme/user_demo", "scope": "session", "session_id": "ses_demo" } ``` ### FileMetadata **Type:** `object`, no additional properties Metadata shared by uploads and output files; `UploadedFileMetadata` and `OutputFileMetadata` add kind-specific constraints. - **`created_at` (required)**: `string`, format: `date-time` - **`filename` (required)**: `string`, minLength: `1` - **`id` (required)**: `string`, pattern: `^file_[A-Za-z0-9]+$` - **`kind` (required)**: `string`, possible values: `"upload", "output"` - **`media_type` (required)**: `string`, minLength: `1` - **`path` (required)**: `string | null`, pattern: `^/workspace/outputs/(?!\.\.?(/|$))[^/\u0000\r\n]+(?:/(?!\.\.?(/|$))[^/\u0000\r\n]+)*$(?![\s\S])` For outputs, the normalized absolute path beneath `/workspace/outputs/` when the file was saved: provenance only, not a live file or mount path. Null for uploads. - **`run_id` (required)**: `string | null`, pattern: `^run_[A-Za-z0-9]+$` - **`session_id` (required)**: `string | null`, pattern: `^ses_[A-Za-z0-9]+$` - **`size_bytes` (required)**: `integer`, minimum: `0` ### Uploaded input file **Type:** [FileMetadata](/reference/schemas/FileMetadata.md) A project upload from `POST /files`; `path`, `session_id` and `run_id` are null. - **`kind`**: `string`, const: `"upload"` - **`path`**: `null` - **`run_id`**: `null` - **`session_id`**: `null` ### Output file **Type:** [FileMetadata](/reference/schemas/FileMetadata.md) An output file saved when a run completed normally, with its `session_id`, `run_id` and capture `path`. - **`kind`**: `string`, const: `"output"` - **`path`**: `string` - **`run_id`**: `string` - **`session_id`**: `string` **Example:** ```json { "id": "file_demo", "kind": "output", "path": "/workspace/outputs/findings.md", "filename": "findings.md", "media_type": "text/markdown", "size_bytes": 1420, "session_id": "ses_demo", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z" } ``` ### File An immutable, ready-to-download project upload or session output file. **One of:** discriminated by `kind` - [UploadedFileMetadata](/reference/schemas/UploadedFileMetadata.md), kind: `upload` A project upload from `POST /files`; `path`, `session_id` and `run_id` are null. - [OutputFileMetadata](/reference/schemas/OutputFileMetadata.md), kind: `output` An output file saved when a run completed normally, with its `session_id`, `run_id` and capture `path`. **Example:** ```json { "id": "file_demo", "kind": "output", "path": "/workspace/outputs/findings.md", "filename": "findings.md", "media_type": "text/markdown", "size_bytes": 1420, "session_id": "ses_demo", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z" } ``` ### UploadFile **Type:** `object`, no additional properties - **`file` (required)**: `string`, format: `binary` ### SessionCreatedEvent **Type:** `object`, no additional properties Session and initial configuration are durably created. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`session` (required)**: [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"session.created"` **Example:** ```json { "id": "evt_1", "session_id": "ses_demo", "sequence": 1, "created_at": "2026-09-29T17:00:00Z", "type": "session.created", "data": { "session": { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 1, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } } } ``` ### InputAcceptedEvent **Type:** `object`, no additional properties Input is durably accepted; not necessarily consumed. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`input` (required)**: [Input](/reference/schemas/Input.md) `accepted` means durably recorded; `applied` means the agent has taken it into model context. Steering is bound to its run on acceptance and never reassigned; queued input gets a `run_id` when its run starts. - **`status`**: `string`, const: `"accepted"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"input.accepted"` **Example:** ```json { "id": "evt_2", "session_id": "ses_demo", "sequence": 2, "created_at": "2026-09-29T17:00:00Z", "type": "input.accepted", "data": { "input": { "id": "inp_demo", "session_id": "ses_demo", "content": [ { "type": "text", "text": "Review the onboarding flow and save your findings under /workspace/outputs/." } ], "mode": "steer", "reasoning_effort": "medium", "status": "accepted", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z", "applied_at": null, "cancelled_at": null, "cancellation_reason": null } } } ``` ### InputAppliedEvent **Type:** `object`, no additional properties The agent has incorporated the input into its model context. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`input` (required)**: [Input](/reference/schemas/Input.md) `accepted` means durably recorded; `applied` means the agent has taken it into model context. Steering is bound to its run on acceptance and never reassigned; queued input gets a `run_id` when its run starts. - **`status`**: `string`, const: `"applied"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"input.applied"` **Example:** ```json { "id": "evt_3", "session_id": "ses_demo", "sequence": 3, "created_at": "2026-09-29T17:00:00Z", "type": "input.applied", "data": { "input": { "id": "inp_demo", "session_id": "ses_demo", "content": [ { "type": "text", "text": "Review the onboarding flow and save your findings under /workspace/outputs/." } ], "mode": "steer", "reasoning_effort": "medium", "status": "applied", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z", "applied_at": "2026-09-29T17:00:00Z", "cancelled_at": null, "cancellation_reason": null } } } ``` ### InputCancelledEvent **Type:** `object`, no additional properties An input was cancelled before it was applied; see `cancellation_reason`. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`input` (required)**: [Input](/reference/schemas/Input.md) `accepted` means durably recorded; `applied` means the agent has taken it into model context. Steering is bound to its run on acceptance and never reassigned; queued input gets a `run_id` when its run starts. - **`status`**: `string`, const: `"cancelled"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"input.cancelled"` **Example:** ```json { "id": "evt_4", "session_id": "ses_demo", "sequence": 4, "created_at": "2026-09-29T17:00:00Z", "type": "input.cancelled", "data": { "input": { "id": "inp_demo", "session_id": "ses_demo", "content": [ { "type": "text", "text": "Review the onboarding flow and save your findings under /workspace/outputs/." } ], "mode": "steer", "reasoning_effort": "medium", "status": "cancelled", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z", "applied_at": null, "cancelled_at": "2026-09-29T17:00:00Z", "cancellation_reason": "run_stopped" } } } ``` ### RunStartedEvent **Type:** `object`, no additional properties A single run begins. applied_input_ids is empty here; `input.applied` follows once the agent incorporates the initial input. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`run` (required)**: [Run](/reference/schemas/Run.md) One agent execution, started by one input and including steering applied while it is active; it can span many model generations and tool calls. `running`, `waiting_for_tools`, `interrupted` and `stopping` are active states with null `ended_at`; `completed`, `failed` and `stopped` are terminal. See `GET /sessions/{session_id}/runs/{run_id}`. - **`status`**: `string`, const: `"running"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"run.started"` **Example:** ```json { "id": "evt_5", "session_id": "ses_demo", "sequence": 5, "created_at": "2026-09-29T17:00:00Z", "type": "run.started", "data": { "run": { "id": "run_demo", "session_id": "ses_demo", "status": "running", "initial_input_id": "inp_demo", "applied_input_ids": [], "messages": [], "output_file_ids": [], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": null } } } ``` ### RunCompletedEvent **Type:** `object`, no additional properties Normal completion. Does not assert business correctness. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`run` (required)**: [Run](/reference/schemas/Run.md) One agent execution, started by one input and including steering applied while it is active; it can span many model generations and tool calls. `running`, `waiting_for_tools`, `interrupted` and `stopping` are active states with null `ended_at`; `completed`, `failed` and `stopped` are terminal. See `GET /sessions/{session_id}/runs/{run_id}`. - **`status`**: `string`, const: `"completed"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"run.completed"` **Example:** ```json { "id": "evt_6", "session_id": "ses_demo", "sequence": 18, "created_at": "2026-09-29T17:00:00Z", "type": "run.completed", "data": { "run": { "id": "run_demo", "session_id": "ses_demo", "status": "completed", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [ { "id": "msg_demo", "role": "assistant", "content": [ { "type": "text", "text": "I reviewed the flow and saved findings.md under /workspace/outputs/." } ], "created_at": "2026-09-29T17:00:00Z" } ], "output_file_ids": [ "file_demo" ], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": "2026-09-29T17:00:00Z" } } } ``` ### RunFailedEvent **Type:** `object`, no additional properties The run failed with `run.error`; the session is paused with no active run and queued input retained. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`run` (required)**: [Run](/reference/schemas/Run.md) One agent execution, started by one input and including steering applied while it is active; it can span many model generations and tool calls. `running`, `waiting_for_tools`, `interrupted` and `stopping` are active states with null `ended_at`; `completed`, `failed` and `stopped` are terminal. See `GET /sessions/{session_id}/runs/{run_id}`. - **`status`**: `string`, const: `"failed"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"run.failed"` **Example:** ```json { "id": "evt_7", "session_id": "ses_demo", "sequence": 7, "created_at": "2026-09-29T17:00:00Z", "type": "run.failed", "data": { "run": { "id": "run_demo", "session_id": "ses_demo", "status": "failed", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": { "code": "sandbox_lost", "message": "The sandbox became unavailable and work could not continue." }, "started_at": "2026-09-29T17:00:00Z", "ended_at": "2026-09-29T17:00:00Z" } } } ``` ### RunInterruptedEvent **Type:** `object`, no additional properties Execution was lost. The run remains active but is no longer executing, and the session is paused. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`run` (required)**: [Run](/reference/schemas/Run.md) One agent execution, started by one input and including steering applied while it is active; it can span many model generations and tool calls. `running`, `waiting_for_tools`, `interrupted` and `stopping` are active states with null `ended_at`; `completed`, `failed` and `stopped` are terminal. See `GET /sessions/{session_id}/runs/{run_id}`. - **`status`**: `string`, const: `"interrupted"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"run.interrupted"` **Example:** ```json { "id": "evt_harnesslost", "session_id": "ses_demo", "sequence": 8, "created_at": "2026-09-29T17:00:00Z", "type": "run.interrupted", "data": { "run": { "id": "run_demo", "session_id": "ses_demo", "status": "interrupted", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": { "code": "harness_lost", "message": "Execution was lost. The run is interrupted and will not resume automatically." }, "started_at": "2026-09-29T17:00:00Z", "ended_at": null } } } ``` ### RunStoppedEvent **Type:** `object`, no additional properties The platform stopped dispatching work for the target run; in-flight tool effects may remain. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`run` (required)**: [Run](/reference/schemas/Run.md) One agent execution, started by one input and including steering applied while it is active; it can span many model generations and tool calls. `running`, `waiting_for_tools`, `interrupted` and `stopping` are active states with null `ended_at`; `completed`, `failed` and `stopped` are terminal. See `GET /sessions/{session_id}/runs/{run_id}`. - **`status`**: `string`, const: `"stopped"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"run.stopped"` **Example:** ```json { "id": "evt_8", "session_id": "ses_demo", "sequence": 8, "created_at": "2026-09-29T17:00:00Z", "type": "run.stopped", "data": { "run": { "id": "run_demo", "session_id": "ses_demo", "status": "stopped", "initial_input_id": "inp_demo", "applied_input_ids": [ "inp_demo" ], "messages": [], "output_file_ids": [], "error": null, "started_at": "2026-09-29T17:00:00Z", "ended_at": "2026-09-29T17:00:00Z" } } } ``` ### SessionUpdatedEvent **Type:** `object`, no additional properties The session's status or queue changed; `data.session` is the new snapshot, including `pending_tool_calls`. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`session` (required)**: [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"session.updated"` **Example:** ```json { "id": "evt_9", "session_id": "ses_demo", "sequence": 9, "created_at": "2026-09-29T17:00:00Z", "type": "session.updated", "data": { "session": { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "active", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 9, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } } } ``` **Example:** ```json { "id": "evt_waiting", "session_id": "ses_demo", "sequence": 20, "created_at": "2026-09-29T17:00:00Z", "type": "session.updated", "data": { "session": { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_customer", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] }, "environment": { "type": "none" }, "status": "active", "active_run_id": "run_demo", "active_run_status": "waiting_for_tools", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 20, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } } } ``` **Example:** ```json { "id": "evt_resumed", "session_id": "ses_demo", "sequence": 22, "created_at": "2026-09-29T17:01:00Z", "type": "session.updated", "data": { "session": { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_customer", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Use get_customer to look up records for the session user.", "tools": [ { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ] }, "environment": { "type": "none" }, "status": "active", "active_run_id": "run_demo", "active_run_status": "running", "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 22, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:01:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } } } ``` ### SessionArchivedEvent **Type:** `object`, no additional properties Session is read-only; queued inputs have been cancelled. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`session` (required)**: [Session](/reference/schemas/Session.md) A session's configuration snapshot and current state; see `GET /sessions/{session_id}` for status and queue semantics. - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"session.archived"` **Example:** ```json { "id": "evt_10", "session_id": "ses_demo", "sequence": 10, "created_at": "2026-09-29T17:00:00Z", "type": "session.archived", "data": { "session": { "id": "ses_demo", "title": "Review the onboarding flow", "agent": { "id": "agt_demo", "version": 1 }, "agent_config": { "model": "openai/gpt-6.1-sol", "model_api_key_id": "mkey_demo", "instructions": "Research the request and save a report under /workspace/outputs/.", "tools": [ "read_file", "apply_patch", "web_search" ] }, "environment": { "type": "sandbox", "image": "managed-default", "network": { "allowed_hosts": [] } }, "status": "archived", "active_run_id": null, "active_run_status": null, "pending_input_count": 0, "sandbox_id": null, "last_event_sequence": 10, "created_at": "2026-09-29T17:00:00Z", "updated_at": "2026-09-29T17:00:00Z", "connections": [], "subject_id": "tenant_acme/user_demo", "pending_tool_calls": [] } } } ``` ### MessageCompletedEvent **Type:** `object`, no additional properties A complete assistant message was saved when its generation finished. It replaces any preview with the same message ID; interrupted generations produce no such event. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`message` (required)**: [AssistantMessage](/reference/schemas/AssistantMessage.md) - **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` - **`last_delta_index`**: `integer`, minimum: `-1` Index of the last preview chunk generated for this message, or -1 if none was. A subscriber may not have received every chunk. - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"message.completed"` **Example:** ```json { "id": "evt_11", "session_id": "ses_demo", "sequence": 11, "created_at": "2026-09-29T17:00:00Z", "type": "message.completed", "data": { "run_id": "run_demo", "message": { "id": "msg_demo", "role": "assistant", "content": [ { "type": "text", "text": "I reviewed the flow and saved findings.md under /workspace/outputs/." } ], "created_at": "2026-09-29T17:00:00Z" } } } ``` ### ToolStartedEvent **Type:** `object`, no additional properties A granted built-in or MCP call was dispatched by the platform. Application functions emit `tool.requested` instead. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`call` (required)**: [ToolCall](/reference/schemas/ToolCall.md) A durable tool call record. Platform calls (built-ins, and MCP tools with their `connection_id`) are `running` until `completed` or `failed`, or `cancelled` when their run stops or ends first. Application calls are `requested` until they become `completed`, `failed` or `cancelled`. An MCP tool error result fails the call with `mcp_tool_error`. Connection credentials never appear in tool records. - **`execution`**: `string`, const: `"platform"` - **`status`**: `string`, const: `"running"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"tool.started"` **Example:** ```json { "id": "evt_12", "session_id": "ses_demo", "sequence": 12, "created_at": "2026-09-29T17:00:00Z", "type": "tool.started", "data": { "call": { "id": "call_demo", "run_id": "run_demo", "tool": "web_search", "connection_id": null, "arguments": {}, "status": "running", "result": null, "error": null, "execution": "platform", "deadline_at": null } } } ``` ### ToolCompletedEvent **Type:** `object`, no additional properties A platform tool completed, or a successful application result was accepted. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`call` (required)**: [ToolCall](/reference/schemas/ToolCall.md) A durable tool call record. Platform calls (built-ins, and MCP tools with their `connection_id`) are `running` until `completed` or `failed`, or `cancelled` when their run stops or ends first. Application calls are `requested` until they become `completed`, `failed` or `cancelled`. An MCP tool error result fails the call with `mcp_tool_error`. Connection credentials never appear in tool records. - **`status`**: `string`, const: `"completed"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"tool.completed"` **Example:** ```json { "id": "evt_13", "session_id": "ses_demo", "sequence": 13, "created_at": "2026-09-29T17:00:00Z", "type": "tool.completed", "data": { "call": { "id": "call_demo", "run_id": "run_demo", "tool": "web_search", "connection_id": null, "arguments": {}, "status": "completed", "result": "Retrieved source material.", "error": null, "execution": "platform", "deadline_at": null } } } ``` **Example:** ```json { "id": "evt_customercompleted", "session_id": "ses_demo", "sequence": 21, "created_at": "2026-09-29T17:01:00Z", "type": "tool.completed", "data": { "call": { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "completed", "result": { "customer_id": "customer_123", "name": "Example Customer" }, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } } } ``` ### ToolFailedEvent **Type:** `object`, no additional properties A tool call failed, possibly with an uncertain external result. It need not follow `tool.started`: for example, expired or revoked credentials fail an MCP call before dispatch. Application calls fail when an error result is accepted or their deadline passes (`tool_result_timeout`). The agent may handle the failure and continue the run. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`call` (required)**: [ToolCall](/reference/schemas/ToolCall.md) A durable tool call record. Platform calls (built-ins, and MCP tools with their `connection_id`) are `running` until `completed` or `failed`, or `cancelled` when their run stops or ends first. Application calls are `requested` until they become `completed`, `failed` or `cancelled`. An MCP tool error result fails the call with `mcp_tool_error`. Connection credentials never appear in tool records. - **`status`**: `string`, const: `"failed"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"tool.failed"` **Example:** ```json { "id": "evt_14", "session_id": "ses_demo", "sequence": 14, "created_at": "2026-09-29T17:00:00Z", "type": "tool.failed", "data": { "call": { "id": "call_demo", "run_id": "run_demo", "tool": "web_fetch", "connection_id": null, "arguments": { "url": "https://example.com/report" }, "status": "failed", "result": null, "error": { "code": "web_fetch_failed", "message": "Web server returned HTTP 404." }, "execution": "platform", "deadline_at": null } } } ``` **Example:** ```json { "id": "evt_authfailed", "session_id": "ses_demo", "sequence": 18, "created_at": "2026-09-29T17:00:00Z", "type": "tool.failed", "data": { "call": { "id": "call_authfailed", "run_id": "run_demo", "tool": "search_documents", "connection_id": "conn_demo", "arguments": {}, "status": "failed", "result": null, "error": { "code": "mcp_authentication_failed", "message": "The MCP endpoint rejected authentication. Update the connection credentials through your backend." }, "execution": "platform", "deadline_at": null } } } ``` **Example:** ```json { "id": "evt_timeout", "session_id": "ses_demo", "sequence": 23, "created_at": "2026-09-29T17:10:00Z", "type": "tool.failed", "data": { "call": { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "failed", "result": null, "error": { "code": "tool_result_timeout", "message": "No result was accepted before the deadline; external execution may have occurred." }, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } } } ``` **Example:** ```json { "id": "evt_customerfailed", "session_id": "ses_demo", "sequence": 21, "created_at": "2026-09-29T17:01:00Z", "type": "tool.failed", "data": { "call": { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "failed", "result": null, "error": { "code": "customer_not_found", "message": "No visible customer matched the requested ID." }, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } } } ``` ### SandboxProvisionedEvent **Type:** `object`, no additional properties Lazy sandbox provisioning succeeded. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`sandbox_id` (required)**: `string`, pattern: `^sbx_[A-Za-z0-9]+$` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"sandbox.provisioned"` **Example:** ```json { "id": "evt_15", "session_id": "ses_demo", "sequence": 15, "created_at": "2026-09-29T17:00:00Z", "type": "sandbox.provisioned", "data": { "sandbox_id": "sbx_demo" } } ``` ### SandboxLostEvent **Type:** `object`, no additional properties Sandbox is unavailable. Session history and saved output files remain. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`reason` (required)**: `string`, minLength: `1` - **`sandbox_id` (required)**: `string`, pattern: `^sbx_[A-Za-z0-9]+$` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"sandbox.lost"` **Example:** ```json { "id": "evt_16", "session_id": "ses_demo", "sequence": 16, "created_at": "2026-09-29T17:00:00Z", "type": "sandbox.lost", "data": { "sandbox_id": "sbx_demo", "reason": "Sandbox connection was lost." } } ``` ### OutputFileCreatedEvent **Type:** `object`, no additional properties A saved output file is committed and ready to download. Emitted as part of normal run completion, before run.completed; never emitted for an uploaded input. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`file` (required)**: [OutputFileMetadata](/reference/schemas/OutputFileMetadata.md) An output file saved when a run completed normally, with its `session_id`, `run_id` and capture `path`. - **`kind`**: `string`, const: `"output"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"file.created"` **Example:** ```json { "id": "evt_17", "session_id": "ses_demo", "sequence": 17, "created_at": "2026-09-29T17:00:00Z", "type": "file.created", "data": { "file": { "id": "file_demo", "kind": "output", "path": "/workspace/outputs/findings.md", "filename": "findings.md", "media_type": "text/markdown", "size_bytes": 1420, "session_id": "ses_demo", "run_id": "run_demo", "created_at": "2026-09-29T17:00:00Z" } } } ``` ### Event A committed session event; see `GET /sessions/{session_id}/events`. **One of:** discriminated by `type` - [SessionCreatedEvent](/reference/schemas/SessionCreatedEvent.md), type: `session.created` Session and initial configuration are durably created. - [InputAcceptedEvent](/reference/schemas/InputAcceptedEvent.md), type: `input.accepted` Input is durably accepted; not necessarily consumed. - [InputAppliedEvent](/reference/schemas/InputAppliedEvent.md), type: `input.applied` The agent has incorporated the input into its model context. - [InputCancelledEvent](/reference/schemas/InputCancelledEvent.md), type: `input.cancelled` An input was cancelled before it was applied; see `cancellation_reason`. - [RunStartedEvent](/reference/schemas/RunStartedEvent.md), type: `run.started` A single run begins. applied_input_ids is empty here; `input.applied` follows once the agent incorporates the initial input. - [RunCompletedEvent](/reference/schemas/RunCompletedEvent.md), type: `run.completed` Normal completion. Does not assert business correctness. - [RunFailedEvent](/reference/schemas/RunFailedEvent.md), type: `run.failed` The run failed with `run.error`; the session is paused with no active run and queued input retained. - [RunInterruptedEvent](/reference/schemas/RunInterruptedEvent.md), type: `run.interrupted` Execution was lost. The run remains active but is no longer executing, and the session is paused. - [RunStoppedEvent](/reference/schemas/RunStoppedEvent.md), type: `run.stopped` The platform stopped dispatching work for the target run; in-flight tool effects may remain. - [SessionUpdatedEvent](/reference/schemas/SessionUpdatedEvent.md), type: `session.updated` The session's status or queue changed; `data.session` is the new snapshot, including `pending_tool_calls`. - [SessionArchivedEvent](/reference/schemas/SessionArchivedEvent.md), type: `session.archived` Session is read-only; queued inputs have been cancelled. - [MessageCompletedEvent](/reference/schemas/MessageCompletedEvent.md), type: `message.completed` A complete assistant message was saved when its generation finished. It replaces any preview with the same message ID; interrupted generations produce no such event. - [ToolStartedEvent](/reference/schemas/ToolStartedEvent.md), type: `tool.started` A granted built-in or MCP call was dispatched by the platform. Application functions emit `tool.requested` instead. - [ToolCompletedEvent](/reference/schemas/ToolCompletedEvent.md), type: `tool.completed` A platform tool completed, or a successful application result was accepted. - [ToolFailedEvent](/reference/schemas/ToolFailedEvent.md), type: `tool.failed` A tool call failed, possibly with an uncertain external result. It need not follow `tool.started`: for example, expired or revoked credentials fail an MCP call before dispatch. Application calls fail when an error result is accepted or their deadline passes (`tool_result_timeout`). The agent may handle the failure and continue the run. - [SandboxProvisionedEvent](/reference/schemas/SandboxProvisionedEvent.md), type: `sandbox.provisioned` Lazy sandbox provisioning succeeded. - [SandboxLostEvent](/reference/schemas/SandboxLostEvent.md), type: `sandbox.lost` Sandbox is unavailable. Session history and saved output files remain. - [OutputFileCreatedEvent](/reference/schemas/OutputFileCreatedEvent.md), type: `file.created` A saved output file is committed and ready to download. Emitted as part of normal run completion, before run.completed; never emitted for an uploaded input. - [ToolRequestedEvent](/reference/schemas/ToolRequestedEvent.md), type: `tool.requested` An application function call was requested and committed with its deadline and the `waiting_for_tools` state. Execute it and submit its result; receiving this event does not mean it ran. - [ToolCancelledEvent](/reference/schemas/ToolCancelledEvent.md), type: `tool.cancelled` An unresolved call, either a pending application call or a running platform tool, was cancelled with `tool_call_cancelled` because its run stopped or ended. New application results for it are rejected; a platform tool's later outcome is discarded and its effects are unknown. ### MessageDelta **Type:** `object`, no additional properties Transient text preview of an assistant message; see `GET /sessions/{session_id}/events/stream`. `index` counts chunks across all text blocks of the message. Preview text can differ from the final content. - **`content_index` (required)**: `integer`, minimum: `0` Index of the text block in the final public assistant message content array. - **`index` (required)**: `integer`, minimum: `0` - **`message_id` (required)**: `string`, pattern: `^msg_[A-Za-z0-9]+$` - **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`text` (required)**: `string` - **`type` (required)**: `string`, const: `"message.delta"` **Example:** ```json { "type": "message.delta", "session_id": "ses_demo", "run_id": "run_demo", "message_id": "msg_demo", "index": 0, "content_index": 0, "text": "Review the onboarding flow and save your findings under /workspace/outputs/." } ``` ### SSECommittedEvent **Type:** `object`, no additional properties A committed event's SSE frame after standard parsing: `id` and `event` equal the payload's `id` and `type`, and `data` is the JSON-encoded event as a string. `id` is the resume cursor. - **`data` (required)**: `string` - **`event` (required)**: `string`, possible values: `"session.created", "input.accepted", "input.applied", "input.cancelled", "run.started", "run.completed", "run.failed", "run.interrupted", "run.stopped", "session.updated", "session.archived", "message.completed", "tool.started", "tool.completed", "tool.failed", "sandbox.provisioned", "sandbox.lost", "file.created", "tool.requested", "tool.cancelled"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` **Example:** ```json { "id": "evt_demo", "event": "run.started", "data": "{\"id\":\"evt_demo\",\"session_id\":\"ses_demo\",\"sequence\":3,\"created_at\":\"2026-09-29T17:00:00Z\",\"type\":\"run.started\",\"data\":{\"run\":{\"id\":\"run_demo\",\"session_id\":\"ses_demo\",\"status\":\"running\",\"initial_input_id\":\"inp_demo\",\"applied_input_ids\":[],\"messages\":[],\"output_file_ids\":[],\"error\":null,\"started_at\":\"2026-09-29T17:00:00Z\",\"ended_at\":null}}}" } ``` ### SSEMessageDelta **Type:** `object`, no additional properties No id field: previews must not advance the durable reconnect cursor. - **`data` (required)**: `string` - **`event` (required)**: `string`, const: `"message.delta"` **Example:** ```json { "event": "message.delta", "data": "{\"type\":\"message.delta\",\"session_id\":\"ses_demo\",\"run_id\":\"run_demo\",\"message_id\":\"msg_demo\",\"index\":0,\"content_index\":0,\"text\":\"Hello!\"}" } ``` ### StreamItem **Type:** [SSECommittedEvent](/reference/schemas/SSECommittedEvent.md) | [SSEMessageDelta](/reference/schemas/SSEMessageDelta.md) ### AgentList **Type:** `object`, no additional properties - **`data` (required)**: array of [Agent](/reference/schemas/Agent.md) - **`next_cursor` (required)**: `string | null` ### ConnectionList **Type:** `object`, no additional properties - **`data` (required)**: array of [Connection](/reference/schemas/Connection.md) - **`next_cursor` (required)**: `string | null` ### SessionList **Type:** `object`, no additional properties - **`data` (required)**: array of [Session](/reference/schemas/Session.md) - **`next_cursor` (required)**: `string | null` ### InputList **Type:** `object`, no additional properties - **`data` (required)**: array of [Input](/reference/schemas/Input.md) - **`next_cursor` (required)**: `string | null` ### RunList **Type:** `object`, no additional properties - **`data` (required)**: array of [Run](/reference/schemas/Run.md) - **`next_cursor` (required)**: `string | null` ### EventList **Type:** `object`, no additional properties - **`data` (required)**: array of [Event](/reference/schemas/Event.md) - **`next_cursor` (required)**: `string | null` ### OutputFileList **Type:** `object`, no additional properties - **`data` (required)**: array of [OutputFileMetadata](/reference/schemas/OutputFileMetadata.md) - **`next_cursor` (required)**: `string | null` ### SecretHeaders **Type:** `object`, writeOnly Secret headers sent only to the connection's endpoint, such as `authorization` for a bearer token or a provider field such as `x-api-key`. Names are lowercase HTTP field names other than routing and transport-controlled fields; values are nonempty and contain no CR or LF. An empty object means no authentication. The credential configuration is never returned or exposed to the model, the sandbox or session history; response sanitization and its limits are described on POST /connections. **Additional properties:** `string`, minLength: `1`, pattern: `^[^\r\n]+$(?![\s\S])`, writeOnly **Example:** ```json { "authorization": "Bearer EXAMPLE_MCP_TOKEN" } ``` **Example:** ```json { "x-api-key": "EXAMPLE_PROVIDER_KEY" } ``` ### ReplaceConnectionCredentials **Type:** `object`, no additional properties The complete new credentials; see `PUT /connections/{connection_id}/credentials`. - **`headers` (required)**: [SecretHeaders](/reference/schemas/SecretHeaders.md) Secret headers sent only to the connection's endpoint, such as `authorization` for a bearer token or a provider field such as `x-api-key`. Names are lowercase HTTP field names other than routing and transport-controlled fields; values are nonempty and contain no CR or LF. An empty object means no authentication. The credential configuration is never returned or exposed to the model, the sandbox or session history; response sanitization and its limits are described on POST /connections. - **`expires_at`**: `string | null`, format: `date-time` Declared credential expiry; null or omitted means unknown. Known-expired credentials block dispatch. Empty headers reset it to null. **Example:** ```json { "headers": { "authorization": "Bearer EXAMPLE_REPLACEMENT_TOKEN" }, "expires_at": "2026-10-01T18:00:00Z" } ``` **Example:** ```json { "headers": {} } ``` ### SubjectId **Type:** `string`, minLength: `1`, maxLength: `256`, pattern: `^[^\x00-\x1f\x7f]+$(?![\s\S])` Opaque, case-sensitive end-user identity within the project, supplied by your backend after it authenticates the user; include the tenant when user IDs are only unique per tenant. It is not a credential or proof of authentication. Immutable on sessions and connections. ### SessionConnectionBinding **Type:** `object`, no additional properties A bound connection and its exact tool grants: `scope` is `reusable` for a registered connection and `session` for an inline one. - **`allowed_tools` (required)**: `array`, minItems: `1`, uniqueItems: `true` **Items:** `string`, minLength: `1`, pattern: `^[^*]+$` - **`connection_id` (required)**: `string`, pattern: `^conn_[A-Za-z0-9]+$` - **`scope` (required)**: `string`, possible values: `"reusable", "session"` ### BuiltinTool **Type:** `string`, possible values: `"shell", "read_file", "apply_patch", "view_image", "web_search", "web_fetch"` A built-in tool, granted individually; see `POST /agents`. ### ApplyPatchArguments **Type:** `object`, no additional properties Create, update or delete UTF-8 text files beneath `/workspace/` with a standard unified diff. Use LF-terminated structural headers, `--- a/path` and `+++ b/path`, where `path` is relative to `/workspace/`. One leading path component is removed, and the remaining path resolves within the workspace; redundant separators are normalized. Use `/dev/null` as the old path when creating a file or as the new path when deleting one. Creating a file never overwrites an existing entry, and missing parent directories are created. Numbered hunks use `@@ -old_start,old_count +new_start,new_count @@` headers, with space-prefixed unchanged context, `-`-prefixed removals and `+`-prefixed additions. Include unchanged context lines around partial-file edits; context-free partial hunks may be rejected. All supplied context must match exactly; whitespace is significant and no fuzzy matching is used. A hunk may apply at a shifted line position when its full context matches. Use `\ No newline at end of file` after a content line to represent a missing trailing newline. Existing targets must contain valid UTF-8 text. CRLF content lines are supported when the diff matches their carriage returns exactly. Patch text and target contents must not contain NUL bytes. Git-style `diff --git a/path b/path` headers are accepted. Empty-file creation uses `new file mode 100644` without content hunks; empty-file deletion uses `deleted file mode 100644` or `deleted file mode 100755` for an executable regular file. Regular executable text files can be updated or deleted. Resolved paths must be normalized workspace-relative paths, without traversal, absolute paths or symlinks. Renames, copies, binary patches, symlink creation and permission changes are unsupported. Created files have mode 0644; updates retain existing permissions. Attachment paths under `/workspace/inputs/` are writable working copies; edits do not alter their durable sources. Use `shell` for other file formats or transformations. Limits: 1 MiB of patch text, 64 distinct paths per patch, and 32 MiB total existing target bytes plus resulting content bytes. Repeated paths are rejected. Syntax, paths, existing targets and all hunks are validated before workspace contents change. Files are then changed in patch order. This is not a transaction: an I/O failure or sandbox loss can leave partial changes, and concurrent processes can change files during execution. Inspect affected paths before retrying an uncertain result. Invalid patches and filesystem failures return recoverable tool errors. - **`patch` (required)**: `string`, minLength: `1`, maxLength: `1048576` Patch text; the sandbox additionally enforces a 1 MiB UTF-8 byte limit. **Example:** ```json { "patch": "--- /dev/null\n+++ b/outputs/report.txt\n@@ -0,0 +1 @@\n+Draft report\n" } ``` **Example:** ```json { "patch": "--- a/outputs/report.txt\n+++ b/outputs/report.txt\n@@ -1 +1 @@\n-Draft report\n+Final report\n" } ``` ### ApplyPatchResult **Type:** `object`, no additional properties Successfully changed files in patch order, stored as a JSON-encoded string in ToolCall.result. File content remains in the sandbox; files under /workspace/outputs/ are collected when the run completes normally. - **`files` (required)**: `array`, minItems: `1`, maxItems: `64` **Items:** no additional properties - **`operation` (required)**: `string`, possible values: `"add", "update", "delete"` - **`path` (required)**: `string` **Example:** ```json { "files": [ { "path": "/workspace/outputs/report.txt", "operation": "update" } ] } ``` ### ViewImageArguments **Type:** `object`, no additional properties - **`path` (required)**: `string`, minLength: `1` Path to a static PNG, JPEG or WebP beneath /workspace/, absolute or relative to /workspace/. Workspace confinement and symlink rejection apply as for read_file. The pixels come from the current sandbox file, including edits to an attachment's working copy. **Example:** ```json { "path": "/workspace/page-1.png" } ``` ### ViewImageResult **Type:** `object`, no additional properties Metadata returned to the agent script and stored as a JSON-encoded string in ToolCall.result. The harness separately delivers the original image pixels to the model; no base64 or internal storage path is exposed in public history. - **`height` (required)**: `integer`, minimum: `1` - **`mime_type` (required)**: `string`, possible values: `"image/png", "image/jpeg", "image/webp"` - **`path` (required)**: `string`, minLength: `1` - **`size_bytes` (required)**: `integer`, minimum: `1` - **`width` (required)**: `integer`, minimum: `1` **Example:** ```json { "path": "/workspace/page-1.png", "mime_type": "image/png", "width": 800, "height": 600, "size_bytes": 42100 } ``` ### ShellArguments **Type:** `object`, no additional properties Arguments of the `shell` built-in, which waits for the command to finish and returns a `ShellResult`. - **`command` (required)**: `string`, minLength: `1`, maxLength: `65536` Command of 1 to 65,536 UTF-8 bytes, run in the session's sandbox. - **`timeout_ms`**: `integer`, default: `30000`, minimum: `1`, maximum: `60000` Execution deadline. When it is reached, the command's process group receives TERM, then is killed after a two-second grace period if needed. **Example:** ```json { "command": "printf hello", "timeout_ms": 30000 } ``` ### ShellResult **Type:** `object`, no additional properties Result of the `shell` built-in, stored as a JSON-encoded string in `ToolCall.result`. Use `exit_code` and `timed_out` to assess the outcome. - **`exit_code` (required)**: `integer` - **`stderr` (required)**: `string` Standard error, bounded to 2 MiB. - **`stdout` (required)**: `string` Standard output, bounded to 2 MiB. - **`timed_out` (required)**: `boolean` Inferred from exit code 124 or 137, which a command can also return itself, so it does not prove that the deadline was reached or establish external effects. - **`truncated` (required)**: `boolean` Whether output truncation was detected. **Example:** ```json { "stdout": "hello", "stderr": "", "exit_code": 0, "timed_out": false, "truncated": false } ``` ### FunctionTool **Type:** `object`, no additional properties A function executed by your application; see `POST /agents`. Its `name` is unique among the agent's tools and differs from built-in names. - **`description` (required)**: `string`, minLength: `1` - **`name` (required)**: `string`, minLength: `1`, maxLength: `64`, pattern: `^[A-Za-z_][A-Za-z0-9_]*$(?![\s\S])` - **`parameters` (required)**: `object` A valid JSON Schema 2020-12 for the argument object, with `type: object` at the root. References must be fragments within this schema, such as `#/$defs/customer`: external references are rejected, and `$id` values are allowed but never fetched. Keys named `$ref` or `$id` inside literal `const`, `enum`, `default` or `examples` values are data. Requested arguments must satisfy this schema before they become pending calls. - **`type` (required)**: `string`, const: `"object"` - **`type` (required)**: `string`, const: `"function"` **Example:** ```json { "type": "function", "name": "get_customer", "description": "Look up a customer visible to the authenticated application user.", "parameters": { "type": "object", "properties": { "customer_id": { "type": "string", "minLength": 1 } }, "required": [ "customer_id" ], "additionalProperties": false } } ``` ### AgentTool A supported built-in name or a customer-executed function definition. **One of:** - `string`, possible values: `"shell", "read_file", "apply_patch", "view_image", "web_search", "web_fetch"` A built-in tool, granted individually; see `POST /agents`. - [FunctionTool](/reference/schemas/FunctionTool.md) A function executed by your application; see `POST /agents`. Its `name` is unique among the agent's tools and differs from built-in names. ### PendingToolCall **Type:** `object`, no additional properties An unresolved application function call of the active run, with immutable fields. Execute it and submit its result with this `id` as `call_id`. - **`arguments` (required)**: `object` - **`connection_id` (required)**: `null` - **`deadline_at` (required)**: `string`, format: `date-time` - **`error` (required)**: `null` - **`execution` (required)**: `string`, const: `"application"` - **`id` (required)**: `string`, pattern: `^call_[A-Za-z0-9]+$` - **`result` (required)**: `null` - **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` - **`status` (required)**: `string`, const: `"requested"` - **`tool` (required)**: `string`, minLength: `1` **Example:** ```json { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ``` ### ToolResultError **Type:** `object`, no additional properties Customer-reported application failure. Supply a stable code and message without credentials; both enter model context and history. - **`code` (required)**: `string`, minLength: `1` - **`message` (required)**: `string`, minLength: `1` ### SuccessfulToolResult **Type:** `object`, no additional properties Successful application result. output is required even when null; error is not accepted. - **`call_id` (required)**: `string`, pattern: `^call_[A-Za-z0-9]+$` - **`output` (required)**: `any` Any JSON value, including null. Stored and given to the model as the tool result, so redact secrets. - **`success` (required)**: `boolean`, const: `true` **Example:** ```json { "call_id": "call_customer", "success": true, "output": { "customer_id": "customer_123", "name": "Example Customer" } } ``` ### FailedToolResult **Type:** `object`, no additional properties Application error result. error is required; output is not accepted. A tool error does not necessarily fail the run. - **`call_id` (required)**: `string`, pattern: `^call_[A-Za-z0-9]+$` - **`error` (required)**: [ToolResultError](/reference/schemas/ToolResultError.md) Customer-reported application failure. Supply a stable code and message without credentials; both enter model context and history. - **`success` (required)**: `boolean`, const: `false` **Example:** ```json { "call_id": "call_customer", "success": false, "error": { "code": "customer_not_found", "message": "No visible customer matched the requested ID." } } ``` ### ToolResult **Type:** [SuccessfulToolResult](/reference/schemas/SuccessfulToolResult.md) | [FailedToolResult](/reference/schemas/FailedToolResult.md) Exactly one successful output or failed error for a requested application function. ### SubmitToolResults **Type:** `object`, no additional properties Results for calls of run `run_id`, each `call_id` at most once; see `POST /sessions/{session_id}/tool-results`. - **`results` (required)**: array of [ToolResult](/reference/schemas/ToolResult.md), minItems: `1` - **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` **Example:** ```json { "run_id": "run_demo", "results": [ { "call_id": "call_customer", "success": true, "output": { "customer_id": "customer_123", "name": "Example Customer" } } ] } ``` ### ToolResultsReceipt **Type:** `object`, no additional properties The stored call records of this submission, in the order of the submitted results. An identical retry returns the same records. - **`calls` (required)**: array of [ApplicationResultCall](/reference/schemas/ApplicationResultCall.md), minItems: `1` - **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` **Example:** ```json { "session_id": "ses_demo", "run_id": "run_demo", "calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "completed", "result": { "customer_id": "customer_123", "name": "Example Customer" }, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` **Example:** ```json { "session_id": "ses_demo", "run_id": "run_demo", "calls": [ { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "failed", "result": null, "error": { "code": "customer_not_found", "message": "No visible customer matched the requested ID." }, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } ] } ``` ### ToolRequestedEvent **Type:** `object`, no additional properties An application function call was requested and committed with its deadline and the `waiting_for_tools` state. Execute it and submit its result; receiving this event does not mean it ran. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`call` (required)**: [PendingToolCall](/reference/schemas/PendingToolCall.md) An unresolved application function call of the active run, with immutable fields. Execute it and submit its result with this `id` as `call_id`. - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"tool.requested"` **Example:** ```json { "id": "evt_requested", "session_id": "ses_demo", "sequence": 19, "created_at": "2026-09-29T17:00:00Z", "type": "tool.requested", "data": { "call": { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "requested", "result": null, "error": null, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } } } ``` ### ToolCancelledEvent **Type:** `object`, no additional properties An unresolved call, either a pending application call or a running platform tool, was cancelled with `tool_call_cancelled` because its run stopped or ended. New application results for it are rejected; a platform tool's later outcome is discarded and its effects are unknown. - **`created_at` (required)**: `string`, format: `date-time` - **`data` (required)**: `object`, no additional properties - **`call` (required)**: [ToolCall](/reference/schemas/ToolCall.md) A durable tool call record. Platform calls (built-ins, and MCP tools with their `connection_id`) are `running` until `completed` or `failed`, or `cancelled` when their run stops or ends first. Application calls are `requested` until they become `completed`, `failed` or `cancelled`. An MCP tool error result fails the call with `mcp_tool_error`. Connection credentials never appear in tool records. - **`status`**: `string`, const: `"cancelled"` - **`id` (required)**: `string`, pattern: `^evt_[A-Za-z0-9]+$` - **`sequence` (required)**: `integer`, minimum: `1` - **`session_id` (required)**: `string`, pattern: `^ses_[A-Za-z0-9]+$` - **`type` (required)**: `string`, const: `"tool.cancelled"` **Example:** ```json { "id": "evt_cancelled", "session_id": "ses_demo", "sequence": 23, "created_at": "2026-09-29T17:00:00Z", "type": "tool.cancelled", "data": { "call": { "id": "call_customer", "run_id": "run_demo", "tool": "get_customer", "connection_id": null, "arguments": { "customer_id": "customer_123" }, "status": "cancelled", "result": null, "error": { "code": "tool_call_cancelled", "message": "The run stopped before a result was accepted." }, "execution": "application", "deadline_at": "2026-09-29T17:10:00Z" } } } ``` ### ApplicationResultCall **Type:** `object`, no additional properties An application call resolved by a submitted result. Expired and cancelled calls never appear in receipts. **Any of:** - `object` - **`error`**: `null` - **`status`**: `string`, const: `"completed"` - `object` - **`error`**: [ToolResultError](/reference/schemas/ToolResultError.md) Customer-reported application failure. Supply a stable code and message without credentials; both enter model context and history. - **`result`**: `null` - **`status`**: `string`, const: `"failed"` * **`arguments` (required)**: `object` * **`connection_id` (required)**: `null` * **`deadline_at` (required)**: `string`, format: `date-time` * **`error` (required)**: [ToolResultError](/reference/schemas/ToolResultError.md) | `null` Customer-reported application failure. Supply a stable code and message without credentials; both enter model context and history. * **`execution` (required)**: `string`, const: `"application"` * **`id` (required)**: `string`, pattern: `^call_[A-Za-z0-9]+$` * **`result` (required)**: `any` The accepted output, which may be any JSON value including null; null when `status` is `failed`, with the error in `error`. * **`run_id` (required)**: `string`, pattern: `^run_[A-Za-z0-9]+$` * **`status` (required)**: `string`, possible values: `"completed", "failed"` * **`tool` (required)**: `string`, minLength: `1` ## Encoded content schemas ### [SSECommittedEvent](/reference/schemas/SSECommittedEvent.md) - **`data`**: Encoded `application/json` content conforms to [Event](/reference/schemas/Event.md). ### [SSEMessageDelta](/reference/schemas/SSEMessageDelta.md) - **`data`**: Encoded `application/json` content conforms to [MessageDelta](/reference/schemas/MessageDelta.md). ## Stream item schemas ### [GET /sessions/{session_id}/events/stream](/reference/operations/get_sessions_session_id_events_stream.md) - **200 text/event-stream**: Each streamed item conforms to [StreamItem](/reference/schemas/StreamItem.md). # Code samples ## [GET /sessions/{session_id}/events/stream](/reference/operations/get_sessions_session_id_events_stream.md) ### Python (streaming) ```python import json import os import time import requests base = os.environ["PLATFORM_API_BASE_URL"].rstrip("/") sid = os.environ["SESSION_ID"] url = base + f"/sessions/{sid}/events/stream" cursor = os.environ.get("LAST_EVENT_ID") seen = set() while True: headers = {"Authorization": "Bearer " + os.environ["PLATFORM_API_KEY"], "Accept": "text/event-stream"} if cursor: headers["Last-Event-ID"] = cursor try: with requests.get(url, headers=headers, stream=True, params={"include_deltas": "true"}, timeout=(10, 60)) as response: if response.status_code == 410: raise RuntimeError("Cursor expired; reconcile live events and history") response.raise_for_status() response.encoding = "utf-8" print("stream_open", flush=True) data = [] for line in response.iter_lines(chunk_size=1, decode_unicode=True): if line.startswith("data:"): data.append(line[5:].lstrip(" ")) elif not line and data: event = json.loads("\n".join(data)) data = [] event_id = event.get("id") if event_id is None or event_id not in seen: print(json.dumps(event), flush=True) if event_id is not None: seen.add(event_id) if event_id is not None: cursor = event_id if event["type"] == "session.archived": raise SystemExit(0) except (requests.ConnectionError, requests.Timeout, requests.exceptions.ChunkedEncodingError): pass # A lost stream never stops the run; resume committed events. time.sleep(1) ```