> 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.

# Runs

> The session record created when a runtime starts.

A **Run** is one execution of a Runtime, from start until it stops or fails.
It is the record of that execution.

Every trace, event, recording, and usage entry for the execution is keyed by
the Run ID. A Run response exposes that identifier as `id`; Run-scoped methods
take it as `runId`. Use `runtimeId` to identify the Runtime that produced the
Run.

The runtime controls the Run lifecycle:

1. Creating an ephemeral runtime normally opens a Run immediately.
2. Starting a stopped runtime opens a Run and returns its `runId`.
3. Browser connections, Tools, ToolCalls, and Agent turns contribute to that Run.
4. Stopping the runtime ends the Run.

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

const started = await bctrl.runtimes.start(runtime.id);
const run = await bctrl.runs.get(started.runId);

console.log(run.id, run.status, run.runtimeId);

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

## Find Runs

List Runs for a Space or read one by ID:

```ts
const page = await bctrl.runs.list({
  spaceId: "default",
});

for await (const run of bctrl.runs.iter({ spaceId: "default" })) {
  console.log(run.id, run.status, run.startedAt);
}

const one = await bctrl.runs.get(runId);
```

Run status is `active`, `stopped`, or `failed`. A failed Run includes a failure
code and message when the platform has one.

## Run fields

| Field             | Type                                               | Always present | Description                                                                        |
| ----------------- | -------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------- |
| `id`              | `RunId`                                            | Yes            | Unique Run identifier.                                                             |
| `spaceId`         | `string`                                           | Yes            | Space that owns the Run.                                                           |
| `runtimeId`       | `RuntimeId`                                        | Yes            | Runtime that produced the Run.                                                     |
| `runtimeType`     | `"browser" \| "desktop" \| "spreadsheet"`          | Yes            | Runtime category recorded for the Run. The SDK currently creates browser Runtimes. |
| `status`          | `"active" \| "stopped" \| "failed"`                | Yes            | Current Run state.                                                                 |
| `createdAt`       | `string`                                           | Yes            | Creation timestamp in ISO 8601 format.                                             |
| `startedAt`       | `string`                                           | Yes            | Start timestamp in ISO 8601 format.                                                |
| `finishedAt`      | `string \| null`                                   | Yes            | Completion timestamp, if finished.                                                 |
| `durationSeconds` | `number \| null`                                   | Yes            | Run duration, if available.                                                        |
| `failure`         | `RunFailure \| null`                               | Yes            | Failure code and message, if failed.                                               |
| `recording`       | `{ enabled: boolean }`                             | Yes            | Whether recording was enabled.                                                     |
| `counts`          | `{ events: number; files: number; spans: number }` | Yes            | Related resource counts.                                                           |
| `usage`           | `RunUsage`                                         | No             | Usage totals when available.                                                       |

#### Full Run shape

```ts
type Run = {
  id: string;
  spaceId: string;
  runtimeId: string;
  runtimeType: "browser" | "desktop" | "spreadsheet";
  status: "active" | "stopped" | "failed";
  createdAt: string;
  startedAt: string;
  finishedAt: string | null;
  durationSeconds: number | null;
  failure: RunFailure | null;
  recording: { enabled: boolean };
  counts: { events: number; files: number; spans: number };
  usage?: RunUsage;
};
```

## Runtime and Run are different

The **Runtime** is the durable automation resource. The **Run** is one session
of that Runtime. An ephemeral Runtime normally has one Run; a profile-backed
Runtime can have many Runs over its lifetime.

Use the Run ID when you need to inspect the trace, read raw events, follow live
activity, review an audit record, or connect files and artifacts to one
execution.

## Trace and events

BCTRL exposes two complementary views of a Run:

| Surface        | What it contains                                                                | Best for                                                          |
| -------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| **Trace**      | Hierarchical spans with a kind, status, timing, and parent                      | Understanding causal work such as a ToolCall inside an Agent turn |
| **Events**     | Raw point-in-time facts from the control plane, runtime, browser, or connection | Debugging low-level runtime behavior                              |
| **Run stream** | A resumable SSE stream of trace and event frames                                | Building live progress or monitoring                              |

### Read the trace

```ts
const tracePage = await bctrl.runs.trace.list(runId, {
  kind: ["tool", "browser"],
  status: ["succeeded", "failed"],
});

for await (const span of bctrl.runs.trace.iter(runId)) {
  console.log(span.kind, span.name, span.status, span.parentId);
}
```

Trace spans can have these kinds:

`runtime`, `agent`, `tool`, `llm`, `browser`, `network`, `file`, and `system`.

`parentId` connects nested spans into a causal tree. Use `resourceType` and
`resourceId` to connect a span back to a runtime, ToolCall, Agent turn, file,
or other platform resource.

### Read raw events

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

for await (const event of bctrl.runs.events.iter(runId)) {
  console.log(event.timestamp, event.source, event.type, event.data);
}
```

Events include a source such as `control-plane`, `browser-host`, `runtime-agent`,
`gateway`, `cdp`, or `webdriver`. They may reference the trace span that caused
the event through `spanId`.

### Trace and event fields

| Surface    | Important fields                                                                                                          |
| ---------- | ------------------------------------------------------------------------------------------------------------------------- |
| Trace span | `id`, `kind`, `name`, `status`, `parentId`, `resourceType`, `resourceId`, `startedAt`, `finishedAt`, `durationMs`, `data` |
| Run event  | `id`, `runId`, `timestamp`, `source`, `type`, `spanId`, `pageId`, `data`                                                  |

Trace `kind` is one of `runtime`, `agent`, `tool`, `llm`, `browser`, `network`,
`file`, or `system`. Event `source` identifies where the fact came from.

#### Full trace and event shapes

```ts
type TraceSpan = {
  id: string;
  runId: string;
  kind: "runtime" | "agent" | "tool" | "llm" | "browser" | "network" | "file" | "system";
  name: string;
  status: "queued" | "running" | "requires_input" | "suspended" | "succeeded" | "failed" | "cancelled" | "timed_out";
  parentId: string | null;
  resourceId: string | null;
  resourceType: "run" | "runtime" | "tool_call" | "agent_turn" | "message" | "file" | "artifact" | "connection" | null;
  startedAt: string | null;
  finishedAt: string | null;
  durationMs: number | null;
  data: Record<string, unknown>;
};

type RunEvent = {
  id: string;
  runId: string;
  timestamp: string;
  source: "control-plane" | "browser-host" | "runtime-agent" | "gateway" | "cdp" | "webdriver";
  type: string;
  spanId: string | null;
  pageId: string | null;
  data: Record<string, unknown>;
};
```

### Stream a Run

The unified stream emits normalized frames as the Run changes:

```ts
for await (const item of bctrl.runs.stream(runId, {
  include: ["trace", "events"],
})) {
  switch (item.type) {
    case "span.started":
    case "span.updated":
    case "span.completed":
      console.log(item.type, item.span.name, item.span.status);
      break;
    case "runtime.event":
      console.log(item.event.type, item.event.data);
      break;
    case "run.ended":
      console.log("Run ended:", item.status);
      break;
  }
}
```

For a reconnect, pass the last received stream ID as `after` so the server can
continue from that point. The stream ends when the Run ends.

Use **trace** to answer “what work caused this result?”, **events** to answer
“what did the runtime report?”, and the **stream** to answer “what is happening
now?”.

See [Connect with CDP](/sdk/connect-cdp) for attaching a browser client to the
active Run.