Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ docs/.mintlify/
# Claude Code
.claude/skills/

# OMC / harness state (any directory level)
.omc/
.harness/
omc/
harness/

# Personal notes
reagan_*
.pnpm-store
35 changes: 35 additions & 0 deletions docs/cloud/agent/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: Overview
description: "The hosted agent takes a task in plain language and drives a stealth browser until it's done."
icon: robot
---

The agent is a hosted loop: it reads the page, decides an action, executes it, and repeats until the task is complete. You send a task, you get a result.

```python
from browser_use_sdk import BrowserUse

@cubic-dev-ai cubic-dev-ai Bot Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Code example imports v2 (from browser_use_sdk import BrowserUse) but links to the quickstart which uses v3 (from browser_use_sdk.v3 import AsyncBrowserUse). A reader following the overview example will write sync v2 code, then find the quickstart with a different async v3 import path. Stick to one API version throughout the agent section to avoid confusion — either match the quickstart's v3 import, or use the v4 client (from browser_use_sdk.v4 import BrowserUse) which is the current API.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/cloud/agent/overview.mdx, line 10:

<comment>Code example imports v2 (`from browser_use_sdk import BrowserUse`) but links to the quickstart which uses v3 (`from browser_use_sdk.v3 import AsyncBrowserUse`). A reader following the overview example will write sync v2 code, then find the quickstart with a different async v3 import path. Stick to one API version throughout the agent section to avoid confusion — either match the quickstart's v3 import, or use the v4 client (`from browser_use_sdk.v4 import BrowserUse`) which is the current API.</comment>

<file context>
@@ -0,0 +1,35 @@
+The agent is a hosted loop: it reads the page, decides an action, executes it, and repeats until the task is complete. You send a task, you get a result.
+
+```python
+from browser_use_sdk import BrowserUse
+
+client = BrowserUse()
</file context>
Fix with cubic


client = BrowserUse()
result = client.run("List the top 5 posts on Hacker News with their points")
print(result.output)
```

Each run gets its own [stealth cloud browser](/cloud/browser/stealth) with proxies and CAPTCHA handling already on. No browser management, no selectors, no waiting logic.

## When to use the agent

The agent fits tasks where you care about the outcome, not the exact clicks: data extraction from sites that change layout, workflows across several pages, form submission, or anything you'd rather describe than script. If you need pixel-exact control or deterministic repetition, drive a [browser session](/cloud/browser/overview) directly instead, or record an agent run once and replay it with [cache scripts](/cloud/agent/cache-script).

## What the agent can do

- [Structured output](/cloud/agent/structured-output) — get results as typed JSON matching your schema
- [Follow-up tasks](/cloud/agent/follow-up-tasks) — continue in the same browser with context intact
- [Streaming](/cloud/agent/streaming) — watch steps as they happen
- [Workspaces](/cloud/agent/workspaces) — files the agent reads and writes during a run
- [Human-in-the-loop](/cloud/agent/human-in-the-loop) — take over the browser mid-task, then hand back
- [Models](/cloud/agent/models) — pick the LLM that drives the loop
- [Cache scripts](/cloud/agent/cache-script) — record a run, replay it without LLM calls

## Next

Start with the [agent quickstart](/cloud/agent/quickstart).
140 changes: 140 additions & 0 deletions docs/cloud/agent/sessions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
title: Sessions
description: "One cloud browser plus the tasks an agent runs inside it."
icon: layer-group
---

A session is the container the agent works in: **one cloud browser and one or more tasks**, sharing the same browser state. When you call `client.run()`, the SDK creates a session and runs your first task inside it — you don't have to manage sessions yourself unless you want to.

```python
from browser_use_sdk import BrowserUse

client = BrowserUse()

# client.run() creates a session and runs the task inside it
result = client.run("List the top 5 posts on Hacker News with their points")
print(result.output)
```

Create a session explicitly when you want to run several tasks in the same browser, embed a live view before the first task, or manage the session's lifecycle yourself.

## Session vs. task vs. browser session

These three are easy to confuse:

| Concept | What it is |
| --- | --- |
| **Session** | The agent's workspace — one browser plus every task run in it. Context (page, cookies, tabs) carries across tasks. |
| **Task** | A single agent run: one natural-language instruction, its steps, and its output. `client.run()` is one task. |
| **[Browser session](/cloud/browser/overview)** | The raw Chrome instance itself, driven directly over CDP without an agent. |

A session *holds* tasks and *wraps* a browser. If you want the agent to decide the clicks, you're in session/task territory. If you want to drive Chrome yourself, use a [browser session](/cloud/browser/overview) directly.

## Create a session and run tasks in it

Pass `session_id` to `client.run()` to run each task in the same session. The browser state carries over between tasks — see [Follow-up tasks](/cloud/agent/follow-up-tasks).

<CodeGroup>
```python Python
from browser_use_sdk import BrowserUse

