Docs / Session replay

Session replay

Create a session with record: true and BrowserView captures everything server-side — a video of the display plus structured streams of actions, console output, network requests, and errors. The replay is retrievable seconds after the session ends, long after the browser itself is gone.

Recording a session

Recording is opt-in per session. Pass record: true when creating; nothing else about the session changes — same viewer, same CDP endpoint, same lifecycle.

create a recorded session
curl -X POST https://sessions.browserview.io/sessions \  -H "authorization: Bearer $BROWSERVIEW_API_KEY" \  -H "content-type: application/json" \  -d '{"start_url": "https://example.com", "record": true}'

Capture happens outside the browser, so it works no matter who drives the session: a human in the live viewer, Playwright over CDP, or an agent. Recording adds no client-side scripts to the pages under test.

  • Video — the X display encoded to WebM (VP8, 12 fps by default), including everything a user would have seen: dialogs, popups, downloads bars, cross-origin iframes.
  • Actions — human input from the live viewer (mouse, keyboard, scroll) and automation commands sent over CDP (Input.*, Page.navigate, Runtime.evaluate), plus page navigations.
  • Consoleconsole.* calls and browser log entries from every tab.
  • Network — one entry per request with method, URL, status, timing, and size. Sensitive headers (Authorization, Cookie, …) are redacted at capture time; bodies are never recorded.
  • Errors — uncaught exceptions with stacks, and failed requests.

Fetching a replay

GET /sessions/{id}/replay returns {"status": "recording"} while the session is alive, 404 while the recording finalizes (typically under 30 seconds — poll every few seconds), and the full manifest once ready:

replay manifest
# Poll after the session ends (ready ~15-30s later)curl https://sessions.browserview.io/sessions/$SESSION_ID/replay \  -H "authorization: Bearer $BROWSERVIEW_API_KEY" {  "status": "ready",  "session_id": "1f0d33f9a1f2",  "started_at_ms": 1754038800000,  "ended_at_ms": 1754038923000,  "video": {    "url": "https://…",          # seekable WebM (VP8), ~1h presigned    "start_time_ms": 1754038800450,    "duration_ms": 122550,    "size_bytes": 15728640  },  "page_count": 2,  "pages": [    { "page_id": "p_000", "url": "https://example.com",      "start_time_ms": 1754038801000, "end_time_ms": 1754038860000 }  ],  "events": {    "actions":  { "url": "https://…", "count": 214, "size_bytes": 9182 },    "console":  { "url": "https://…", "count": 12,  "size_bytes": 2210 },    "network":  { "url": "https://…", "count": 96,  "size_bytes": 18876 },    "errors":   { "url": "https://…", "count": 1,   "size_bytes": 402 }  },  "urls_expire_at_ms": 1754042523000}

Artifact URLs are presigned and expire (see urls_expire_at_ms); re-fetch the manifest for fresh ones. The video is a single seekable WebM — a plain <video> element plays it, range requests make scrubbing cheap, and playbackRate gives you 2×/4× review.

Aligning events with video

timeline math
// Every event line carries an absolute epoch-ms "ts".// One formula aligns everything with the video:videoTimeSeconds = (event.ts - manifest.video.start_time_ms) / 1000
event stream format (JSONL)
# Event files are newline-delimited JSON (served gzip-encoded;# browsers and HTTP clients decompress transparently).{"ts":1754038801200,"src":"cdp","type":"page.navigated","url":"https://example.com"}{"ts":1754038802414,"src":"input","type":"input.btn","b":1,"d":true}{"ts":1754038802731,"src":"cdp","type":"network","method":"GET","url":"https://example.com/api","status":200,"durationMs":102,"encodedBytes":5120}{"ts":1754038803090,"src":"cdp","type":"console","level":"error","text":"Uncaught TypeError: x is not a function"}

The pages array is the main-frame navigation timeline across all tabs — useful for chaptering a replay or jumping to when a specific page was on screen.

Availability & retention

PropertyValue
Replay ready after session end~15–30 seconds
Manifest URL lifetime1 hour per fetch (re-fetch to renew)
Replay retention30 days, then artifacts expire
Crash behaviorsessions that die abruptly (OOM, crash) still produce a replay up to the moment of death

Replays also appear in the console: any recorded session gets a Replay entry under History with the full player — video, scrubber with per-page segments and error markers, and synchronized Actions / Console / Network / Errors panes.