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

# Events & Activity

> The structured event timeline and higher-level activity view of a run.

Every [run](/sdk/runs) records a structured timeline. Events are the low-level record of what happened; activity is the higher-level view over the same run. Both can be listed page by page or streamed live.

## List events

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

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

Filter by `type`, `status`, `pageId`, or `contextId`:

```ts
await bctrl.runs.events.list(runId, { type: "navigation" });
```

Valid `type` values: `runtime.lifecycle`, `navigation`, `network.request`, `network.response`, `network.failed`, `console.message`.

## Stream events

For a live feed, use `streamUrl` to get a server-sent events endpoint and consume it with your SSE client of choice:

```ts
const url = bctrl.runs.events.streamUrl(runId, { type: "console.message" });

const source = new EventSource(url);
source.onmessage = (message) => {
  const event = JSON.parse(message.data);
  console.log(event.type, event.name);
};
```

See [Streaming](/sdk/essentials) for the SSE consumption pattern.

## Activity

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

for await (const item of bctrl.runs.activity.iter(runId)) {
  console.log(item);
}

const liveUrl = bctrl.runs.activity.streamUrl(runId);
```

## Next

* [Live View](/sdk/live-view) - watch or take over a run
* [Recording](/sdk/recording) - replay a finished run
* [Streaming](/sdk/essentials) - SSE consumption