> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://platform.bctrl.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://platform.bctrl.ai/_mcp/server.

# Runtimes

> Create and control durable resources for automation.

A **Runtime** is the durable resource that performs automation. It represents
the thing being automated: a browser today, with computers and spreadsheets as
other runtime types in the same model.

A Runtime belongs to a Space and owns its configuration and identity. Tools,
Agents, and browser connections all operate through a Runtime.

The API currently exposes one runtime type:

| Type      | Meaning                    |
| --------- | -------------------------- |
| `browser` | A managed browser Runtime. |

The Runtime response exposes its generated identifier as `id` (`RuntimeId`).
When another resource or request refers to the Runtime, the field is named
`runtimeId`. Treat the ID as opaque; create it through the API rather than
constructing one yourself.

Starting a Runtime opens a Run and returns its `runId`.

## Choose the Runtime lifecycle

The `profile` option determines whether the browser identity persists:

| Runtime shape  | `profile`          | Starts by default | What happens when it stops                                            |
| -------------- | ------------------ | ----------------- | --------------------------------------------------------------------- |
| Ephemeral      | Omitted or `false` | Yes               | The session is single-use; create a new Runtime for the next session. |
| Profile-backed | `true`             | No                | The Runtime can be started again with the same browser identity.      |

Use an ephemeral Runtime for isolated jobs. Use a profile-backed Runtime when
cookies, logins, or local storage should survive a stop and restart.

## Create an ephemeral Runtime

```ts
const runtime = await bctrl.runtimes.create({
  name: "checkout-job",
});

console.log(runtime.id, runtime.activeRunId);
console.log(runtime.connection?.cdpUrl);
```

Ephemeral Runtimes start during creation unless you pass `start: false`. Their
response includes the active Run and run-scoped connection URLs.

If you do not need a label, the minimal request is valid too:

```ts
const runtime = await bctrl.runtimes.create({});
```

## Create a profile-backed Runtime

Profile-backed Runtimes are reusable and start stopped by default. Pass
`start: true` when you want a one-call create-and-start flow.

```ts
const runtime = await bctrl.runtimes.create({
  name: "customer-portal",
  profile: true,
});

const started = await bctrl.runtimes.start(runtime.id);
console.log(started.runId, started.connection.cdpUrl);

await bctrl.runtimes.stop(runtime.id);

// Start the same Runtime later. Its browser identity is retained.
await bctrl.runtimes.start(runtime.id);
```

## Runtime ID and Run ID

Use the Runtime object's `id` when operating on the Runtime. Use the Run's
`runId` when inspecting one execution:

| Field       | Where it appears                                | Use it for                                        |
| ----------- | ----------------------------------------------- | ------------------------------------------------- |
| `id`        | Runtime response (`runtime.id`)                 | Create, configure, start, and stop the Runtime.   |
| `runtimeId` | Run, Tool, and related resource fields          | Refer to the Runtime from another resource.       |
| `id`        | Run response (`run.id`)                         | Identify the returned Run object.                 |
| `runId`     | Run-scoped method arguments and start responses | Trace, events, recordings, streaming, and audits. |

## Runtime lifecycle

The Runtime owns the lifecycle; each start opens a Run:

```ts
const current = await bctrl.runtimes.get(runtime.id);
const runtimes = await bctrl.runtimes.list({ spaceId: "default" });

await bctrl.runtimes.update(runtime.id, {
  name: "customer-portal-prod",
});

await bctrl.runtimes.stop(runtime.id);
```

Runtime status is `active`, `stopped`, or `failed`. Read the associated Run to
understand what happened during an active or completed session.

## Configure the browser

Runtime creation has two kinds of options:

* Lifecycle options decide where the Runtime belongs, whether its browser
  identity persists, and when it starts.
* Browser configuration decides how the browser behaves once it starts.

### Creation parameters

| Parameter   | Type                         | Required | Description                                                                                                          |
| ----------- | ---------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `type`      | `"browser"`                  | No       | Runtime type. Defaults to `"browser"`.                                                                               |
| `spaceId`   | `string \| "default"`        | No       | Space whose environment the Runtime inherits. Defaults to the caller's default Space.                                |
| `profile`   | `boolean`                    | No       | `false` or omitted for ephemeral; `true` for profile-backed. Defaults to `false`.                                    |
| `start`     | `boolean`                    | No       | Start during creation or leave the Runtime stopped. Defaults to `true` for ephemeral and `false` for profile-backed. |
| `recording` | `boolean`                    | No       | Enable recording for the Run opened by the Runtime. Defaults to `true`. Set to `false` to disable it.                |
| `name`      | `string`                     | No       | Human-readable label. Defaults to the generated Runtime ID.                                                          |
| `metadata`  | `Record<string, unknown>`    | No       | Caller-owned metadata stored with the Runtime.                                                                       |
| `config`    | `BrowserRuntimeCreateConfig` | No       | Browser settings applied when the Runtime starts.                                                                    |

