> 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 full documentation content, see https://platform.bctrl.ai/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://platform.bctrl.ai/_mcp/server.

# Quickstart

> Install the SDK, launch a cloud browser, and connect to it in about 60 seconds.

Go from an empty project to a cloud browser you drive with Playwright.

## 1. Install

```bash npm
npm install @bctrl/sdk playwright
```

```bash pnpm
pnpm add @bctrl/sdk playwright
```

## 2. Create a client

```ts
import { Bctrl } from "@bctrl/sdk";

const bctrl = new Bctrl({ apiKey: process.env.BCTRL_API_KEY! });
```

Create an API key in the [dashboard](https://app.bctrl.ai). If you omit `apiKey`, the client reads `BCTRL_API_KEY` from the environment.

## 3. Launch a runtime

A runtime is a cloud browser. Create it, then start it to get a connect URL:

```ts
const runtime = await bctrl.runtimes.create({ type: "browser", name: "quickstart" });
const { connectUrl, runId } = await bctrl.runtimes.start(runtime.id);
```

`start` mints a fresh, run-scoped `connectUrl` and opens a [run](/sdk/runs) that records everything that happens.

## 4. Drive it (two options)

```ts Connect with CDP
import { chromium } from "playwright";

const browser = await chromium.connectOverCDP(connectUrl);
const page = browser.contexts()[0]?.pages()[0] ?? (await browser.newPage());

await page.goto("https://example.com");
console.log(await page.title());
```

```ts Hand it to an agent
import { z } from "zod";

const invocation = await bctrl.runtimes.invocations.createAndWait(runtime.id, {
  action: "extract",
  instruction: "Extract the page title.",
  schema: z.object({ title: z.string() }),
});

console.log(invocation.status, invocation.output);
```

Use one controller at a time. See [Connect with CDP](/sdk/connect-cdp) and [Hosted agents](/sdk/hosted-agents) for the full surface.

## 5. Inspect the run

The `runId` from `start` lets you read events and open a live view while the browser runs:

```ts
const run = await bctrl.runs.get(runId);
const events = await bctrl.runs.events.list(runId);

const live = await bctrl.runs.live(runId, { control: "none" });
console.log(live.url);
```

## 6. Stop the runtime

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

## Next

* [Spaces](/sdk/spaces) - scope what a runtime can access
* [Invocations](/sdk/invocations) - hosted agent actions
* [Runs](/sdk/runs) - events, live view, and recordings