Managed Agents API
The Managed Agents API runs your organization’s Context agents from your own code. Each session you start shows up as a task in the app, along with its transcript. The request and response shapes follow Anthropic’s Managed Agents API, so Anthropic’s Python, TypeScript and .NET SDKs can call it (see SDKs). If you are porting code written for Anthropic, read Coming from Anthropic’s API first.
Core concepts
| Concept | What it is |
|---|---|
| Agent | The worker a session runs. Build agents in the Context app or create them with this API. |
| Environment | The place a session runs: env_default, the platform’s cloud environment. |
| Session | One conversation with an agent. Each message you send starts a turn. |
| Events | The messages and approvals you send, and everything the session streams back. |
| File | A document you upload for a session to read, or a file a session produced. |
| Skill | A folder of instructions and files that an agent loads when a task needs it. |
How it works
- Pick an agent with List agents (
GET /v1/agents), or create one with a personal key that hasagents:write. - Create a session for it in an environment, optionally with uploaded files. You choose an environment rather than create one (see Environments).
- Open the event stream, then send a
user.message. - When the session goes idle with
stop_reason.typeset torequires_action, approve or deny the waiting tool calls. Repeat until it goes idle withend_turn. Then send another message, or archive the session. - List the files the session produced by setting
scope_idto the session ID, then download them.
Prerequisites
You need a personal Task API key, or a service account key for automations. You also need an agent in your
organization, or a personal key with agents:write to create one. For help deciding, see Choose a key.
To approve tool calls, turn on tasks:approve when you create the key. You can’t add it later.
Where to start
Basics
Base URL and authentication
Your deployment is the Context instance your organization signs in to. The base URL is its host plus /v1, for example
https://api.context.ai/v1. Request and response bodies are JSON, except for file upload (multipart/form-data), file download (raw bytes) and the event stream (server-sent events).
Authenticate with a Task API key in the x-api-key header. Authorization: Bearer <key> also works.
anthropic-version and anthropic-beta are accepted and ignored.
The examples set CONTEXT_BASE_URL to your deployment’s host and CONTEXT_API_KEY to your key.
curl -sS "$CONTEXT_BASE_URL/v1/agents" -H "x-api-key: $CONTEXT_API_KEY"Keys
Create a key in the app under Settings > API > Task keys > New key. The key is shown only once. The default capabilities include
connectors:manage and workspaces:members:read, capabilities for other Context APIs that only an organization
administrator can grant. If you aren’t an administrator, clear both before you save, or the key isn’t created. Keys come in two types, which
Choose a key compares in full.
| Type | Use it for | Who can create it | What it can read |
|---|---|---|---|
| Personal | Calling your own agents from your own code. | Any member, for themselves. | Sessions you own and the agents you can run. |
| Service account | Automations, backends and CI. It can’t approve tool calls. | An organization administrator. | The agents in the organization and the sessions it created, including sessions it created for other members. |
Session ownership. A session belongs to the key’s owner. A service account key can instead name any active member
as the owner when it creates the session, with the x-context-owner-user-id or x-context-owner-user-email header.
That member owns the session and sees it in the app.
A session that a service account key starts on an agent with an Ask tool waits forever. In the app, each of an
agent’s tools has an approval setting, Ask or Allow. The session goes idle with
stop_reason.type: "requires_action" and stays there, because a service account key can’t approve tool calls. Set
those tools to Allow before you start sessions with a service account key.
Agent scope. If you set Agent scope to one agent when you create a key, the key can read only that agent and its sessions.
Write access. To rename, archive or delete a session, or to send it events, use the owner’s personal key or the
service account key that created it. A key that can read the session but doesn’t act for its owner gets 403. A key
that can’t read the session gets 404.
A key stops working when its owner leaves the organization. The owner of a service account key is the administrator who created it, so automations that use a service account key stop when that administrator leaves.
Where your deployment enforces rate limits, each key has a request limit (see Limits). These limits differ from Anthropic’s, which Coming from Anthropic’s API compares.
A key’s capabilities decide which endpoints it can call. This table lists the capabilities this API uses:
| Capability | Endpoints | Default | Key types |
|---|---|---|---|
tasks:read | Every GET, including the event stream, except the file and skill endpoints. | On | Both |
tasks:create | Create, rename and archive sessions, and send events. | On | Both |
tasks:approve | Send user.tool_confirmation. | Off | Personal only |
agents:write | Create and update agents. | Off | Personal only |
sessions:delete | Delete sessions. A service account key deletes only the sessions it created. | Off | Both |
files:read | List, get and download files, including the files a session produced. | On | Both |
files:write | Upload and delete files. | On | Both |
skills:read | List, get and download skills and their versions. | On | Both |
skills:write | Create skills and their versions, and delete skills. | Off | Personal only |
To use a capability that is off by default, turn it on when you create the key. You can’t add a capability to an existing key, so create a new key instead.
Errors
Every error returns an HTTP status code and a JSON body with this shape:
{ "type": "error", "error": { "type": "permission_error", "message": "Task API key missing required capability: tasks:create" }, "request_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"}| Status | error.type | Cause and fix |
|---|---|---|
| 400 | invalid_request_error | A field, header or query parameter is missing or invalid. The message names it. Fix the request before you retry. |
| 401 | authentication_error | The request has no key, or its key is unknown, revoked or expired, or the key’s owner left the organization. Send a valid key, or create a new one. |
| 402 | billing_error | Your deployment requires a paid plan or credits before a session’s output can be downloaded. Add a plan or credits in the app, then retry. |
| 403 | permission_error | The key lacks a capability, can’t run the agent or doesn’t act for the session’s owner. A service account key also gets 403 for user.tool_confirmation and for deleting a file it didn’t upload. Use a key that has the capability and acts for the session’s owner. For user.tool_confirmation, use a personal key. |
| 404 | not_found_error | The resource doesn’t exist, this key can’t read it, or the path isn’t part of this API. Check the ID, the path and the key’s Agent scope. |
| 409 | invalid_request_error | The request conflicts with the session’s or the skill’s current state. See the causes below the table. |
| 413 | request_too_large | An uploaded file is over your deployment’s upload limit, a skill upload is over 32 MiB, or another request body is over 10 MiB. Send a smaller file or body. |
| 429 | rate_limit_error | The key hit one of three limits: open streams on the server instance that answered (24 by default), uploads in progress on that instance, or a rate limit your deployment enforces. Close a stream, or wait for the time given in Retry-After. |
| 500 | api_error | An unexpected error occurred. Quote request_id when you contact support. A session delete that returns 500 deleted nothing, so retry it. A session request with more than 50 attached files also returns 500, which is a known defect. Attach 50 or fewer. |
| 503 | api_error | The session’s history is still being indexed. Wait a few seconds, then retry the request. |
A 409 has one of these causes. Its error.type is invalid_request_error, not Anthropic’s conflict_error, so
check the status code.
- The session’s state changed before the request arrived: another client answered the tool call first, or the session is stopping or moving to another computer. List the session’s events, then send again only if the request still applies.
- A session delete arrived while a turn was running. Wait for the turn to end, or interrupt it.
- A skill with that name exists. Choose another name.
An unknown query parameter returns 400, and so do the Idempotency-Key and anthropic-workspace-id headers. The
x-context-owner-user-id and x-context-owner-user-email headers work only on
Create a session, and return 400 anywhere else. The API ignores any
other unknown header.
Every response carries an x-request-id header with the same value as request_id. Send your own x-request-id
(1 to 256 printable ASCII characters) to set it. Quote it when you contact support.
Errors inside a running session arrive as events on the stream, not as HTTP status codes. While a session retries, it emits session.error with
retry_status.type: "retrying" and keeps running. When the retries run out, it emits session.error with "exhausted",
then goes idle with stop_reason.type: "retries_exhausted". Send a new message to try again. The event’s error.type says
what failed: a rate limit, an overloaded or failed model call, billing, or an unknown cause. See
Session errors.
A session can also wait without an error, when a service account key starts it on an agent with an Ask tool (see Keys).
Sending events isn’t idempotent. If a send times out or the connection drops, the server might already have the
events. List the session’s events before you send again. Turn off SDK retries so the SDK doesn’t resend for you
(max_retries=0 in Python, maxRetries: 0 in TypeScript, MaxRetries = 0 in .NET).
Pagination
List endpoints take limit and page and return next_page. Pass next_page back as page until it is null.
page values are opaque, except on List events, where they are event IDs.
next_page only moves forward, and the prev_page on List sessions is
always null. List files also takes after_id and before_id. A
response to a before_id request has next_page: null. To page further back, pass that response’s first_id as the
next before_id.
{ "data": [ ... ], "next_page": "eyJ0IjoiMjAyNi0xMC0yMVQwMTo0MjoxNi4wNzlaIn0" }Limits
| Limit | Value |
|---|---|
| Requests | 7,500 a minute per key, or 2,500 for a service account key, where your deployment enforces rate limits. |
| File upload | Your deployment’s upload limit: 5 GiB unless your administrator set it lower. 10 MiB for an upload sent without Content-Length. |
| Skill upload | 32 MiB per request, and 30 MiB for the skill’s files once unpacked. |
| Other request bodies | 10 MiB per request. |
| Uploads in progress | 4 file uploads and 2 skill uploads per key on each server instance. |
| Message text | 100,000 characters per event. |
| Session title | 280 characters. |
| Files attached to a session | 50. See Errors for what a request with more returns. |
| Page size | 20 by default, up to 100. For events, 100 by default, up to 1,000. For skills, up to 200. |
| Open event streams | 24 per key on each server instance, unless your deployment sets another number. A deployment can run more than one instance, so don’t count on more than that in total. |
Network access
Every environment reports networking.type as unrestricted, which is the only value the API accepts.
unrestricted means the session’s sandbox can reach the public internet, unless your deployment restricts it (see
the note below). Model calls are separate. Context handles them, and the sandbox’s network access doesn’t govern them. Nothing you set
through the API changes network access.
Self-hosted (KOTS) deployments can restrict sandbox outbound traffic to a list of allowed domains. It’s a
setting in the KOTS Admin Console, not in the API. Your administrator turns on Sandbox Egress Proxy (domain
allowlist) and lists the domains in Sandbox Egress Proxy Allowlist, or turns off Sandbox Internet Access.
With Sandbox Workload Identity on, the same choice is Sandbox Egress Posture, set to Open internet,
Domain allowlist or Workspace only. The API’s networking label doesn’t reflect this setting, so environments
report unrestricted even when the install is tighter. To set it up, ask your Context contact.
Coming soon: limited networking. An environment will be able to set networking.type to limited with
an allowed_hosts list, as in Anthropic’s Managed Agents. The list will cover the sandbox’s outbound traffic, the web
fetch tool (a blocked host returns a tool error) and the web search tool (results from blocked hosts are left out).
If an agent uses an MCP server whose host isn’t on the list, creating the session will fail. Model calls won’t be
covered. Until it ships, a request to create an environment with limited networking returns 400, as
Environments shows.
How long data is kept
Context deletes nothing on a schedule, and no setting sets a retention period. Your deployment keeps sessions, their
history, uploaded files and skills until you delete them. Archiving a session doesn’t delete anything, and a file’s
expires_in_seconds isn’t applied. Three requests delete data:
| Request | What it deletes | What it keeps |
|---|---|---|
| Delete a session | The session’s task and its subagents’ tasks, with their events and transcripts. The session’s inputs/ copies and the files it produced. Its sandbox and saved workspace, its LLM traces, and the memories its runs saved. | Billing usage and cost. Audit records. Dispatch history, with its prompt, title and output text cleared. Files you uploaded. Notes in the agent’s own .memory folder, which belong to the agent rather than to one session. Storage residue that no API returns. |
| Delete a file | A file you uploaded. It can’t be restored. | Storage residue that no API returns. |
| Delete a skill | The skill, its versions and their files, and its place on every agent that had it. | Storage residue that no API returns. In some organizations the skill’s files are kept in Drive trash until the trash is emptied. |
Deleting a session needs sessions:delete, which is off by default (see Keys).
Storage residue, in the table, means copies that no API returns and that the storage underneath removes on its own schedule. Deleted trace rows stay until the trace store’s next merge. On storage that keeps versions, the earlier versions of removed files stay until they expire.
Streaming
Stream events sends the session’s events as server-sent events. The stream sends only events that happen after it opens, so open it before you send a message. That page also explains how a stream ends and how to reconnect without losing events. Events lists every event type.
Specification
The OpenAPI file openapi.json describes the endpoints in this reference. Your deployment also serves a specification at GET /v1/openapi.json, with
no key needed. It is built from the server’s own route descriptions, so its wording differs from these pages.