### Browser configuration parameters

Pass browser-specific settings in `config`:

```ts
const runtime = await bctrl.runtimes.create({
  name: "research-session",
  config: {
    headless: true,
    stealth: "best",
    proxy: "proxy_123",
    extensionIds: ["ext_123"],
    idleTimeoutSeconds: 900,
    webRtcProxyOnly: true,
    networkTraffic: {
      saver: "medium",
      blockAds: true,
    },
  },
});
```

| Parameter              | Type                                   | Required | Description                                                                                                                                                                                                                              |
| ---------------------- | -------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `headless`             | `boolean`                              | No       | Whether the browser runs without a visible window. Defaults to the platform setting.                                                                                                                                                     |
| `stealth`              | `"normal" \| "best" \| "experimental"` | No       | Browser hardening level. Defaults to the platform setting.                                                                                                                                                                               |
| `proxy`                | `RuntimeProxyInput`                    | No       | Saved proxy, proxy URL, or inline proxy configuration. Omit it on create to use the BCTRL-managed proxy; on update, omission preserves the existing setting. Use `{ type: "managed-rotating" }` to explicitly reset to managed defaults. |
| `fingerprint`          | `RuntimeFingerprintCreateConfig`       | No       | Browser and viewport constraints.                                                                                                                                                                                                        |
| `extensionIds`         | `string[]`                             | No       | Extensions to load at browser start.                                                                                                                                                                                                     |
| `idleTimeoutSeconds`   | `number`                               | No       | Stop the Runtime after inactivity.                                                                                                                                                                                                       |
| `autoUpgrade`          | `boolean`                              | No       | Use the latest compatible browser version on start.                                                                                                                                                                                      |
| `webRtcProxyOnly`      | `boolean`                              | No       | Route WebRTC through the proxy. Defaults to `false`.                                                                                                                                                                                     |
| `forceOpenShadowRoots` | `boolean`                              | No       | Make closed shadow roots available to automation. Defaults to `false`.                                                                                                                                                                   |
| `networkTraffic`       | `BrowserNetworkTrafficConfig`          | No       | Save bandwidth or block selected traffic.                                                                                                                                                                                                |

### Network traffic parameters

| Parameter            | Type                                                                                  | Required | Description                       |
| -------------------- | ------------------------------------------------------------------------------------- | -------- | --------------------------------- |
| `saver`              | `"none" \| "light" \| "medium" \| "high"`                                             | No       | Traffic-saving preset.            |
| `blockAds`           | `boolean`                                                                             | No       | Block known advertising requests. |
| `blockTrackers`      | `boolean`                                                                             | No       | Block known tracker requests.     |
| `blockResourceTypes` | `("media" \| "texttrack" \| "font" \| "image" \| "ping" \| "prefetch" \| "beacon")[]` | No       | Resource types to block.          |
| `urlAllowlist`       | `string[]`                                                                            | No       | URLs that remain allowed.         |
| `urlBlocklist`       | `string[]`                                                                            | No       | URLs that should be blocked.      |

#### Full BrowserRuntimeCreateConfig shape

```ts
type BrowserRuntimeCreateConfig = {
  autoUpgrade?: boolean;
  extensionIds?: string[];
  fingerprint?: {
    browser?: "chrome";
    viewport?: {
      height: number;
      width: number;
    };
  };
  forceOpenShadowRoots?: boolean;
  headless?: boolean;
  idleTimeoutSeconds?: number;
  networkTraffic?: BrowserNetworkTrafficConfig;
  proxy?: RuntimeProxyInput;
  stealth?: "normal" | "best" | "experimental";
  webRtcProxyOnly?: boolean;
};
```

Profile-backed Runtimes retain browser identity. Keep their configuration
focused on settings that should apply to every start:

```ts
const runtime = await bctrl.runtimes.create({
  profile: true,
  name: "customer-portal",
  config: {
    proxy: "proxy_123",
    idleTimeoutSeconds: 900,
  },
});
```

Use the [Stealth browsing cookbook](/cookbook/stealth-browsing), [Load browser extensions cookbook](/cookbook/load-extensions), and [Trim network traffic cookbook](/cookbook/trim-network-traffic) for complete recipes. This page is
the option map; the cookbooks show the combinations.

## Next

* [Runs](/sdk/runs) — understand the session opened by a Runtime
* [Connect with CDP](/sdk/connect-cdp) — attach Playwright or Puppeteer
* [Connect with WebDriver](/sdk/connect-webdriver) — attach Selenium