> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lusor.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Recordings and replay

> Watch a session back as video, or step through it action by action.

A session can be watched back two ways:

* **Recording**: a video of the phone's screen during the session.
* **Step-by-step replay**: each action the agent took, with the screenshot taken after it.

## Which sessions are recorded

* **Turns sent to an agent** are always recorded. The turn's response has `recording: true`.
* **Sessions without an agent** are recorded only when you ask. Send `"recording": true` when you [start the session](https://docs.lusor.ai/agents/send-a-turn.md#sessions-without-an-agent). It is off by default.

## Get the recording

```bash cURL theme={null}
curl https://api.lusor.ai/v1/sessions/<session id>/recording \
  -H "X-Api-Key: $LUSOR_API_KEY"
```

```python Python theme={null}
import os, requests

r = requests.get(
    "https://api.lusor.ai/v1/sessions/<session id>/recording",
    headers={"X-Api-Key": os.environ["LUSOR_API_KEY"]},
).json()
if r["data"]:
    for segment in r["data"]["segments"]:
        print(segment["url"])
```

```javascript Node.js theme={null}
const r = await (
  await fetch("https://api.lusor.ai/v1/sessions/<session id>/recording", {
    headers: { "X-Api-Key": process.env.LUSOR_API_KEY },
  })
).json();
if (r.data) {
  for (const segment of r.data.segments) console.log(segment.url);
}
```

`recording_status` is always present:

| `recording_status` | Meaning |
| - | - |
| `absent` | The session has no recording. |
| `pending` | The recording is still being finished. Ask again in a few seconds. |
| `complete` | The recording is finished. |
| `failed` | The recording could not be finished. `recording_status_reason` says why. |

`data` is `null` until there is something to play. Then `data.segments` lists its MP4 segments in order. Each segment has a `url`, its `start_offset_ms` and `duration_ms` within the recording, and `expires_at`, the time in Unix seconds when the `url` stops working. Request the endpoint again for fresh links.

## Step-by-step replay

```bash theme={null}
curl https://api.lusor.ai/v1/sessions/<session id>/replay \
  -H "X-Api-Key: $LUSOR_API_KEY"
```

`data` lists each completed action in time order. Each entry has the action `event`, its `timestamp`, and a `frame_url` for the PNG screenshot taken after it. `frame_url` expires at `expires_at` (Unix seconds), about five minutes later. Screenshots that are still uploading appear on a later request.

To download one screenshot through the API instead of a link, request `GET /v1/sessions/{id}/replay/frame?index=<n>`. `index` counts from 0 in the list `/replay` returns. The response is the PNG image.

## History window

Recordings and replay follow your plan's history window. For a session older than the window, both endpoints return `402` with `error: "upgrade_required"` and `reason: "history_window"`. A recording stays available past the window when your plan includes video replay, or when it was made on a Lusor Phone with a paid plan. See [Pricing](https://lusor.ai/pricing).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.