Quickstart

browserfarm speaks the Browserbase dialect. Keep your SDK, keep your code — point it at us by setting one field.

1. Your key

Go to API keys and create one. The secret starts with bf_live_ and is shown exactly once — we only store its hash.

2. Point the SDK at browserfarm

Base URL: http://localhost:4000

pnpm add @browserbasehq/sdk playwright-core
import Browserbase from "@browserbasehq/sdk";
import { chromium } from "playwright-core";

const bb = new Browserbase({
  apiKey: process.env.BROWSERFARM_API_KEY, // bf_live_…  (from /keys),
  baseURL: "http://localhost:4000",   // <- the only line you change
});

const session = await bb.sessions.create({
  projectId: process.env.BROWSERFARM_PROJECT_ID ?? "default",
});

// session.connectUrl is an opaque browserfarm handle. Clients never see
// topology — the same URL shape works whether the browser is a context, a
// process, or its own microVM.
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = (browser.contexts()[0] ?? (await browser.newContext())).pages()[0]
  ?? await browser.newPage();

await page.goto("https://example.com");
console.log(await page.title());

await browser.close();
// Release the slot now rather than waiting for the idle reaper.
await bb.sessions.update(session.id, {
  projectId: process.env.BROWSERFARM_PROJECT_ID ?? "default",
  status: "REQUEST_RELEASE",
});

3. Or hit the REST API directly

curl -X POST http://localhost:4000/v1/sessions \
  -H "X-BB-API-Key: $BROWSERFARM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"default"}'

Limits

One limit is enforced: concurrent browsers per account (see Usage). Past the cap, session creation returns HTTP 429 with a Retry-After header. Sessions are ephemeral — nothing persists between them, so log in inside each session.