SDK Overview
The BCTRL SDK is a thin client. Each resource maps one-to-one to the HTTP API, each method makes a single request, and each request returns the response body unchanged. There’s no second model to learn: bctrl.runtimes.start(id) is exactly POST /v1/runtimes/{id}/start. Know the API, and you know the SDK.
Install
Omit apiKey and the client reads BCTRL_API_KEY from the environment. Create a key in the dashboard.
A complete run, end to end
Five calls take you from nothing to a recorded session. Read the comments - each step is a noun in the model below.
The model
Four nouns, and they nest. A space is the boundary - it decides which storage, secrets, and AI credentials its runtimes can reach. A runtime is a cloud browser launched inside a space. Starting a runtime opens a run and hands back a connect URL. An invocation is what you create when you’d rather a hosted agent drive the runtime than do it yourself. The run is the thread that ties it together: whether you drove over CDP or an agent did, every event lands in the same run.
One decision: who drives?
A runtime takes one controller at a time, and you pick which:
- Drive it yourself. Take the
connectUrlfromstart()and control the browser with Playwright or Puppeteer over CDP. See Connect with CDP. - Hand it to an agent. Create an invocation and let a hosted agent do the work in natural language. See Hosted agents.
While one controller holds the runtime, the other fails with runtime.controller_busy until the connection is released or the invocation finishes. Check for it with Bctrl.isControllerBusy(error).
Everything else mounts into a space
Vault, AI Providers, Proxies, Extensions, and Tools are reusable resources: define them once, mount them into a space, and every runtime there inherits them. Account is the organization layer above it all - API keys, subaccounts, and usage.
What the SDK guarantees
The SDK will never:
- Wrap responses. Every method returns the route’s response body, unchanged.
- Make a request you didn’t ask for - no hidden follow-ups, no background refresh, no implicit default-space lookup.
- Bundle a browser driver. You bring your own Playwright or Puppeteer; the SDK never wraps them.
The few ergonomics it does add are explicit, so you always know where the work happens:
.iter()walks cursor pagination for you..streamUrl()returns an SSE endpoint for live events.- Typed errors -
BctrlNotFoundError,BctrlRateLimitError,isControllerBusy, and more. - Pass a Zod
schematoextract; the SDK converts it to JSON Schema on the wire. createAndWaitpolls an invocation to completion - the name tells you it makes more than one request.
What to read next
- Quickstart - launch and connect in 60 seconds
- Invocations - hosted agent actions
- Runs - events, live view, and recordings
- SDK Essentials - pagination, streaming, errors, and idempotency

