Skip to main content

Using Browser Use Sandbox

Best practices for web automation agents: create a template from the browser image and connect Puppeteer, Playwright, or BrowserUse over CDP to perform page visits, interactions, screenshots, and result archiving.

Browser Use Sandbox is designed for agents that need to visit web pages, click buttons, fill in forms, archive screenshots, or scrape dynamic pages. Create a template based on the browser image (browser): port 3000 provides the browser service, reachable over CDP from Puppeteer, Playwright, or BrowserUse. If the task only involves page visits, clicks, screenshots, file downloads, and lightweight result extraction, Browser Use Sandbox is sufficient. When browser artifacts must be handed over to Python/Node.js in the same session for data cleaning, tabular analysis, or report generation, prefer the AIO Sandbox.
Treat the sandbox's public URL as an access credential: without application-layer authentication, anyone holding the URL has full control over the browser inside the sandbox, including logged-in state and cookies. Do not share it publicly, and do not write it into logs or frontend code.

Use Cases

ScenarioDescription
Web data collectionVisit dynamic pages and extract titles, body text, tables, links, or business fields
Back-office automationLog in to admin consoles, fill forms, click buttons, download reports, or archive screenshots
Page monitoringOpen pages on a schedule to verify key elements, take screenshots, or check performance and availability
Lightweight E2E testingRun end-to-end tests in an isolated browser, keeping CI workers clean
Browser-tool agentsLet an agent complete multi-step web tasks through frameworks such as BrowserUse
  1. Create a template based on the browser image (browser) and obtain its templateCode—see Template Management.
  2. Create a sandbox from the template with a reasonable timeout.
  3. Get the public host of the browser service via sandbox.getHost(3000).
  4. Poll /health until the browser service is ready.
  5. Connect Puppeteer, Playwright, or BrowserUse via wss://<sandbox-host>/ws/automation.
  6. Perform page visits, clicks, input, screenshots, PDF generation, or downloads.
  7. Save structured results, screenshots, HTML, PDFs, or downloaded files to a task directory inside the sandbox.
  8. Read the results on the business side, then destroy the sandbox.

Prepare the Local Environment

The following example uses Node.js with Puppeteer Core. The business side does not need a full browser: Chromium/Chrome already runs inside the sandbox.
{
  "name": "browser-use-sandbox-demo",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {
    "e2b": "2.31.0",
    "puppeteer-core": "^24.0.0"
  }
}
e2b is pinned to 2.31.0, the version verified in these examples. Newer SDK versions return 405 when creating a sandbox.
The BrowserUse Python example below additionally requires:
pip install "browser-use==0.13.10" "e2b==2.31.0"
In the BrowserUse example, the model call uses the Bailian OpenAI-compatible endpoint: api_key is a Bailian API Key (required), and model is optional, defaulting to qwen3-vl-plus.

Puppeteer Example

The example flow:
  1. Create a sandbox.
  2. Wait until the browser service /health returns 200.
  3. Connect to the cloud browser over CDP.
  4. Open https://example.com, extract page information, and save a screenshot.
import { writeFile } from "node:fs/promises";
import puppeteer from "puppeteer-core";
import { Sandbox } from "e2b";

const ALIYUN_UID = "your aliyunUid";
const BAILIAN_API_KEY = "sk-...";
const BASE_URL = "https://{workspace_id}.cn-beijing.maas.aliyuncs.com/api/v1/agentstudio/sandbox";
const TEMPLATE = "your template code";

const BROWSER_PORT = 3000;
const TARGET_URL = "https://example.com";
const TASK_DIR = "/tmp/browser-task";
const SCREENSHOT_PATH = `${TASK_DIR}/browser-example.png`;

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

function toArrayBuffer(bytes) {
  return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
}

async function waitUntilHealthy(sandbox, host, timeoutMs = 60_000) {
  const deadline = Date.now() + timeoutMs;

  while (Date.now() < deadline) {
    let result;
    try {
      result = await sandbox.commands.run(
        `curl -sS -o /dev/null -w '%{http_code}' -m 4 ` +
          `https://${host}/health`,
        { timeoutMs: 10_000 },
      );
    } catch (error) {
      result = error;
    }

    const code = (result.stdout || "").trim();
    if (code === "200") {
      return;
    }
    await sleep(2_000);
  }

  throw new Error(`browser service not ready within ${timeoutMs}ms`);
}

