Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.browserbase.com/llms.txt

Use this file to discover all available pages before exploring further.

The Session Replay API streams session replays as HLS for embedded playback. Each tab’s recording gets its own playlist; play them back with hls.js or any HLS-capable player. The same recordings power the Dashboard’s Session Inspector.
Embed session playback in your own application, dashboard, ticketing tool, or QA workflow. Browserbase records every session by default.

Quickstart

Given a sessionId from Create a Session, fetch a replay in two calls: list the pages, then fetch the playlist for any page.
const sessionId = "<your session ID>";
const apiKey = process.env.BROWSERBASE_API_KEY!;
const headers = { "x-bb-api-key": apiKey };

const meta = await fetch(
  `https://api.browserbase.com/v1/sessions/${sessionId}/replays`,
  { headers },
).then((r) => r.json());

const firstPage = meta.pages[0];

const m3u8 = await fetch(
  `https://api.browserbase.com/v1/sessions/${sessionId}/replays/${firstPage.pageId}`,
  { headers },
).then((r) => r.text());

// The body is an HLS playlist. Each "https://..." line is a
// signed CDN segment URL valid for 6 hours; hand the whole body
// to any HLS player.
const firstSegmentUrl = m3u8
  .split("\n")
  .find((line) => line.startsWith("https://"));
console.log(firstSegmentUrl);
The metadata response lists each tab’s recording. The playlist response is an HLS .m3u8 document: a plain-text manifest that points at a sequence of fragmented-MP4 (.m4s) segments served from the Browserbase CDN. Any HLS player fetches the manifest and streams the segments in order. For background on the format, see the HTTP Live Streaming overview on Wikipedia or the spec in RFC 8216.

Embedding a player

Any HLS-capable player works. Pick whichever fits your stack; the playlist URL is the same in all cases.
In each snippet below, the src / loadSource URL points at a route on your own backend — not at api.browserbase.com directly. Calling the Session Replay API from the browser would expose your BROWSERBASE_API_KEY to every viewer. See Recommended integration pattern below for the proxy shape.
hls.js is the most common choice for cross-browser HLS playback, and the recommended path for Firefox desktop, which has no native HLS support.
<video id="replay" controls muted autoplay playsinline></video>

<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<script>
  const video = document.getElementById("replay");
  const hls = new Hls();
  // Route on your own backend that proxies the Session Replay API.
  // See "Recommended integration pattern" below.
  hls.loadSource("/replays/<sessionId>/<pageId>");
  hls.attachMedia(video);
</script>
Browsers only autoplay when the video is muted; the muted attribute is required even for short replays. Drop autoplay and muted if you want a click-to-play UX. The playlist body references signed segment URLs on the Browserbase CDN. The browser fetches those segments directly, so your backend does not need to proxy them.

Multitab

Each recorded tab appears as its own page in the metadata response, with its own playlist URL.
{
  "pages": [
    {
      "pageId": "0",
      "url": "/v1/sessions/0a4c2f10-d7c0-4af8-9efb-a8d5c9f1b2e6/replays/0",
      "startTimeMs": 0,
      "endTimeMs": 121382
    },
    {
      "pageId": "1",
      "url": "/v1/sessions/0a4c2f10-d7c0-4af8-9efb-a8d5c9f1b2e6/replays/1",
      "startTimeMs": 13001,
      "endTimeMs": 121382
    }
  ],
  "pageCount": 2
}
Field semantics:
  • url is a relative path against https://api.browserbase.com.
  • startTimeMs and endTimeMs are milliseconds from session start, not Unix epoch.
  • The API returns pages ordered by pageId ascending.
Browserbase records up to 10 tabs open concurrently per session. Tabs you open while 10 are already recording will not appear in the replay.
1

Backend fetches the playlist

Your backend calls GET /v1/sessions/{id}/replays/{pageId} with x-bb-api-key and forwards the .m3u8 body to your frontend unchanged.
import express from "express";

const app = express();

app.get("/replays/:sessionId/:pageId", async (req, res) => {
  const { sessionId, pageId } = req.params;
  const upstream = await fetch(
    `https://api.browserbase.com/v1/sessions/${sessionId}/replays/${pageId}`,
    { headers: { "x-bb-api-key": process.env.BROWSERBASE_API_KEY! } },
  );
  if (!upstream.ok) {
    res.status(upstream.status).send(await upstream.text());
    return;
  }
  res
    .type("application/vnd.apple.mpegurl")
    .send(await upstream.text());
});
Your frontend then points its HLS player at /replays/<sessionId>/<pageId> on your own origin.
2

Frontend loads the playlist

Point your HLS player at the route on your backend that returns the playlist. The player parses the manifest and starts requesting segments.
3

Browser streams segments from the CDN

Segment URLs in the playlist are pre-signed CDN links. The browser fetches them directly; no proxying through your servers.
This avoids double-egress through your servers while keeping the API key off the browser.
Alternative: skip the proxy. If your backend renders the playback page server-side, you can fetch the playlist there, embed the .m3u8 body in the page (or hand it to the player as a Blob URL), and skip the proxy route entirely. Segment URLs in the body are signed and work directly from the browser regardless of how the body got there.

Segment URL expiration

Browserbase signs each playlist’s segment URLs, and they expire six hours after the API issues the playlist. Most playback sessions finish well before that. To resume playback beyond the expiry window, re-request the playlist; the API mints fresh segment URLs on every call.

Rate limits

Browserbase rate limits the playlist endpoint (GET /v1/sessions/{id}/replays/{pageId}) to 120 requests per minute per project (sustained 2 RPS). Bursts above 2 RPS still succeed as long as your project stays under 120 requests per minute. Going over returns a 429 status code with standard rate-limit response headers; see Concurrency & Rate Limits for the retry pattern.

Disabling recordings

The Session Replay API serves the same recordings the Dashboard plays. To skip recording for a session entirely, set recordSession to false when you create it; see Session Recording.
Sessions you create with recordSession: false produce no replay. Both endpoints return 404 Not Found with {"message": "Replay not found"}. Live View remains available for real-time debugging.

Troubleshooting

Player loads the playlist but no video plays:
  • Some HLS players don’t auto-play after loadedmetadata. Call video.play() manually.
  • Most browsers block autoplay unless the video is muted; set muted on the <video> element if you want playback to start without a click.
Segment requests start failing after several hours of playback:
  • Browserbase signs segment URLs, and they expire six hours after the API issues the playlist. Re-fetch the playlist to get fresh segment URLs.
Chromium plays via native HLS instead of your JavaScript player:
  • Chromium browsers (Chrome, Edge) ship native HLS, which can fall through your canPlayType checks. Prefer your library’s support detection (e.g. Hls.isSupported()) before the native fallback so segments go through the library’s CORS-aware fetch path.
Questions? Email support@browserbase.com