then: histchars= HISTFILE=/dev/null ant beta:worker poll --workdir /workspace changedmanaged-agents/self-hosted/call-the-api
## Prerequisites ## Point your client at your server ## Start a session ## Send a message and read the reply ## Move data in and out of a session ## Find more examples in the hosted guides ## Run your own workers ### Create an environment and its key ### Run a local experiment ### Run workers in production ### Build your own sandbox image ### Move workers from the hosted service ## Next steps
The whole hunk
751 lines, new pageA whole new page. There's nothing to diff it against, so here is what it says.
---
title: Call the API on a self-hosted server
url: https://platform.claude.com/docs/en/managed-agents/self-hosted/call-the-api
description: Point the official SDK, cURL, or the ant CLI at your self-hosted Claude Managed Agents server, start a session, and read the agent's reply. Then connect workers of your own, if you need them.
---
<Note>
To request access to self-hosted Claude Managed Agents, contact your Anthropic account team.
</Note>
A self-hosted Claude Managed Agents server has the same API as Anthropic’s hosted [Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) service. Your code calls it with the official SDK, cURL, or the `ant` CLI. Two things change: the base URL is your server’s address, and the API key is your [server API key](https://platform.claude.com/docs/en/managed-agents/self-hosted#the-three-credentials) instead of a Claude API key.
To create agents and run sessions in a browser, see [Use the console on your server](https://platform.claude.com/docs/en/managed-agents/self-hosted/console).
## Prerequisites
* **A running server:** Start one with [Get started with self-hosted Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/self-hosted/quickstart) or [Deploy on Kubernetes](https://platform.claude.com/docs/en/managed-agents/self-hosted/kubernetes).
* **Access to the server:** If someone else runs the server, ask them for its address and how to authenticate. If they use single sign-on, see [Let developers log in from a terminal](https://platform.claude.com/docs/en/managed-agents/self-hosted/configure#let-developers-log-in-from-a-terminal).
* **The `ant` CLI:** Install the latest version, as the [CLI quickstart](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/quickstart#installation) shows.
## Point your client at your server
The SDK and the `ant` CLI read the server address from `ANTHROPIC_BASE_URL` and the API key from `ANTHROPIC_API_KEY`. Set both variables in a terminal that you keep for this server.
For the [quickstart stack](https://platform.claude.com/docs/en/managed-agents/self-hosted/quickstart), run these commands from the directory that holds your `.env` file:
```bash
export ANTHROPIC_BASE_URL=http://127.0.0.1:8400
export ANTHROPIC_API_KEY=$(grep '^CMA_SERVER__API_KEY=' .env | cut -d= -f2)
```
On Kubernetes, set the two variables as [Run a session](https://platform.claude.com/docs/en/managed-agents/self-hosted/kubernetes#run-a-session) shows, and keep its port-forward running.
In that terminal, every `ant` command, such as `ant beta:agents list`, reaches your server. Don’t run Claude Code or `docker compose` in that terminal, because they read the same variables.
## Start a session
A session needs the ID of an agent and the ID of an environment:
* **Agent:** Create one as [Create an agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#create-an-agent) shows, with your client pointed at your server. If you send raw HTTP requests, replace `https://api.anthropic.com` in the URL with `$ANTHROPIC_BASE_URL`.
* **Environment:** The quickstart stack creates one named `compose-sandbox`, and the Helm charts create one named `default`. `ant beta:environments list` prints each environment’s name and ID. For your own workers, it’s the ID that the admin CLI printed in [Run your own workers](https://platform.claude.com/docs/en/managed-agents/self-hosted/call-the-api#point-a-worker-at-your-server).
Put your two IDs in your shell, in place of these example IDs:
```bash
export AGENT_ID=agent_011CYm1BLqPXpQRk5khsSXrs
export ENVIRONMENT_ID=env_01595EKxaaTTGwwY3kyXdtbs
```
The following example creates a session and sends its first message in the same request:
<CodeGroup>
```bash cURL
curl -sS --fail-with-body "$ANTHROPIC_BASE_URL/v1/sessions" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2026-10-21" \
-H "anthropic-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
-d '{
"agent": "'"$AGENT_ID"'",
"environment_id": "'"$ENVIRONMENT_ID"'",
"initial_events": [
{
"type": "user.message",
"content": [{"type": "text", "text": "List the files in the working directory."}]
}
]
}'
```
```bash CLI
ant beta:sessions create --agent "$AGENT_ID" --environment-id "$ENVIRONMENT_ID" \
--initial-event '{type: user.message, content: [{type: text, text: "List the files in the working directory."}]}'
```
```python Python
import os
from anthropic import Anthropic
client = Anthropic()
session = client.beta.sessions.create(
agent=os.environ["AGENT_ID"],
environment_id=os.environ["ENVIRONMENT_ID"],
initial_events=[
{
"type": "user.message",
"content": [
{"type": "text", "text": "List the files in the working directory."}
],
},
],
)
print(session.id)
```
```typescript TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const session = await client.beta.sessions.create({
agent: process.env["AGENT_ID"]!,
environment_id: process.env["ENVIRONMENT_ID"]!,
initial_events: [
{
type: "user.message",
content: [{ type: "text", text: "List the files in the working directory." }]
}
]
});
console.log(session.id);
```
```csharp C#
using System;
using Anthropic;
using Anthropic.Models.Beta.Agents;
using Anthropic.Models.Beta.Sessions;
using Anthropic.Models.Beta.Sessions.Events;
AnthropicClient client = new();
var session = await client.Beta.Sessions.Create(new()
{
Agent = Environment.GetEnvironmentVariable("AGENT_ID")!,
EnvironmentID = Environment.GetEnvironmentVariable("ENVIRONMENT_ID")!,
InitialEvents =
[
new BetaManagedAgentsUserMessageEventParams
{
Content =
[
new BetaManagedAgentsTextBlock
{
Text = "List the files in the working directory.",
},
],
},
],
});
Console.WriteLine(session.ID);
```
```go Go
package main
import (
"context"
"fmt"
"os"
"github.com/anthropics/anthropic-sdk-go/v2"
)
func main() {
client := anthropic.NewClient()
session, err := client.Beta.Sessions.New(context.Background(), anthropic.BetaSessionNewParams{
Agent: anthropic.BetaSessionNewParamsAgentUnion{
OfString: anthropic.String(os.Getenv("AGENT_ID")),
},
EnvironmentID: os.Getenv("ENVIRONMENT_ID"),
InitialEvents: []anthropic.BetaSessionNewParamsInitialEventUnion{{
OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
OfText: &anthropic.BetaManagedAgentsTextBlockParam{
Text: "List the files in the working directory.",
},
}},
},
}},
})
if err != nil {
panic(err)
}
fmt.Println(session.ID)
}
```
```java Java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.beta.sessions.SessionCreateParams;
import com.anthropic.models.beta.sessions.events.BetaManagedAgentsUserMessageEventParams;
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
var session = client.beta().sessions().create(SessionCreateParams.builder()
.agent(System.getenv("AGENT_ID"))
.environmentId(System.getenv("ENVIRONMENT_ID"))
.addInitialEvent(BetaManagedAgentsUserMessageEventParams.builder()
.addTextContent("List the files in the working directory.")
.build())
.build());
IO.println(session.id());
}
```
```php PHP
<?php
use Anthropic\Client;
$client = new Client();
$session = $client->beta->sessions->create(
agent: (string) getenv('AGENT_ID'),
environmentID: (string) getenv('ENVIRONMENT_ID'),
initialEvents: [
[
'type' => 'user.message',
'content' => [['type' => 'text', 'text' => 'List the files in the working directory.']],
],
],
);
echo $session->id, "\n";
```
```ruby Ruby
require "anthropic"
client = Anthropic::Client.new
session = client.beta.sessions.create(
agent: ENV.fetch("AGENT_ID"),
environment_id: ENV.fetch("ENVIRONMENT_ID"),
initial_events: [
{
type: :"user.message",
content: [{type: :text, text: "List the files in the working directory."}]
}
]
)
puts session.id
```
</CodeGroup>
The response holds the session’s ID, which starts with `sesn_`. The agent starts work at once. Its built-in tools, such as `bash`, run on a worker that serves the environment.
To watch the session, open the [console on your server](https://platform.claude.com/docs/en/managed-agents/self-hosted/console) in a browser, select **Sessions**, and then select the session. A session that you started with the server API key, as on this page, appears only to administrators.
To follow the session in your terminal instead, pass its ID to [`ant beta:sessions connect`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/sessions-connect):
```bash
ant beta:sessions connect sesn_011CZkZAtmR3yMPDzynEDxu7
```
For what else a session can do, such as pinning an agent version, see [Start a session](https://platform.claude.com/docs/en/managed-agents/sessions).
## Send a message and read the reply
Put your session’s ID in your shell, in place of this example ID:
```bash
export SESSION_ID=sesn_011CZkZAtmR3yMPDzynEDxu7
```
Wait until the session is idle before you run the next example. The example stops reading when a turn ends. If an earlier turn is still running, its end can stop the example before the reply to your message arrives. The console and `ant beta:sessions connect` both show the session’s status.
The following example sends a message and prints the agent’s reply. It opens the session’s event stream first, because a stream delivers only the events that come after it opens:
<CodeGroup exclude="shell">
<CodeGroupItem language="cURL">
This workflow needs more logic than a single shell command. Use the [Anthropic SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
</CodeGroupItem>
<CodeGroupItem language="CLI">
This workflow needs more logic than a single shell command. To send messages and read the replies in your terminal, use [`ant beta:sessions connect`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/sessions-connect).
</CodeGroupItem>
```python Python
import os
from anthropic import Anthropic
client = Anthropic()
session_id = os.environ["SESSION_ID"]
with client.beta.sessions.events.stream(session_id) as stream:
client.beta.sessions.events.send(
session_id,
events=[
{
"type": "user.message",
"content": [
{"type": "text", "text": "Summarize what you did in one sentence."}
],
},
],
)
for event in stream:
match event.type:
case "agent.message":
for block in event.content:
if block.type == "text":
print(block.text, end="")
Cut at 300 lines. The page has the rest.
No line in this hunk matches that.