let sandbox;

try {
  sandbox = await Sandbox.create(TEMPLATE, {
    apiUrl: BASE_URL,
    apiKey: `e2b_${ALIYUN_UID}`,
    apiHeaders: { Authorization: `Bearer ${BAILIAN_API_KEY}` },
    timeoutMs: 300_000,
    secure: true,
  });

  const host = sandbox.getHost(BROWSER_PORT);

  await sandbox.files.makeDir(TASK_DIR);
  await waitUntilHealthy(sandbox, host);

  const browser = await puppeteer.connect({
    browserWSEndpoint: `wss://${host}/ws/automation`,
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 1365, height: 768 });
  await page.goto(TARGET_URL, {
    waitUntil: "networkidle2",
    timeout: 60_000,
  });

  const screenshot = await page.screenshot({ fullPage: true });
  await sandbox.files.write(SCREENSHOT_PATH, toArrayBuffer(screenshot));
  await writeFile("browser-example.png", screenshot);

  const result = await page.evaluate(() => ({
    url: location.href,
    title: document.title,
    text: document.body.innerText.replace(/\s+/g, " ").slice(0, 500),
  }));

  await browser.close();
  console.log(result);
} finally {
  if (sandbox) {
    await sandbox.kill();
  }
}

BrowserUse Integration

For agents that drive web operations in natural language, point BrowserUse at the CDP endpoint exposed by the sandbox. The business service creates and destroys the sandbox; BrowserUse only connects to the browser session inside it.
import asyncio

from browser_use import Agent, BrowserSession, ChatOpenAI
from browser_use.browser import BrowserProfile
from e2b import Sandbox

BROWSER_PORT = 3000
BAILIAN_API_KEY = "sk-..."

async def main():
    browser_session = None
    sandbox = Sandbox.create(
        api_url="https://{workspace_id}.cn-beijing.maas.aliyuncs.com/api/v1/agentstudio/sandbox",
        api_key="e2b_your aliyunUid",
        headers={"Authorization": f"Bearer {BAILIAN_API_KEY}"},
        template="your template code",
        timeout=600,
        secure=True,
    )

    try:
        host = sandbox.get_host(BROWSER_PORT)
        cdp_url = f"wss://{host}/ws/automation"

        browser_session = BrowserSession(
            cdp_url=cdp_url,
            browser_profile=BrowserProfile(
                headless=False,
                keep_alive=True,
            ),
        )

        agent = Agent(
            task="Visit https://example.com and extract the page title, then summarize the above-the-fold content",
            llm=ChatOpenAI(
                model="qwen3-vl-plus",
                api_key=BAILIAN_API_KEY,
                base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
            ),
            browser_session=browser_session,
            use_vision=True,
        )
        result = await agent.run(max_steps=20)
        print(result)
    finally:
        if browser_session is not None:
            await browser_session.stop()
        sandbox.kill()

if __name__ == "__main__":
    asyncio.run(main())
This integration fits searching, comparing, filling forms, clicking confirmations, and producing screenshot evidence. When stable artifacts matter, have the agent write key results as JSON and keep screenshots or HTML fragments for manual review and troubleshooting.

Production Advice

  • Restrict each browser task to an explicit URL scope and add a domain allowlist when necessary.
  • Limit downloaded file types, per-file size, total output size, and task lifetime.
  • Cap the agent's maximum steps with max_steps to keep it from repeating the same actions.
  • Page content may contain prompt injection. Do not let an agent execute instructions from a page without validation.
  • Isolate login state, cookies, account credentials, and business tokens per task and inject them at runtime; never bake them into the template.
  • Record URLs, screenshots, key DOM summaries, tool-call traces, and result file paths.
  • For manual observation or debugging, use the noVNC page built into the image: https://<sandbox-host>/static/vnc.html?path=/ws/livestream&autoconnect=true. The path parameter is mandatory and must start with /—a relative ws/livestream resolves to /static/ws/livestream and fails; the root path /vnc.html returns 404. WebSocket clients can connect directly to wss://<sandbox-host>/ws/livestream (equivalent alias /ws/liveview).
  • When a task must continue with Python/Node.js data processing after browser operations, use the AIO Sandbox.

Next Steps

Agent Context
Agent Governance & Evolution
Store
Application Marketplace