Browser (CDP)
When an agent needs full page automation, hand the sandbox's Chromium to Playwright or Puppeteer. The daemon supplies the CDP endpoint, and the client connects to and drives the same browser instance.
Routes:
For automation without a framework — navigate, snapshot, fill, click, screenshot over REST — see Browser Use.
Requirements
The capabilities object from GET /v2/sandbox should include browser.
GET /v1/capabilities should report browser.
A Chromium started with --remote-debugging-port=9222 must be reachable from the daemon. The daemon connects to it as a CDP client; it does not launch or proxy it.
Get the CDP URL
cdp_url is Chromium's WebSocket endpoint rewritten to the public origin:
BASE_URL = "http://127.0.0.1:18091"
sb = Aio(BASE_URL)
cdp_url = sb.get("/v2/browser/info")["cdp_url"]
print(cdp_url)
# -> ws://127.0.0.1:18091/cdp/devtools/browser/9ca46b6e-ab32-46b1-8e7e-7af3d540de4b
BASE_URL = "http://127.0.0.1:18091"
sb = Aio(BASE_URL)
# The 1.x Python SDK's browser.get_info rejects this body; see the migration
# guide. The route itself answers, so the helper reads it.
cdp_url = sb.get("/v1/browser/info")["cdp_url"]
print(cdp_url)
# -> ws://127.0.0.1:18091/cdp/devtools/browser/9ca46b6e-ab32-46b1-8e7e-7af3d540de4b
The path lives under /cdp/, which the deployment serves, not the daemon. See CDP Access. Which SDK calls fail against the daemon is listed in 1.x SDK compatibility.
Connect with Playwright
Pass cdp_url to connect_over_cdp:
import httpx
from playwright.sync_api import sync_playwright
BASE_URL = "http://127.0.0.1:18091"
cdp_url = httpx.get(f"{BASE_URL}/v1/browser/info").json()["data"]["cdp_url"]
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(cdp_url)
page = browser.contexts[0].pages[0]
page.goto("https://example.com")
print(page.title())
# → Example Domain
Playwright keeps the /cdp/ prefix and any query string, so cdp_url works unmodified. Take the existing context and page rather than launching one: the browser belongs to the sandbox and is shared with the daemon's own REST tools.
Connect with Puppeteer
Use browserWSEndpoint. Puppeteer's browserURL drops the path prefix:
import puppeteer from "puppeteer-core";
const BASE_URL = "http://127.0.0.1:18091";
const info = await fetch(`${BASE_URL}/v1/browser/info`).then((r) => r.json());
const browser = await puppeteer.connect({ browserWSEndpoint: info.data.cdp_url });
const [page] = await browser.pages();
await page.goto("https://example.com");
console.log(await page.title());
// → Example Domain