Quickstart

View as Markdown

Install the SDK and set your API key:

$pnpm add @bctrl/sdk
$export BCTRL_API_KEY=your_api_key

Create a runtime

An ephemeral browser runtime starts immediately by default. Its response includes the active Run that was opened for the session.

1import { Bctrl } from "@bctrl/sdk";
2
3const bctrl = new Bctrl({
4 apiKey: process.env.BCTRL_API_KEY,
5});
6
7const runtime = await bctrl.runtimes.create({
8 name: "quickstart",
9});
10
11const runId = runtime.activeRunId;
12if (!runId) {
13 throw new Error("The runtime did not start");
14}

This uses the platform defaults: the caller’s default Space, a browser Runtime, recording enabled, and an ephemeral Runtime that starts immediately. The name is optional; when omitted, BCTRL uses the Runtime ID as the name.

Run a tool

Tools that may take longer than one request are started as durable ToolCalls. Wait for the result with the ToolCall client:

1const call = await bctrl.tools.start("browser.pages.open", {
2 url: "https://example.com",
3}, { runtimeId: runtime.id });
4
5const page = await bctrl.toolCalls.result(call.id, {
6 waitSeconds: 30,
7});
8
9console.log(page);

The same Run contains the runtime lifecycle and the ToolCall. Read it when you need the final status or identifiers for later inspection:

1const run = await bctrl.runs.get(runId);
2console.log(run.status, run.runtimeId);

Stop the runtime when the work is complete:

1await bctrl.runtimes.stop(runtime.id);
  • Core model - how Spaces, Runtimes, Runs, and automation fit together
  • Spaces - scope storage, Vault access, and AI credentials
  • Runtimes - choose ephemeral or profile-backed browser state
  • Runs - inspect and stream Run activity