Browsa
  1. Guides
  2. Stagehand

Run Stagehand on Browsa.

Run Browserbase's open-source Stagehand SDK on a Browsa cloud browser. Stagehand attaches over CDP and keeps its act() and extract() calls; the browser runs on Browsa.

  • TimeAbout 5 minutes
  • Cost1 credit per 5-minute browser, plus your model costs
  • Last tested
What we tested. On November 7, 2026 we connected Stagehand 3.7.3 to a live Browsa browser with this script's code (env: "LOCAL" with cdpUrl and cdpHeaders) and opened https://example.com. The script also type-checks. We didn't run act() or extract(), which need your OpenAI key; those lines follow Stagehand's v3 API.

Prerequisites

  • A Browsa API key (it starts with agt_). Sign up for 100 free credits, no card.
  • Node.js 20.19 or newer (Stagehand 3.7 requires it).
  • A model key. The script uses OpenAI; Stagehand also takes anthropic/... and google/... model names.

Install

Terminal
npm install @browserbasehq/stagehand@3 browsa zod
npm install -D tsx
npm pkg set type=module

Then put your keys in the environment:

Terminal
export BROWSA_API_KEY="agt_live_..."
export OPENAI_API_KEY="sk-..."
Use Stagehand v3 for now. The script pins @browserbasehq/stagehand@3. Stagehand v4 attaches through a browser extension that it loads over CDP from your disk. In our test, v4's localBrowser.connect() failed on a Browsa browser with Method not available. v3 talks to the browser over plain CDP and works.

The script

One file. It starts a 5-minute Browsa browser, asks it for its WebSocket address, attaches Stagehand, clicks and extracts with your model, then destroys the browser.

agent.ts
import { Client } from "browsa";
import { Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod";

const apiKey = process.env.BROWSA_API_KEY!;
const browsa = new Client({ apiKey });
const cloud = await browsa.createAgent({ ttl: "5m" }); // a Browsa cloud browser, 1 credit

try {
  // Stagehand v3 attaches to a browser-level WebSocket URL. Ask the browser for it.
  const res = await fetch(`${cloud.cdp_http}/json/version`, {
    headers: { "X-API-Key": apiKey },
  });
  const { webSocketDebuggerUrl } = await res.json();

  const stagehand = new Stagehand({
    env: "LOCAL",
    localBrowserLaunchOptions: {
      cdpUrl: webSocketDebuggerUrl,
      cdpHeaders: { "X-API-Key": apiKey },
    },
    model: { modelName: "openai/gpt-5.6-luna", apiKey: process.env.OPENAI_API_KEY },
  });
  await stagehand.init();

  const page = stagehand.context.pages()[0];
  await page.goto("https://example.com");

  await stagehand.act("click the link on the page");
  const { title } = await stagehand.extract(
    "the main heading of the page",
    z.object({ title: z.string() }),
  );
  console.log(title);

  await stagehand.close();
} finally {
  await browsa.destroyAgent(cloud.id);
}

Run it:

Terminal
npx tsx agent.ts

How it works

  1. Start a browser. createAgent({ ttl: "5m" }) starts a Chromium on Browsa and returns its id and its cdp_http address.
  2. Get the WebSocket address. Stagehand v3 connects to a WebSocket URL, so the script reads /json/version at cdp_http (with your header) and takes webSocketDebuggerUrl, a wss://browsa.io address.
  3. Attach and act. env: "LOCAL" with cdpUrl makes Stagehand attach instead of launching Chrome, and cdpHeaders sends your key on the WebSocket. stagehand.close() leaves the browser running, so destroyAgent() in finally shuts it down.

Troubleshooting

401 Unauthorized when connecting

The X-API-Key header didn't reach Browsa, or the key is wrong. Check that BROWSA_API_KEY is set in the shell that runs the script and that it starts with agt_; the Browsa SDK refuses keys that don't. Pass the header exactly as the script does.

The connection drops after a few minutes

The browser reached the end of its TTL and shut down. The scripts use ttl="5m" (1 credit). For longer runs, ask for more, up to "1h"; any TTL over 5 minutes costs 5 credits. Start a new browser for the next run.

Method not available. on connect

You're on Stagehand v4. Install v3: npm install @browserbasehq/stagehand@3, and use the new Stagehand({ env: "LOCAL", ... }) form shown above.

Top-level await or require errors

The script is an ES module. Keep "type": "module" in package.json and run it with npx tsx agent.ts.

Next steps

Use the same browser from Playwright or Puppeteer, or move to a Python agent with browser-use.

Run it on a cloud browser.

100 free credits. No card, no subscription.