Skip to navigation

Runs

View as Markdown

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

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

FieldTypeAlways presentDescription
idRunIdYesUnique Run identifier.
spaceIdstringYesSpace that owns the Run.
runtimeIdRuntimeIdYesRuntime that produced the Run.
runtimeType"browser" | "desktop" | "spreadsheet"YesRuntime category recorded for the Run. The SDK currently creates browser Runtimes.
status"active" | "stopped" | "failed"YesCurrent Run state.
createdAtstringYesCreation timestamp in ISO 8601 format.
startedAtstringYesStart timestamp in ISO 8601 format.
finishedAtstring | nullYesCompletion timestamp, if finished.
durationSecondsnumber | nullYesRun duration, if available.
failureRunFailure | nullYesFailure code and message, if failed.
recording{ enabled: boolean }YesWhether recording was enabled.
counts{ events: number; files: number; spans: number }YesRelated resource counts.
usageRunUsageNoUsage totals when available.
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:

SurfaceWhat it containsBest for
TraceHierarchical spans with a kind, status, timing, and parentUnderstanding causal work such as a ToolCall inside an Agent turn
EventsRaw point-in-time facts from the control plane, runtime, browser, or connectionDebugging low-level runtime behavior
Run streamA resumable SSE stream of trace and event framesBuilding live progress or monitoring

Read the trace

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

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

SurfaceImportant fields
Trace spanid, kind, name, status, parentId, resourceType, resourceId, startedAt, finishedAt, durationMs, data
Run eventid, 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.

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:

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 for attaching a browser client to the active Run.