API reference
The full REST surface at https://sessions.browserview.io. Lifecycle endpoints take your API key; per-session traffic takes a scoped session token.
Authentication
Send your API key on every lifecycle request, either as a bearer token or an x-api-key header:
Authorization: Bearer bv_live_...# orx-api-key: bv_live_...Keys are minted in the console and can be revoked there at any time; revocation takes effect within about a minute. Your key sees only your own sessions.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /sessions | Create a session |
GET | /sessions | List your sessions |
GET | /sessions/{id} | Inspect one session (returns fresh URLs and tokens) |
DELETE | /sessions/{id} | Destroy a session |
POST | /sessions/{id}/tokens | Mint an extra scoped token |
GET | /sessions/{id}/replay | Replay manifest for a recorded session (works after destruction) |
Create a session
{ "start_url": "https://example.com", // default "about:blank" "width": 1280, // 320–3840, default 1280 "height": 800, // 240–2160, default 800 "wait": true, // block until the browser is ready "record": true // capture a session replay (default false)}Returns 201 with the session object. The viewer_url, watch_url, and cdp_url fields are paths relative to the API host. With "wait": true (the default) the call returns once the browser answers on DevTools — typically about five seconds.
The session object
{ "id": "3f9c62d81b4a", "status": "running", // container state "health": "healthy", // healthy | starting | unhealthy "start_url": "https://example.com", "width": 1280, "height": 800, "created_at": "2026-07-29T17:04:05Z", "record": false, // whether a replay is being captured "mem_limit_bytes": 2147483648, "viewer_url": "/sessions/3f9c62d81b4a/viewer?token=...", // control scope "watch_url": "/sessions/3f9c62d81b4a/viewer?token=...", // view scope "cdp_url": "/sessions/3f9c62d81b4a/cdp", "cdp_token": "...", "token_ttl_seconds": 3600}GET /sessions (the list endpoint) returns a bare JSON array and omits the URL and token fields; fetch a single session to get fresh ones. GET /sessions/{id} additionally reports browser health: restarts (times the in-session browser restarted, or null when the status probe is unreachable) and degraded (true once it has restarted). DELETE /sessions/{id} returns 204 with no body.
Mint a token
{ "scope": "view", // view | control | cdp "ttl_seconds": 900 // up to 7 days} // 200 → { "token": "...", "scope": "view", "ttl_seconds": 900 }Fetch a replay
// while the session runs → 200 { "status": "recording", ... }// just ended, still finalizing → 404 — not an error; retry for a few seconds// once finalized (typically <30s) → 200 with the full manifest:{ "status": "ready", "video": { "url": "...", "start_time_ms": ..., "duration_ms": ... }, "pages": [ { "page_id": "p_000", "url": "...", "start_time_ms": ..., "end_time_ms": ... } ], "events": { "actions": {...}, "console": {...}, "network": {...}, "errors": {...} }, "urls_expire_at_ms": ...}Only sessions created with record: true have replays. The SDKs' waitForReplay / wait_for_replay helpers poll through the recording and finalizing states for you. See the session replay guide for stream formats and timeline math.
Token scopes
| Scope | Grants |
|---|---|
view | Watch the live stream. Input is stripped server-side — spectators physically cannot click or type. |
control | Watch plus full mouse and keyboard. |
cdp | Chrome DevTools Protocol access for Playwright, Puppeteer, or raw CDP clients. |
Tokens are signed, scoped to one session, and expire (one hour by default). Pass them as ?token= or the x-session-token header.
Connecting over CDP
The API rewrites Chromium's discovery JSON so webSocketDebuggerUrl points back through the proxy with your token attached — Playwright and Puppeteer work with no special configuration beyond the header:
// Playwrightconst browser = await chromium.connectOverCDP(cdpUrl, { headers: { "x-session-token": cdpToken },}); // Puppeteerconst browser = await puppeteer.connect({ browserURL: cdpUrl + "?token=" + cdpToken,});Errors and rate limits
Errors are JSON: {"detail": "..."}.
| Status | Meaning |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | Valid token, wrong scope — or a plan limit: included browser-hours exhausted on the free tier, plan concurrency reached, or a failed payment. Upgrade or manage billing in the console. |
| 404 | Session not found (or not yours). |
| 429 | Rate limit or capacity: concurrent-session limit reached, or the fleet is momentarily full. Honor the Retry-After header. |
| 503 | Authentication service briefly unavailable — retry. |
Liveness is exposed at GET https://sessions.browserview.io/healthz.