SDK Overview

View as Markdown

BCTRL gives automation agents managed browser runtimes they can control from your code. The SDK handles spaces, runtime lifecycle, connection leases, hosted invocations, storage, and run observability.

The browser itself is still controlled by the tools you already use.

Runtime = control
Run = observability

Use runtime APIs to launch, connect, invoke, move files, and stop. Use run APIs to inspect events, commands, artifacts, live view, and recordings.

Browser runtimes have a strict controller lock. Use either a CDP connection from your own process or a hosted invocation from BCTRL, but not both at the same time on the same runtime.

Canonical browser flow

1import { Bctrl } from "@bctrl/sdk";
2import { chromium } from "playwright";
3
4const bctrl = new Bctrl({
5 apiKey: process.env.BCTRL_API_KEY!,
6});
7
8const space = await bctrl.spaces.create({
9 name: "browser-agent",
10});
11
12const runtime = await space.runtimes.browser.launch({
13 name: "main",
14});
15
16const connection = await runtime.connections.create({
17 protocol: "cdp",
18});
19
20const browser = await chromium.connectOverCDP(connection.endpoint.url);
21const page = browser.contexts()[0]?.pages()[0] ?? await browser.newPage();
22
23await page.goto("https://example.com");
24
25const run = await runtime.currentRun();
26
27await run.events.list();
28await run.artifacts.list();
29
30await runtime.stop();

Core resources

ResourcePurpose
SpacesTask and permission boundaries for runtimes, storage, vault access, AI credentials, and tools.
RuntimesLive execution targets. Browser runtimes are the stable runtime type today.
ConnectionsShort-lived protocol leases for external tools such as Playwright, Puppeteer, or debuggers.
InvocationsHosted AI work that BCTRL runs inside a runtime, such as Stagehand or browser-use tasks.
RunsDurable records for events, commands, artifacts, live view, recordings, and activity.

Connections vs invocations

Use connections when your own process controls the browser through CDP.

Use invocations when BCTRL should run hosted AI work inside the runtime.

Both target the same live runtime. If one controller is active, the other returns runtime.controller_busy until the connection is revoked, expires, or the invocation reaches a terminal state.