> ## Documentation Index
> Fetch the complete documentation index at: https://docs.browserbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Managed Agents quickstart

> Create an Anthropic Managed Agent, start a session, and drive a Browserbase session from inside the sandbox.

This guide sets up a Claude Managed Agent that browses the web through a Browserbase session. You create the agent and environment once, then start as many sessions as you need.

## Prerequisites

* An [Anthropic API key](https://console.anthropic.com) — Managed Agents is enabled by default for all API accounts in beta
* A [Browserbase API key and project ID](https://www.browserbase.com/settings)
* Node.js 18+

## 1. Install dependencies

```bash theme={null}
npm install @anthropic-ai/sdk @browserbasehq/sdk
npm install -g @browserbasehq/cli @browserbasehq/browse-cli
```

Claude uses `@browserbasehq/browse-cli` (`browse`) to drive the session. Session creation can go through `@browserbasehq/cli` (`bb`) or `curl` — install both so you can switch freely. Step 2 declares them as sandbox dependencies too.

## 2. Create the agent and environment

Create both once, store the returned IDs as env vars, and reuse them across sessions.

```typescript theme={null}
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const SYSTEM_PROMPT = `You are a browsing agent. You control a remote Browserbase session via the browse CLI.

Workflow:
1. Create a Browserbase session — either with: bb sessions create --body '{"projectId":"<PROJECT_ID>"}' or with curl against https://api.browserbase.com/v1/sessions
2. Prefix every browse command with BROWSERBASE_API_KEY=<key> and use --connect <sessionId>.
3. Take screenshots to see the page. Only take snapshots (truncated with | head -200) when you need ref IDs to click.
4. Report findings concisely and cite key URLs.`;

const agent = await client.beta.agents.create({
  name: "Browserbase Agent",
  model: "claude-opus-4-7",
  system: SYSTEM_PROMPT,
  tools: [
    {
      type: "agent_toolset_20260401",
      configs: [
        { name: "web_fetch", enabled: false },
        { name: "web_search", enabled: false },
      ],
    },
  ],
});

const environment = await client.beta.environments.create({
  name: "browserbase-env",
  config: {
    type: "cloud",
    packages: {
      npm: ["@browserbasehq/cli", "@browserbasehq/browse-cli"],
    },
    networking: { type: "unrestricted" },
  },
});

console.log(`MANAGED_AGENT_ID=${agent.id}`);
console.log(`MANAGED_ENVIRONMENT_ID=${environment.id}`);
```

<Note>
  The Anthropic SDK sets the `managed-agents-2026-04-01` beta header automatically. If you're calling the REST API directly with `curl`, add `-H "anthropic-beta: managed-agents-2026-04-01"` to every request.
</Note>

<Note>
  Disabling `web_fetch` and `web_search` forces Claude to browse through Browserbase. Leave them on and Claude shortcuts around the real browser.
</Note>

## 3. Set your environment variables

```bash theme={null}
ANTHROPIC_API_KEY=sk-ant-...
BROWSERBASE_API_KEY=bb_...
BROWSERBASE_PROJECT_ID=proj_...
MANAGED_AGENT_ID=agent_...
MANAGED_ENVIRONMENT_ID=env_...
```

## 4. Start a session and stream events

A session is one running instance of the agent. You open an SSE stream against the session, send a user message, and process events as they arrive — agent text, tool calls, and a final `session.status_idle` event when Claude is done.

The prompt tells Claude how to create a Browserbase session. You can show it either flavor — the `bb` CLI or `curl` straight against the API. Both work; pick whichever you prefer and stay consistent.

<Tabs>
  <Tab title="bb CLI">
    ```typescript theme={null}
    const prompt = `Go to Hacker News, find the top story, and summarize the comments.

    You have these credentials available:
    BROWSERBASE_API_KEY=${process.env.BROWSERBASE_API_KEY}
    BROWSERBASE_PROJECT_ID=${process.env.BROWSERBASE_PROJECT_ID}

    Create a Browserbase session with the bb CLI:
      export BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY
      bb sessions create --body '{"projectId":"'$BROWSERBASE_PROJECT_ID'"}'

    The command prints JSON with an \`id\` — that's your sessionId. Then drive the session:
      BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY browse --json --connect <sessionId> open https://news.ycombinator.com`;
    ```
  </Tab>

  <Tab title="curl">
    ```typescript theme={null}
    const prompt = `Go to Hacker News, find the top story, and summarize the comments.

    You have these credentials available:
    BROWSERBASE_API_KEY=${process.env.BROWSERBASE_API_KEY}
    BROWSERBASE_PROJECT_ID=${process.env.BROWSERBASE_PROJECT_ID}

    Create a Browserbase session with curl:
      curl -s -X POST https://api.browserbase.com/v1/sessions \\
        -H "Content-Type: application/json" \\
        -H "x-bb-api-key: $BROWSERBASE_API_KEY" \\
        -d '{"projectId":"'$BROWSERBASE_PROJECT_ID'"}'

    The response JSON has an \`id\` field — that's your sessionId. Then drive the session:
      BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY browse --json --connect <sessionId> open https://news.ycombinator.com`;
    ```
  </Tab>
</Tabs>

```typescript theme={null}
const session = await client.beta.sessions.create({
  agent: process.env.MANAGED_AGENT_ID!,
  environment_id: process.env.MANAGED_ENVIRONMENT_ID!,
  title: "Browserbase quickstart",
});

const stream = await client.beta.sessions.events.stream(session.id);

// Send the user message after the stream opens
await client.beta.sessions.events.send(session.id, {
  events: [
    {
      type: "user.message",
      content: [{ type: "text", text: prompt }],
    },
  ],
});

// Process streaming events until the agent goes idle
for await (const event of stream) {
  if (event.type === "agent.message") {
    for (const block of event.content) {
      process.stdout.write(block.text);
    }
  } else if (event.type === "agent.tool_use") {
    console.log(`\n[Using tool: ${event.name}]`);
  } else if (event.type === "session.status_idle") {
    console.log("\n\nAgent finished.");
    break;
  }
}
```

The session lives until you archive it — Anthropic only bills for compute while it's running. Event history is persisted server-side and you can refetch it with `client.beta.sessions.events.list(session.id)`.

## 5. Watch the run live

Every Browserbase session has a [Live View](/platform/browser/observability/session-live-view) URL. Grab it once the agent creates the session — from your own code with the Browserbase SDK, from the sandbox with the `bb` CLI, or directly with `curl`.

<Tabs>
  <Tab title="Browserbase SDK">
    ```typescript theme={null}
    import Browserbase from "@browserbasehq/sdk";

    const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY! });
    const debug = await bb.sessions.debug(sessionId);
    console.log(debug.debuggerFullscreenUrl);
    ```
  </Tab>

  <Tab title="bb CLI">
    ```bash theme={null}
    bb sessions debug $SESSION_ID
    ```

    Pipe through `jq` to extract `debuggerFullscreenUrl`:

    ```bash theme={null}
    bb sessions debug $SESSION_ID | jq -r .debuggerFullscreenUrl
    ```
  </Tab>

  <Tab title="curl">
    ```bash theme={null}
    curl -s https://api.browserbase.com/v1/sessions/$SESSION_ID/debug \
      -H "x-bb-api-key: $BROWSERBASE_API_KEY"
    ```
  </Tab>
</Tabs>

Share the URL in your UI (Slack, web app, or dashboard) so users can watch Claude drive the browser in real time. After the session ends, the full video replay appears in [session recordings](/platform/browser/observability/session-recording).

## Ending the session

Two sessions to clean up — Anthropic's and Browserbase's.

**Anthropic Managed Agents:** archive the session when you're done. Archiving terminates the container and stops compute billing. Sessions are also deleted after a TTL — see [Anthropic's docs](https://docs.claude.com/en/docs/managed-agents/sessions) for current values.

```typescript theme={null}
await client.beta.sessions.archive(session.id);
```

**Browserbase:** sessions don't end automatically — close them explicitly or rely on the session timeout.

<Tabs>
  <Tab title="Browserbase SDK">
    ```typescript theme={null}
    import Browserbase from "@browserbasehq/sdk";

    const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY! });
    await bb.sessions.update(sessionId, {
      projectId: process.env.BROWSERBASE_PROJECT_ID!,
      status: "REQUEST_RELEASE",
    });
    ```
  </Tab>

  <Tab title="bb CLI">
    ```bash theme={null}
    bb sessions update $SESSION_ID \
      --body '{"projectId":"'$BROWSERBASE_PROJECT_ID'","status":"REQUEST_RELEASE"}'
    ```
  </Tab>

  <Tab title="curl">
    ```bash theme={null}
    curl -s -X POST https://api.browserbase.com/v1/sessions/$SESSION_ID \
      -H "Content-Type: application/json" \
      -H "x-bb-api-key: $BROWSERBASE_API_KEY" \
      -d '{"projectId":"'$BROWSERBASE_PROJECT_ID'","status":"REQUEST_RELEASE"}'
    ```
  </Tab>
</Tabs>

## Troubleshooting

<AccordionGroup>
  <Accordion title="The agent keeps using web_search instead of the browser.">
    Disable `web_search` and `web_fetch` in the `agent_toolset_20260401` configs. Without them, Claude has to use the Browse CLI.
  </Accordion>

  <Accordion title="Snapshots blow past the context window.">
    Pipe every snapshot through `head -200`. Tell Claude in the system prompt to prefer `screenshot` over `snapshot` and only fall back to snapshots when it needs a ref ID to click.
  </Accordion>

  <Accordion title="`browse --connect <sessionId>` fails with an auth error.">
    Every browse invocation needs `BROWSERBASE_API_KEY` in the environment. Prefix each command: `BROWSERBASE_API_KEY=$KEY browse --json --connect $SID open https://...`.
  </Accordion>

  <Accordion title="The session times out before the agent finishes.">
    Long-running sessions stay alive — Anthropic only times out compute, not the session itself. If you're hitting an inactivity timeout, send another `user.message` event to wake the agent up. For multi-stage workflows, just keep sending events on the same session ID; the conversation history is preserved server-side.
  </Accordion>

  <Accordion title="How do I reuse a browser across runs?">
    Don't end the Browserbase session between user messages. Pass the existing `sessionId` in the next prompt and Claude reconnects with `browse --connect <sessionId>`. Cookies and local storage persist because it's the same browser. Across separate Anthropic sessions, use [Browserbase Contexts](/platform/browser/core-features/contexts) to persist cookies and storage.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Browse CLI reference" icon="terminal" href="https://www.npmjs.com/package/@browserbasehq/browse-cli">
    Every command Claude can issue against a Browserbase session.
  </Card>

  <Card title="Session Live View" icon="eye" href="/platform/browser/observability/session-live-view">
    Embed real-time browser views in your chat UI.
  </Card>

  <Card title="Contexts" icon="database" href="/platform/browser/core-features/contexts">
    Persist cookies and storage across agent runs.
  </Card>

  <Card title="Agent Identity" icon="shield-check" href="/platform/identity/overview">
    Verified browsers, proxies, and auth for agents on the open web.
  </Card>
</CardGroup>
