SDKs
Use Anthropic’s official Python, TypeScript and .NET SDKs to call your deployment’s Managed Agents API. The API uses the
same request and response shapes as Anthropic’s Managed Agents API, so the SDKs work once you point them at your
deployment. Some SDK methods aren’t supported and return 404 or 400. For the full list, see
Coming from Anthropic’s API.
Install the SDK
The examples in these docs use the following SDK versions.
| Language | Package | Version |
|---|---|---|
| Python | anthropic | 1.17.0 |
| TypeScript | @anthropic-ai/sdk | 0.137.0 |
| .NET | Anthropic (NuGet) | 12.44.0 |
pip install anthropic==1.17.0npm install @anthropic-ai/sdk@0.137.0dotnet add package Anthropic --version 12.44.0The Python and TypeScript examples in the Quickstart and the playbooks
run against a deployment. The cURL examples aren’t run. The other TypeScript examples compile with tsc --strict,
and the other Python examples match the SDK’s signatures. The .NET SDK is tested against every response
and event shape the API sends, with the SDK’s response checks on. For what differs in .NET, see .NET.
Set up the client
Set the base URL to your deployment’s address without a path, for example https://api.context.ai. The SDK adds /v1
itself. Pass your Task API key as the API key. To decide which key to create, see
Choose a key.
import osfrom anthropic import Anthropic
client = Anthropic( base_url=os.environ["CONTEXT_BASE_URL"], # for example https://api.context.ai api_key=os.environ["CONTEXT_API_KEY"], max_retries=0,)import Anthropic from "@anthropic-ai/sdk"
const client = new Anthropic({ baseURL: process.env.CONTEXT_BASE_URL, // for example https://api.context.ai apiKey: process.env.CONTEXT_API_KEY, maxRetries: 0,})Set max_retries to 0 in Python, maxRetries to 0 in TypeScript or MaxRetries to 0 in .NET. Sending events
isn’t idempotent, so a retried send can deliver a message twice.
The endpoints are under client.beta: agents, environments, sessions, sessions.events, files and skills.
Each endpoint’s reference page shows its SDK method.
Context headers
Some calls accept headers that are specific to Context. Pass them per call with extra_headers in Python or the
headers request option in TypeScript. For example, a service account key can name the session’s owner with the
x-context-owner-user-email header when it creates a session. Without the header, the key’s owner owns the session.
session = client.beta.sessions.create( agent="6f1c2a9e-0d4b-4c57-9a3e-2b7d8e1f4c60", environment_id="env_default", extra_headers={"x-context-owner-user-email": "member@example.com"},)const session = await client.beta.sessions.create( { agent: "6f1c2a9e-0d4b-4c57-9a3e-2b7d8e1f4c60", environment_id: "env_default" }, { headers: { "x-context-owner-user-email": "member@example.com" } },)Pagination
When you loop over a list call, the SDK fetches each next page for you. limit sets the page size. It defaults to 20 and can be up to 100. For events, it
defaults to 100 and can be up to 1,000. For skills, it can be up to 200.
for session in client.beta.sessions.list(limit=100): print(session.id)for await (const session of client.beta.sessions.list({ limit: 100 })) console.log(session.id)Streaming
Open the stream before you send an event, because the stream carries only events that happen after it opens. Stop
reading at the first session.status_idle event whose stop_reason.type isn’t requires_action. A requires_action
stop means the agent is waiting for you to approve or deny a tool call. To answer it, see the
tool approvals playbook.
The SDKs don’t reconnect a dropped stream. To resume, reopen it with the Last-Event-ID header set to the ID of the
last event you received. For how a stream ends and reconnects, see
Stream events.
Each key can have 24 streams open on each server instance, unless your deployment sets another number. Opening another
returns 429, so close each stream when you’re done with it.
last_id = Nonewith client.beta.sessions.events.stream(session_id) as stream: for event in stream: last_id = event.id if event.type == "session.status_idle" and event.stop_reason.type != "requires_action": break
# After a dropped connection:stream = client.beta.sessions.events.stream(session_id, extra_headers={"Last-Event-ID": last_id})let lastId: string | undefinedconst stream = await client.beta.sessions.events.stream(sessionId)for await (const event of stream) { if ("id" in event) lastId = event.id if (event.type === "session.status_idle" && event.stop_reason.type !== "requires_action") break}
// After a dropped connection:const resumed = await client.beta.sessions.events.stream(sessionId, {}, { headers: { "Last-Event-ID": lastId! } })Errors
An error response raises an exception in Python and throws one in TypeScript. The base class is APIStatusError in
Python and APIError in TypeScript. Each status has its own subclass, such as NotFoundError for 404. The error body, including request_id, is in err.body in Python
and err.error in TypeScript.
import anthropic
try: client.beta.sessions.retrieve("dd13d728-93e3-440a-874c-4efeb58c97e0")except anthropic.APIStatusError as err: print(err.status_code, err.body["error"]["message"], err.body["request_id"])import Anthropic from "@anthropic-ai/sdk"
try { await client.beta.sessions.retrieve("dd13d728-93e3-440a-874c-4efeb58c97e0")} catch (err) { if (err instanceof Anthropic.APIError) console.log(err.status, err.error) // err.error is the error body}.NET
Set BaseUrl to your deployment’s address without a path, ApiKey to your Task API key and MaxRetries to 0.
using Anthropic;
IAnthropicClient client = new AnthropicClient{ BaseUrl = Environment.GetEnvironmentVariable("CONTEXT_BASE_URL")!, // for example https://api.context.ai ApiKey = Environment.GetEnvironmentVariable("CONTEXT_API_KEY")!, MaxRetries = 0,};var session = await client.Beta.Sessions.Create(new() { Agent = agentId, EnvironmentID = "env_default" });The .NET SDK differs from the other two in a few places:
- Uploads need a filename. Give the
BinaryContentyou upload aFileName. A barebyte[]sends no filename, and the upload returns400. - Context headers go on a per-call client. In 12.44.0 the client’s own
ExtraHeadersisn’t public. Add a header such asx-context-owner-user-emailwithclient.WithOptions(o => o with { ExtraHeaders = ... }), and use that client only to create the session. Every other request refuses the owner header. - The stream skips
session.usage. The SDK’s stream reader drops event names it doesn’t know, andsession.usageis one of them. Read usage from the session (client.Beta.Sessions.Retrieve(id)) or from the event list. - Open the stream before you send.
client.Beta.Sessions.Events.WithRawResponse.StreamStreaming(id)returns once the stream is open.StreamStreaming(id)sends its request only when you start reading. - The stream’s
errorframe raisesAnthropicSseException, withErrorTypeset to the error’s type.
See also
- Coming from Anthropic’s API lists the calls that return
404or400, the headers that are ignored or refused and the limits that differ. - Stream events shows which frames the stream sends, how it ends and how to reconnect.