← Back to skills

Domain skill

browser-use-cloud

Markdown synced from browser-harness domain skills.

Host
browser-use-cloud
Files
1

Agent prompt

Use this skill

Copy this prompt into your coding agent to make it enable browser-harness domain skills and read this exact domain folder before automating.

Set up https://github.com/browser-use/browser-harness for me if it is not already installed. If setup is needed, read `install.md` first to install and connect it to my real browser. Then read `SKILL.md` for normal usage and always read `helpers.py` because that is where the browser-harness functions are.

Enable domain skills if they are not already enabled by setting `BH_DOMAIN_SKILLS=1` for browser-harness. Use the `browser-use-cloud` domain skill from `agent-workspace/domain-skills/browser-use-cloud/`. Read every markdown file for this domain before inventing an approach:
- agent-workspace/domain-skills/browser-use-cloud/cloud.md

Use those domain-skill notes to complete my task for `browser-use-cloud` in my real browser. When you open a setup, verification, or task tab, activate it so I can see the active browser tab.

Skill contents

What the agent will read

Programmatic Automation

cloud.md

Source
  • https://api.browser-use.com/api/v3 (REST). All five endpoints below were exercised end-to-end on 2026-05-05 with a real BROWSERUSEAPIKEY; the companion script cleanup-zombies.py next to this file is the field-test —...
  • This skill is for users who already start cloud browsers via startremotedaemon() and want to manage the surrounding lifecycle — provisioning fleets, cleaning up zombies, listing what's running, sharing liveUrls —...
  • REST uses a custom header (not Authorization: Bearer — that path returns a generic 401 silently):
  • The key only authorises actions on browsers and profiles created under it — there are no organisation-level admin endpoints on the public API.
Show full markdown

https://api.browser-use.com/api/v3 (REST). All five endpoints below were exercised end-to-end on 2026-05-05 with a real BROWSER_USE_API_KEY; the companion script cleanup-zombies.py next to this file is the field-test — running it lists active browsers and stops zombies via the same wire calls the harness uses internally.

This skill is for users who already start cloud browsers via start_remote_daemon() and want to manage the surrounding lifecycle — provisioning fleets, cleaning up zombies, listing what's running, sharing liveUrls — without clicking through cloud.browser-use.com.

Auth

REST uses a custom header (not Authorization: Bearer — that path returns a generic 401 silently):

python
import os
HEADERS = {
    "X-Browser-Use-API-Key": os.environ["BROWSER_USE_API_KEY"],
    "Content-Type": "application/json",
}

The key only authorises actions on browsers and profiles created under it — there are no organisation-level admin endpoints on the public API.

Endpoint reference

All paths are under https://api.browser-use.com/api/v3. Verified status codes and shapes from 2026-05-05 below.

POST /browsers — provision a cloud browser

Body (camelCase):

KeyTypeNotes
profileIdUUIDoptional; logged-in cloud profile
profileNamestroptional; resolved client-side
proxyCountryCodeISO2default "us"; pass null to disable BU proxy
timeoutintminutes, 1..240
customProxyobj{host, port, username, password, ignoreCertErrors}
browserScreenWidth / browserScreenHeightintviewport
allowResizingboolviewport user-resizable
enableRecordingboolsession recording

Returns 201 with this shape (also returned by GET /browsers/{id}, GET /browsers items, and PATCH /browsers/{id}):

python
{
    "id": str,
    "status": str,                  # e.g. "active"
    "liveUrl": str,                 # host: live.browser-use.com (different from cloud.browser-use.com)
    "cdpUrl": str,                  # https:// — daemon converts to ws via /json/version
    "timeoutAt": str,               # ISO 8601 UTC
    "startedAt": str,
    "finishedAt": None,             # populated only after stop
    "proxyUsedMb": str,             # STRING — cast to float before arithmetic
    "proxyCost": str,               # STRING
    "browserCost": str,             # STRING
    "agentSessionId": None,
    "recordingUrl": None,           # str only when enableRecording=True at create
}

The liveUrl carries the cdp WebSocket as a ?wss=... query param, so sharing the URL alone hands off a viewable session — no extra setup.

PATCH /browsers/{id} — stop (end billing)

Body {"action": "stop"}. Returns 200 with the same browser object, but liveUrl and cdpUrl come back as null and finishedAt is populated. Use the returned proxyCost + browserCost for final cost. Always wrap caller code in try/finally; every billed minute counts.

GET /browsers — list active sessions

Returns 200 and the standard envelope {items: [...], totalItems, pageNumber, pageSize}. items[*] matches the POST /browsers response shape. Already-finished browsers appear in the listing for a window with finishedAt populated — filter them out when computing age.

GET /profiles?pageSize=N&pageNumber=N — list cloud profiles

pageSize caps at 100. Same envelope as /browsers.

GET /profiles/{id} — profile detail

Returns the same shape as the listing items:

