Runtimes

View as Markdown

A runtime is a managed cloud browser running on BCTRL infrastructure. Create it with a configuration, start it to get a connect URL, drive it, then stop it. Browser is the only runtime type today.

Create a runtime

1const runtime = await bctrl.runtimes.create({
2 type: "browser",
3 name: "main",
4});

Scope it to a space with spaceId so it inherits that space’s storage, vault, and AI mounts:

1const runtime = await bctrl.runtimes.create({
2 spaceId: space.id,
3 type: "browser",
4 name: "main",
5});

Configure the browser

Pass config to set stealth, proxy, fingerprint, extensions, and network behaviour:

1const runtime = await bctrl.runtimes.create({
2 type: "browser",
3 name: "stealthy",
4 config: {
5 stealth: "high",
6 proxy: { mode: "saved", id: "pxy_123" },
7 fingerprint: { browser: "chrome", locale: "en-US" },
8 extensionIds: ["ext_123"],
9 idleTimeoutMinutes: 10,
10 },
11});

See Runtime configuration for the full set of options, and Proxies and Extensions for the resources they reference.

Start a runtime

Starting boots the browser and mints a fresh, run-scoped connect URL:

1const { connectUrl, runId, runtimeId } = await bctrl.runtimes.start(runtime.id);

Every start opens a new run (runId) where the session is recorded. The connectUrl is a credentialed CDP endpoint - see Connect with CDP.

start accepts an idempotency key so retries do not double-start:

1await bctrl.runtimes.start(runtime.id, { idempotencyKey: "boot-2024-06-01" });

List, read, and stop

list returns every runtime in the organization; pass spaceId to narrow to one space.

1const { data } = await bctrl.runtimes.list({ spaceId: space.id });
2
3for await (const rt of bctrl.runtimes.iter()) {
4 console.log(rt.id, rt.status);
5}
6
7const current = await bctrl.runtimes.get(runtime.id);
8
9await bctrl.runtimes.stop(runtime.id);

Update and delete

name and idleTimeoutMinutes are editable any time; config only while the runtime is stopped. The name is a display label - renaming never affects the runtime’s browser state.

1await bctrl.runtimes.update(runtime.id, { name: "renamed", idleTimeoutMinutes: 15 });
2
3await bctrl.runtimes.delete(runtime.id);

Deleting requires the runtime to be stopped; pass { force: true } to stop and delete in one call.

Targets (tabs)

A running browser exposes its pages as targets. List them, open new ones, switch focus, and close them:

1const { data: targets } = await bctrl.runtimes.targets.list(runtime.id);
2
3const tab = await bctrl.runtimes.targets.create(runtime.id, {
4 uri: "https://example.com",
5 activate: true,
6});
7
8await bctrl.runtimes.targets.activate(runtime.id, tab.id);
9
10await bctrl.runtimes.targets.delete(runtime.id, tab.id);

Hosted invocations act on the active target by default, so activate is how you point an agent at a specific tab.

Files on a runtime

Move files in and out of a running browser. These operate on the live runtime filesystem, distinct from the durable run artifacts in Run files:

1await bctrl.runtimes.files.list(runtime.id);
2
3await bctrl.runtimes.files.upload(runtime.id, {
4 file: new Blob(["name,email\n..."]),
5 runtimePath: "/work/input.csv",
6});
7
8await bctrl.runtimes.files.stage(runtime.id, {
9 fileId: "file_123",
10 runtimePath: "/work/input.csv",
11});
12
13await bctrl.runtimes.files.collect(runtime.id, {
14 runtimePath: "/work/output.pdf",
15});

stage copies a durable file into the runtime; collect saves a runtime file back to durable storage.

Next