client = BrowserUse()

session = client.sessions.create()

client.run(
"Go to amazon.com, search for laptops, and open the first result",
session_id=session.id,
)
client.run("Extract the customer reviews", session_id=session.id)

client.sessions.stop(session.id)
```
```typescript TypeScript
import { BrowserUse } from "browser-use-sdk";

const client = new BrowserUse();

const session = await client.sessions.create();

await client.run("Go to amazon.com, search for laptops, and open the first result", {
sessionId: session.id,
});
await client.run("Extract the customer reviews", { sessionId: session.id });

await client.sessions.stop(session.id);
```
</CodeGroup>

`sessions.create()` returns a `live_url` you can embed to watch tasks execute — see [Live preview](/cloud/browser/live-preview).

<Note>
Sessions time out after 15 minutes of inactivity by default. The maximum session duration is 4 hours.
</Note>

## Lifecycle

A session is `active` while its browser is running and `stopped` once it ends — whether you stop it, it times out, or it hits the 4-hour cap. Stopping a session stops every task still running inside it.

## Manage sessions

<CodeGroup>
```python Python
# List sessions for the project
sessions = client.sessions.list()

# Inspect one
session = client.sessions.get(session_id)
print(session.status)

# Stop it (and any running tasks)
client.sessions.stop(session_id)

# Delete it and all its tasks
client.sessions.delete(session_id)
```
```typescript TypeScript
// List sessions for the project
const sessions = await client.sessions.list();

// Inspect one
const session = await client.sessions.get(sessionId);
console.log(session.status);

// Stop it (and any running tasks)
await client.sessions.stop(sessionId);

// Delete it and all its tasks
await client.sessions.delete(sessionId);
```
</CodeGroup>

## Share a session

Create a public share link to let anyone view a session's replay without an API key.

<CodeGroup>
```python Python
share = client.sessions.create_share(session_id)
print(share.share_url)

# Later
client.sessions.delete_share(session_id)
```
```typescript TypeScript
const share = await client.sessions.createShare(sessionId);
console.log(share.shareUrl);

// Later
await client.sessions.deleteShare(sessionId);
```
</CodeGroup>

For projects on zero-data-retention, `client.sessions.purge(session_id)` immediately deletes all data for a session.

## Next

- [Follow-up tasks](/cloud/agent/follow-up-tasks) — run multiple tasks in one session
- [Streaming](/cloud/agent/streaming) — watch steps as they happen
- [Live preview](/cloud/browser/live-preview) — embed the browser in your UI
- [Browser sessions](/cloud/browser/overview) — drive Chrome directly without an agent
10 changes: 10 additions & 0 deletions docs/cloud/api-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ Get a key at [cloud.browser-use.com/settings](https://cloud.browser-use.com/sett
https://api.browser-use.com/api/v3
```

## OpenAPI spec

The full API surface is published as a machine-readable OpenAPI 3.1 spec — use it to generate typed clients or validate payloads:

```
https://docs.browser-use.com/openapi.json
```

