Docs
Dashboard
IntegrationsBeta

Stagehand

Stagehand's act() and extract() drive a Boxline session's browser. Stagehand calls the model itself, with your own OpenAI key.

How it works

Stagehand v3: new Stagehand({ env: "LOCAL", localBrowserLaunchOptions: { cdpUrl: session.connectUrl }, model: { modelName, apiKey } }), then init(), act(), extract() with a zod schema. Create the session with keepAlive: true and release it after stagehand.close().

Needsany plan; your own OpenAI key.
Sitebooks.toscrape.com or quotes.toscrape.com, demo sites made for scraping practice.
EnvironmentBOXLINE_API_KEY, OPENAI_API_KEY (your OpenAI key: Stagehand calls OpenAI itself), STAGEHAND_MODEL (the model, as provider/model; default openai/gpt-6-luna).
Packages@boxline/sdk, @browserbasehq/stagehand@3.7.3, tsx@4.23.15, zod@3.25.76

The code

TypeScript
/** * Stagehand with Boxline: Stagehand's act() and extract() drive a Boxline session's browser, connected by its CDP * address (Stagehand v3: env "LOCAL" with localBrowserLaunchOptions.cdpUrl). Stagehand calls the model itself, with * your own OpenAI key. * *   npm install && npx tsx index.ts        (BOXLINE_API_KEY and OPENAI_API_KEY in the environment; STAGEHAND_MODEL) * * Stagehand v4 connects differently: it loads its own browser extension from this computer's disk and needs the * `debugger` permission, which Boxline sessions do not accept. Use v3 with Boxline. Writes output/result.json. */import { mkdirSync, writeFileSync } from "node:fs";import { join } from "node:path";import { Boxline } from "@boxline/sdk";import { Stagehand } from "@browserbasehq/stagehand";import { z } from "zod";const out = process.env.OUTPUT_DIR ?? "output";const modelName = process.env.STAGEHAND_MODEL ?? "openai/gpt-6-luna";if (!process.env.OPENAI_API_KEY) throw new Error("Set OPENAI_API_KEY: Stagehand calls the model itself");const bx = new Boxline();// keepAlive: the session stays up while Stagehand connects, and until it is stopped below.const session = await bx.sessions.create({ timeout: 600, keepAlive: true, userMetadata: { example: "integrations/stagehand" } });console.log(`Session: ${session.id}`);const stagehand = new Stagehand({  env: "LOCAL",  localBrowserLaunchOptions: { cdpUrl: session.connectUrl! }, // a signed address: treat it like a password  model: { modelName, apiKey: process.env.OPENAI_API_KEY },  verbose: 0,  disablePino: true,});try {  await stagehand.init();  const page = stagehand.context.pages()[0]!;  await page.goto("https://books.toscrape.com/");  const act = await stagehand.act("click the Poetry category in the list of book categories");  console.log(`act: ${act.message}`);  const { books } = await stagehand.extract(    "the title and price of the first 5 books listed on this page",    z.object({ books: z.array(z.object({ title: z.string(), price: z.string().describe("as shown, e.g. £51.77") })) }),  );  const url = page.url();  const metrics = await stagehand.metrics;  console.log(`${url}: ${books.length} books, e.g. ${books[0]?.title} ${books[0]?.price}`);  mkdirSync(out, { recursive: true });  writeFileSync(    join(out, "result.json"),    JSON.stringify(      { sessionId: session.id, model: modelName, act: { success: act.success, message: act.message }, url, books, usage: { ownModelTokens: metrics.totalPromptTokens + metrics.totalCompletionTokens } },      null,      2,    ),  );} finally {  await stagehand.close().catch(() => undefined);  await session.stop();}

Install and run

The packages are pinned at the versions the example’s check ran with. It writes to output/ and stops its session when it finishes.

Shell
# Node 22 or newerexport BOXLINE_API_KEY=…        # your Boxline API keyexport OPENAI_API_KEY=…         # your own OpenAI keynpm install @boxline/sdk @browserbasehq/stagehand@3.7.3 tsx@4.23.15 zod@3.25.76npx tsx index.ts

What its check proves

It checks that act() opened the Poetry category and extract() read its first 5 books with the prices the site shows. To run it from a clone of the examples (git clone https://github.com/Boxline-dev/examples.git), go to examples/integrations/stagehand, run the commands above, then check the result from the same folder: npx tsx check.ts output.

Source: github.com/Boxline-dev/examples/integrations/stagehand on GitHub. See all integrations.

These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.