Documentation/docs/managed-agents/claude-sdk

#Claude SDK

Use the official Anthropic SDK for client code. The only SDK-level change is the API host and key:

SDK fieldValue
baseURLSandbox0 Managed Agents API endpoint
apiKeySandbox0 API key
LLM tokenNot passed to the SDK client. Store it in an LLM vault.

The SDK sets the Managed Agents beta header automatically. If you call the HTTP API directly, include anthropic-beta: managed-agents-2026-04-01.

TypeScript Example#

typescript
import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ baseURL: process.env.SANDBOX0_MANAGED_AGENTS_URL ?? "https://agents.sandbox0.ai", apiKey: process.env.SANDBOX0_API_KEY, }); const suffix = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`; const environment = await client.beta.environments.create({ name: `demo-env-${suffix}`, config: { type: "cloud", networking: { type: "unrestricted" }, packages: { type: "packages" }, }, }); const agent = await client.beta.agents.create({ name: `Demo Agent ${suffix}`, model: { id: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-20250514" }, system: "Reply in one short sentence.", tools: [{ type: "agent_toolset_20260401" }], }); const llmVault = await client.beta.vaults.create({ display_name: `Claude LLM ${suffix}`, metadata: { "sandbox0.managed_agents.role": "llm", "sandbox0.managed_agents.engine": "claude", "sandbox0.managed_agents.llm_base_url": process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com", }, }); await client.beta.vaults.credentials.create(llmVault.id, { display_name: "Anthropic-compatible API key", auth: { type: "static_bearer", token: process.env.ANTHROPIC_API_KEY, }, }); const session = await client.beta.sessions.create({ agent: agent.id, environment_id: environment.id, title: `Sandbox0 demo ${suffix}`, metadata: { // Optional hard TTL. Managed Agents disables soft TTL and pauses/resumes itself; this defaults to 3600 seconds. // Set this to "0" only if the session should have no hard cost cap. "sandbox0.managed_agents.hard_ttl_seconds": "3600", }, vault_ids: [llmVault.id], }); await client.beta.sessions.events.send(session.id, { events: [ { type: "user.message", content: [{ type: "text", text: "Say hello from Sandbox0 managed agents." }], }, ], }); for await (const event of client.beta.sessions.events.list(session.id, { limit: 100 })) { if (event.type === "agent.message") { console.log(event.content?.map((block) => block.text ?? "").join("")); } }

Required Environment Variables#

VariableDescription
SANDBOX0_API_KEYAPI key for the Sandbox0 Managed Agents API
SANDBOX0_MANAGED_AGENTS_URLOptional API endpoint override, defaults to https://agents.sandbox0.ai in examples
ANTHROPIC_API_KEYLLM provider token stored in the LLM vault
ANTHROPIC_BASE_URLOptional Anthropic-compatible LLM base URL
ANTHROPIC_MODELOptional model id passed in the agent definition

Do not set the SDK client's apiKey to the Anthropic model token when calling Sandbox0 Managed Agents. The SDK authenticates to the Sandbox0 API. The LLM token belongs in the vault attached to the session.

Session Hard TTL#

Sandbox0 Managed Agents claims a sandbox when the session is created, then pauses and resumes it around agent work. The sandbox uses a hard TTL as a cost cap. The default hard TTL is 3600 seconds.

Use the official session metadata field to override the hard TTL at session creation:

typescript
const session = await client.beta.sessions.create({ agent: agent.id, environment_id: environment.id, metadata: { "sandbox0.managed_agents.hard_ttl_seconds": "7200", }, vault_ids: [llmVault.id], });
Metadata keyValue
sandbox0.managed_agents.hard_ttl_secondsNon-negative integer string, in seconds

Omit the key to use the deployment default. Set it to "0" only when the session should have no hard cost cap. The key is read when the session is created; updating session metadata later does not change the sandbox hard TTL.

This controls the sandbox hard TTL. It does not change event retention, SDK request timeouts, or LLM provider limits. Managed Agents disables the sandbox soft TTL because the backend controls pause and resume directly.

Event Handling#

The event log is the durable interface for a session. A client can list past events or stream events through the SDK. Treat session.status_idle as the normal end-of-turn state. If the idle event contains stop_reason.type = "requires_action", send the required confirmation or custom tool result event before expecting the run to continue.

Common event types:

EventMeaning
user.messageUser input sent by your application
agent.messageText output from the agent
agent.tool_useBuilt-in tool request
agent.mcp_tool_useMCP tool request
agent.custom_tool_useCustom tool call that your application must answer
user.tool_confirmationAllow or deny a tool that requires confirmation
user.custom_tool_resultResult for a custom tool call
session.status_idleThe agent has stopped for now or needs action
session.status_runningA run is active
session.errorSession-level runtime or integration error

Direct HTTP Calls#

Direct HTTP calls are useful for debugging, but application code should prefer the official SDK.

bash
curl -fsS "$SANDBOX0_MANAGED_AGENTS_URL/v1/sessions" \ -H "x-api-key: $SANDBOX0_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "anthropic-beta: managed-agents-2026-04-01" \ -H "content-type: application/json" \ -d '{ "agent": "agent_...", "environment_id": "env_...", "vault_ids": ["vlt_..."] }'

Next Steps#

LLM Credentials

Store the model host and provider token in a vault before creating sessions

Compatibility

Check the supported API surface and current Sandbox0 differences