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

# Show Customers a Replay

> Embed a session recording and render the activity feed as a human-readable timeline.

After a [run](/sdk/runs) finishes, give your users proof of what happened: a
video-style replay they can scrub next to the activity timeline. A single
embedded View composes both from the run you already have.

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

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

// ... run finished, runtime stopped ...

const replay = await bctrl.views.create({
  scope: { runId },
  recordings: true,
  trace: true,
  events: true,
  presentation: {
    mode: "embedded",
    allowedOrigins: ["https://portal.acme.com"],
  },
  expiresInSeconds: 86_400,
});

console.log(replay.url);

```

```python Python
from bctrl import Bctrl

bctrl = Bctrl()

# ... run finished, runtime stopped ...

replay = bctrl.views.create(
    scope={"run_id": run_id},
    recordings=True,
    trace=True,
    events=True,
    presentation={
        "mode": "embedded",
        "allowed_origins": ["https://portal.acme.com"],
    },
    expires_in_seconds=86_400,
)

print(replay["url"])
```

Embed the replay using the same [View](/sdk/views) surface as a live browser view:

```html
<iframe
  src="https://...embed URL..."
  width="1280"
  height="800"
  style="border: 0"
></iframe>
```

> 📸 **Content TODO:** screenshot of the finished layout - replay iframe on the left, activity timeline rendered as a list on the right. If you have the redesigned activity UI, a capture of a real run (navigation → typing → captcha solve → download) sells it best.

## The timeline is part of the composition

With `events: true`, the embedded View can render the Run's event history beside
the replay, using the same visual system as hosted Views. You do not need to
recreate the timeline in your frontend. If you want a custom native UI, use the
[Run events](/sdk/runs#trace-and-events) API separately.

If you need the raw record instead - every request, console line, and navigation - use [Run events](/sdk/runs#trace-and-events).

## Expiry

The View is a time-limited lease (`expiresInSeconds`). It defaults to 28,800
seconds (8 hours) and allows up to 2,592,000 seconds (30 days). Mint a fresh one
on each customer session rather than storing its bearer URL.

## Next

* [Views](/sdk/views) - live and recording View surfaces
* [Trace and events](/sdk/runs#trace-and-events) - raw execution data
* [Run files](/sdk/files#run-files) - ship the run's artifacts alongside the replay