Also at [/cloud/openapi/v3.json](https://docs.browser-use.com/cloud/openapi/v3.json). Legacy v2 spec: [/cloud/openapi/v2.json](https://docs.browser-use.com/cloud/openapi/v2.json).

## Quick example

```bash Create a session
Expand Down
2 changes: 2 additions & 0 deletions docs/cloud/api-v2-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export BROWSER_USE_API_KEY=your_key

Base URL: `https://api.browser-use.com/api/v2`

OpenAPI spec: [/cloud/openapi/v2.json](https://docs.browser-use.com/cloud/openapi/v2.json) — legacy; new projects should use [v3](https://docs.browser-use.com/openapi.json).

---

Prefer the SDK? See the [Agent (v2) docs](/cloud/legacy/agent).
Expand Down
79 changes: 79 additions & 0 deletions docs/cloud/browser/captcha.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: CAPTCHA Solving
description: "Browser Use remote browsers solve CAPTCHAs automatically, on by default, on every plan."
icon: shield-check
---

Browser Use remote browsers have **automatic CAPTCHA solving** built in. There is nothing to configure — on the browser, the attached agent, or your automation library (Playwright, Puppeteer, Selenium). It is on by default on every plan, including the [free tier](/cloud/pricing).

The best defense is not tripping a challenge in the first place — that is what [stealth](/cloud/browser/stealth) handles (anti-fingerprinting and bot-detection bypass). This page covers what happens when a CAPTCHA or anti-bot system appears anyway: we solve it, and we lead the field on success rate.

## Success rate by vendor

Across the anti-bot and CAPTCHA systems agents hit most, Browser Use Cloud has the **highest overall success rate at 81%** — and the best against **Cloudflare (93%)** and **PerimeterX (81%)**.

| Protection | Browser Use Cloud |
| --- | --- |
| Overall | **81%** |
| Cloudflare | **93%** |
| PerimeterX | **81%** |
| Akamai | 85% |
| DataDome | 69% |
| reCAPTCHA | 80% |

<Frame caption="Success rate by vendor, Browser Use Cloud vs other cloud browser providers">
<img src="/cloud/images/captcha-success-by-vendor.png" style={{ borderRadius: '0.5rem' }} alt="Heatmap of success rate by vendor. Browser Use Cloud leads overall at 81%, with 93% on Cloudflare and 81% on PerimeterX, ahead of Anchor, Onkernel, Browserless, Steel, Browserbase, and Hyperbrowser." />
</Frame>

Full methodology in [We stealth benchmarked every major cloud browser provider](https://browser-use.com/posts/stealth-benchmark).

## Supported CAPTCHA types

These are the interactive CAPTCHA widgets solved automatically, distinct from the anti-bot systems above (Cloudflare, DataDome, PerimeterX, Akamai) that gate a site before a widget ever appears:

| CAPTCHA type | Solved automatically |
| --- | --- |
| reCAPTCHA v2 (checkbox / image challenge) | Yes |
| reCAPTCHA v3 (score-based) | Yes |
| hCaptcha | Yes |
| Cloudflare Turnstile | Yes |

All are handled on by default — no `captcha_type` parameter or per-widget configuration.

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Minor phrasing issue on the last line of the CAPTCHA table: "All are handled on by default" reads as a mashup of two phrasings ("handled by default" and "on by default"). Suggest picking one for cleaner prose.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/cloud/browser/captcha.mdx, line 41:

<comment>Minor phrasing issue on the last line of the CAPTCHA table: "All are handled on by default" reads as a mashup of two phrasings ("handled by default" and "on by default"). Suggest picking one for cleaner prose.</comment>

<file context>
@@ -27,6 +27,19 @@ Across the anti-bot and CAPTCHA systems agents hit most, Browser Use Cloud has t
+| hCaptcha | Yes |
+| Cloudflare Turnstile | Yes |
+
+All are handled on by default — no `captcha_type` parameter or per-widget configuration.
+
 ## Get started
</file context>
Suggested change
All are handled on by default — no `captcha_type` parameter or per-widget configuration.
All are handled by default — no `captcha_type` parameter or per-widget configuration.
Fix with cubic


## Get started

There is nothing to turn on. CAPTCHA solving comes with every session. Start one:

<CardGroup cols={2}>
<Card title="Create a browser session" icon="plus" href="/cloud/browser/create">
SDK, REST, or a single WebSocket URL.
</Card>
<Card title="Connect your framework" icon="code" href="/cloud/browser/playwright">
Playwright, Puppeteer, or Selenium over CDP.
</Card>
<Card title="Stealth" icon="user-secret" href="/cloud/browser/stealth">
What the hardened Chromium fork does.
</Card>
<Card title="Proxies" icon="globe" href="/cloud/browser/proxies">
Residential IPs in 195+ countries, on by default.
</Card>
</CardGroup>

## FAQ

**Does the open-source library solve CAPTCHAs?**

Without remote browsers, [open-source](https://github.com/browser-use/browser-use) agents have no stealth or CAPTCHA solving. Giving your agent stealth is easy: run it on a remote browser with a single parameter. See [Cloud browser + open source agent](/cloud/browser/open-source-agent).

**Can I use a third-party CAPTCHA solver?**

No, we do not support third-party CAPTCHA solver plugins on the browser. If your CAPTCHAs are not being solved properly, reach out and we will look into it.

**Do I need to enable anything for CAPTCHA solving?**

No. Remote browsers solve CAPTCHAs for you automatically.

## Further reading

- [Prove you are a robot: CAPTCHAs for agents](https://browser-use.com/posts/prove-you-are-a-robot)
- [Browser agent bot detection is about to change](https://browser-use.com/posts/bot-detection)
99 changes: 99 additions & 0 deletions docs/cloud/browser/create.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
title: Create a browser session
description: "Every way to start a cloud browser: SDK, REST, or a single WebSocket URL, with all parameters and the response schema."
icon: plus
---

Three ways to create a session. All of them return a browser with stealth, CAPTCHA solving, and a residential proxy already on.

## SDK

<CodeGroup>
```python Python
from browser_use_sdk.v3 import AsyncBrowserUse

client = AsyncBrowserUse()
browser = await client.browsers.create(proxy_country_code="us")
print(browser.cdp_url) # connect any CDP client here
print(browser.live_url) # watch the session in a browser tab
```
```typescript TypeScript
import { BrowserUse } from "browser-use-sdk/v3";

const client = new BrowserUse();
const browser = await client.browsers.create({ proxyCountryCode: "us" });
console.log(browser.cdpUrl);
console.log(browser.liveUrl);
```
</CodeGroup>

## REST

```bash
curl -X POST "https://api.browser-use.com/api/v3/browsers" \
-H "X-Browser-Use-API-Key: $BROWSER_USE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"proxyCountryCode": "us", "timeout": 60}'
```

## WebSocket URL (no SDK, no create call)

Connect directly and the session is created for you. Configuration goes in query parameters, and the session stops when the socket disconnects.

```text
wss://connect.browser-use.com?apiKey=YOUR_API_KEY&proxyCountryCode=us
```

## Parameters

All parameters are optional.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `profileId` | `string` (UUID) | — | Load a saved [profile](/cloud/guides/profile-sync) (cookies, localStorage) into the session. |
| `proxyCountryCode` | `string` | `us` | Residential proxy country. Set to `null` to disable the proxy. |
| `timeout` | `int` | `60` | Session lifetime in minutes, 1–240. The session stops automatically when it expires. |
| `browserScreenWidth` | `int` | — | Screen width in pixels, 320–6144. |
| `browserScreenHeight` | `int` | — | Screen height in pixels, 320–3456. |
| `allowResizing` | `bool` | `false` | Allow window resizing during the session. Not recommended: resizing reduces stealth. |
| `customProxy` | `object` | — | Bring your own proxy instead of ours. |

@cubic-dev-ai cubic-dev-ai Bot Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Parameter listed as standard optional param but Python SDK v3 has no typed custom_proxy argument — customProxy only works via **extra as camelCase, not the snake_case convention used by every other Python SDK parameter. Python users would naturally pass custom_proxy={...} (following the SDK's own pattern) and silently send the wrong body key. Either add custom_proxy as a typed param to the SDK, omit it from this table, or add a note clarifying that Python SDK users must pass customProxy={...} directly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/cloud/browser/create.mdx, line 59:

<comment>Parameter listed as standard optional param but Python SDK v3 has no typed `custom_proxy` argument — `customProxy` only works via `**extra` as camelCase, not the snake_case convention used by every other Python SDK parameter. Python users would naturally pass `custom_proxy={...}` (following the SDK's own pattern) and silently send the wrong body key. Either add `custom_proxy` as a typed param to the SDK, omit it from this table, or add a note clarifying that Python SDK users must pass `customProxy={...}` directly.</comment>

<file context>
@@ -0,0 +1,99 @@
+| `browserScreenWidth` | `int` | — | Screen width in pixels, 320–6144. |
+| `browserScreenHeight` | `int` | — | Screen height in pixels, 320–3456. |
+| `allowResizing` | `bool` | `false` | Allow window resizing during the session. Not recommended: resizing reduces stealth. |
+| `customProxy` | `object` | — | Bring your own proxy instead of ours. |
+| `enableRecording` | `bool` | `false` | Record the session. The video is available as `recordingUrl` after the session stops. |
+
</file context>
Fix with cubic

| `enableRecording` | `bool` | `false` | Record the session. The video is available as `recordingUrl` after the session stops. |

{/* TEAM REVIEW: the WSS connection path previously documented timeout default as 15 minutes; the v3 API spec says 60. Confirm which is correct per method and align the framework pages. */}

## Response

`201` with a browser session object:

```json
{
"id": "0d5f16f3-96cc-4d5f-a5a4-4a4d3b5f9d2e",
"status": "active",
"liveUrl": "https://live.browser-use.com?wss=...",
"cdpUrl": "https://0d5f16f3.cdp1.browser-use.com",
"timeoutAt": "2026-07-15T21:00:00Z",
"startedAt": "2026-07-15T20:00:00Z",
"finishedAt": null,
"proxyUsedMb": "0.0",
"proxyCost": "0.0",
"browserCost": "0.0",
"agentSessionId": null,
"recordingUrl": null
}
```

Field names are camelCase in REST and TypeScript (`cdpUrl`, `liveUrl`), snake_case in Python (`cdp_url`, `live_url`). `cdpUrl` and `liveUrl` are nullable, check them before connecting.

## Errors

| Status | Meaning |
|--------|---------|
| `403` | Session timeout limit exceeded for your plan. |
| `404` | The `profileId` doesn't exist. |
| `422` | Invalid parameter value. |
| `429` | Too many concurrent active sessions. Stop unused sessions or raise your limit. |

## Next

- Connect with [Playwright](/cloud/browser/playwright), [Puppeteer](/cloud/browser/puppeteer), or [Selenium](/cloud/browser/selenium)
- [Manage the session](/cloud/browser/sessions): lifecycle, stopping, billing
Loading