python
{
    "id": str,
    "userId": None,                 # null in observed responses
    "name": str,
    "lastUsedAt": str | None,       # null until first use
    "createdAt": str,
    "updatedAt": str,
    "cookieDomains": list[str] | None,  # null on freshly-created profiles
}

browser_harness.admin.list_cloud_profiles() already wraps the listing

  • per-id GET; prefer it unless you need raw access.

Companion script: cleanup-zombies.py

A self-contained operator script next to this file. Run it with:

bash
BROWSER_USE_API_KEY=... python agent-workspace/domain-skills/browser-use-cloud/cleanup-zombies.py
# stops every active browser older than 30 minutes (default)

BROWSER_USE_API_KEY=... python .../cleanup-zombies.py --older-than 5 --dry-run
# preview only; no PATCH /stop sent

The script is the practical residue of the API verification — running it exercises four of the five endpoints (GET /browsers, plus PATCH .../stop per zombie). Use it as the live regression check whenever this skill is updated.

Dashboard navigation (when API isn't enough)

The dashboard at cloud.browser-use.com requires a logged-in session; the unauthenticated root redirects to /signup (verified 2026-05-05). Beyond /signup the slugs below are inferred from typical SaaS layout — confirm in your own browser before relying on the literal paths:

code
/signup                 (verified)
/dashboard              [verify]
/browsers               [verify] — likely the dashboard mirror of GET /browsers
/browsers/<id>          [verify]
/profiles               [verify]
/api-keys               [verify]

There is no /usage page mirror — GET /usage on the API returns 404, so per-session cost has to come from each browser record (proxyCost + browserCost). The dashboard surfaces aggregate billing somewhere, but that's outside the API surface and not useful from inside bh.

For dashboard scraping, attach to your real Chrome and read cookies:

python
cookies = cdp("Network.getCookies", urls=["https://cloud.browser-use.com"])
parts = [c["name"] + "=" + c["value"] for c in cookies.get("cookies", [])]
dash_headers = {"Cookie": "; ".join(parts), "Accept": "text/html,application/json"}

Empty cookie jar = not logged in; open cloud.browser-use.com in your real Chrome once, then retry.

Traps to avoid

  • Auth header name is X-Browser-Use-API-Key. Authorization: Bearer ... silently fails with a generic 401.
  • Cost fields are strings, not numbers. proxyCost, browserCost, proxyUsedMb come back as quoted strings ("0.0123"); cast to float before arithmetic.
  • cookieDomains can be None on freshly-created profiles, despite what admin.py:list_cloud_profiles's docstring says. Guard with c or [].
  • liveUrl host is live.browser-use.com, not cloud.browser-use.com. They're separate surfaces.
  • start_remote_daemon overwrites BU_CDP_WS in the daemon env; re-read from browser["cdpUrl"] if you need the value afterwards. (PR #300 stops run.py from clobbering an explicit BU_CDP_URL, but the daemon env still gets set.)
  • liveUrl is single-session — after stop, the URL no longer resolves; don't cache across calls.
  • _browser_use has a 60s timeout in admin.py; long-running ops (large profile sync) need their own polling.
  • profile-use CLI is a separate install: curl -fsSL https://browser-use.com/profile.sh | sh.
  • pageSize caps at 100 silently — paginate via pageNumber. totalItems in the envelope lets you size loops up front.
  • proxyCountryCode defaults to "us" when omitted; pass None to disable BU proxy entirely. Wrong country = wrong egress IP = breaks geo-locked auth.

What this skill does NOT cover

  • Billing / payment methods — dashboard only, intentionally sensitive.
  • Organisation / team admin — outside the per-API-key surface.
  • SDK features — Browser Use ships official SDKs separately; this skill is the raw-HTTP path for power users inside bh.
  • Cross-API-key reads — every endpoint is scoped to the calling key.

Provenance

Live-tested 2026-05-05 against https://api.browser-use.com/api/v3:

EndpointMethodStatusNotes
/profiles?pageSize=100&pageNumber=1GET200shape verified
/profiles/{id}GET200cookieDomains=None observed on a fresh profile
/browsersPOST201liveUrl host is live.browser-use.com
/browsers/{id} ({action:"stop"})PATCH200returns final cost
/browsersGET200paginated {items,totalItems,pageNumber,pageSize}
/usageGET404no public endpoint
/GET404no root metadata

Companion script cleanup-zombies.py re-runs the listing + stop subset end-to-end and is the regression artefact for this skill. A full E2E loop (spawn → list → stop → re-list) was executed on 2026-05-05 against the production API and printed:

code
[STOP] 3ac4c964-...-d3d3e1ad7508  age=  0.0min  cost=$0.0020
summary: 1 active session(s), stopped 1

Re-running the script in --dry-run mode against an empty pool is the cheapest smoke test (no PATCH /stop calls, ~$0).