#Claude SDK
Use the official Anthropic SDK for client code. The only SDK-level change is the API host and key:
| SDK field | Value |
|---|---|
baseURL | Sandbox0 Managed Agents API endpoint |
apiKey | Sandbox0 API key |
| LLM token | Not 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#
typescriptimport 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#
| Variable | Description |
|---|---|
SANDBOX0_API_KEY | API key for the Sandbox0 Managed Agents API |
SANDBOX0_MANAGED_AGENTS_URL | Optional API endpoint override, defaults to https://agents.sandbox0.ai in examples |
ANTHROPIC_API_KEY | LLM provider token stored in the LLM vault |
ANTHROPIC_BASE_URL | Optional Anthropic-compatible LLM base URL |
ANTHROPIC_MODEL | Optional 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:
typescriptconst 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 key | Value |
|---|---|
sandbox0.managed_agents.hard_ttl_seconds | Non-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:
| Event | Meaning |
|---|---|
user.message | User input sent by your application |
agent.message | Text output from the agent |
agent.tool_use | Built-in tool request |
agent.mcp_tool_use | MCP tool request |
agent.custom_tool_use | Custom tool call that your application must answer |
user.tool_confirmation | Allow or deny a tool that requires confirmation |
user.custom_tool_result | Result for a custom tool call |
session.status_idle | The agent has stopped for now or needs action |
session.status_running | A run is active |
session.error | Session-level runtime or integration error |
Direct HTTP Calls#
Direct HTTP calls are useful for debugging, but application code should prefer the official SDK.
bashcurl -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