# Recordings

Source: https://phonebox.dev/docs/api-reference/recordings

> Record a phone's screen, stop the recording, list a phone's recordings, download a video and delete a recording.



A recording captures the phone's screen as a video, so you can watch what an agent did, share a failing run, or make a demo. It captures everything on the screen, passwords and codes included, so treat its video like the phone's own data.

* One recording runs at a time on each phone. Starting and stopping one needs a `ready` phone; listing, downloading and deleting work in any status.
* A project keeps at most 20 recordings. Phonebox deletes each one 7 days after it started, and `expires_at` says when.
* A recording is `recording` until you stop it, then `processing` until its video is ready, then `ready`. One that couldn't be saved is `failed`.
* Starting, stopping and deleting are sent to the phone once and never retried. Recording is included in the phone's running time: it costs nothing extra.
* Some phones can't record. Starting a recording on one fails with `422 feature_unavailable`, with `details.feature` set to `recordings`.

## Start a recording [#start-a-recording]

`POST /v1/phones/{id}/recordings` needs the `phones:control` scope.

| Field  | Type   | Default | Rules                                                    |
| ------ | ------ | ------- | -------------------------------------------------------- |
| `name` | string | None    | A name to tell the recording apart, up to 80 characters. |

```json title="POST /v1/phones/{id}/recordings"
{
  "name": "checkout flow"
}
```

```bash
curl -X POST https://phonebox.dev/v1/phones/ph_7kx2m6q4v3ta/recordings \
  -H "Authorization: Bearer $PHONEBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "checkout flow"}'
```

It answers `201 Created` with the recording.

```json title="Response: recording"
{
  "object": "recording",
  "id": "rec_q3m7x2k6v4tb",
  "phone": "ph_7kx2m6q4v3ta",
  "name": "checkout flow",
  "status": "recording",
  "started_at": "2026-09-30T10:00:00.000Z",
  "ended_at": null,
  "duration_ms": null,
  "size_bytes": null,
  "expires_at": "2026-10-07T10:00:00.000Z"
}
```

| Error                         | When                                                                                                                                                                                                           |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `409 recording_in_progress`   | Another recording is running on this phone. `details.recording` names it, when Phonebox can tell, and `next` is the request that stops it.                                                                     |
| `409 recording_limit_reached` | The project already keeps 20 recordings, on any of its phones. Delete one, on this phone or another, or wait for one to expire. A deleted phone's recordings count until they expire, 7 days after they start. |
| `422 feature_unavailable`     | The phone can't record.                                                                                                                                                                                        |

## List recordings [#list-recordings]

`GET /v1/phones/{id}/recordings` needs the `phones:read` scope.

The phone's recordings, newest first.

```bash
curl https://phonebox.dev/v1/phones/ph_7kx2m6q4v3ta/recordings \
  -H "Authorization: Bearer $PHONEBOX_API_KEY"
```

```json title="Response: recordings"
{
  "data": [
    {
      "object": "recording",
      "id": "rec_q3m7x2k6v4tb",
      "phone": "ph_7kx2m6q4v3ta",
      "name": "checkout flow",
      "status": "ready",
      "started_at": "2026-09-30T10:00:00.000Z",
      "ended_at": "2026-09-30T10:02:14.000Z",
      "duration_ms": 134000,
      "size_bytes": 18350080,
      "expires_at": "2026-10-07T10:00:00.000Z"
    }
  ]
}
```

## Stop a recording [#stop-a-recording]

`POST /v1/phones/{id}/recordings/{rid}/stop` needs the `phones:control` scope.

Stops the recording and answers with it, now `processing` or already `ready`. Stopping one that has already stopped answers with it as it is, and sends nothing to the phone.

```bash
curl -X POST https://phonebox.dev/v1/phones/ph_7kx2m6q4v3ta/recordings/rec_q3m7x2k6v4tb/stop \
  -H "Authorization: Bearer $PHONEBOX_API_KEY"
```

| Error                     | When                                             |
| ------------------------- | ------------------------------------------------ |
| `404 recording_not_found` | No recording with this ID belongs to this phone. |

## Download a recording [#download-a-recording]

`GET /v1/phones/{id}/recordings/{rid}/video` needs the `phones:read` scope.

The video, as an MP4 file named after the recording's ID. It streams from Phonebox itself.

```bash
curl -o checkout.mp4 https://phonebox.dev/v1/phones/ph_7kx2m6q4v3ta/recordings/rec_q3m7x2k6v4tb/video \
  -H "Authorization: Bearer $PHONEBOX_API_KEY"
```

| Error                     | When                                                                                                                           |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `404 recording_not_found` | No recording with this ID belongs to this phone, or its video is gone.                                                         |
| `409 recording_not_ready` | The recording is still running, or its video is still processing. Stop it first, then list the recordings until it is `ready`. |

## Delete a recording [#delete-a-recording]

`DELETE /v1/phones/{id}/recordings/{rid}` needs the `phones:control` scope.

Deletes the recording and its video. This can't be undone. A recording that is still running is stopped first.

```bash
curl -X DELETE https://phonebox.dev/v1/phones/ph_7kx2m6q4v3ta/recordings/rec_q3m7x2k6v4tb \
  -H "Authorization: Bearer $PHONEBOX_API_KEY"
```

```json title="Response: delete recording"
{
  "id": "rec_q3m7x2k6v4tb",
  "deleted": true
}
```

| Error                       | When                                                                                                                             |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `404 recording_not_found`   | No recording with this ID belongs to this phone.                                                                                 |
| `409 recording_in_progress` | The recording is still running and the phone isn't, so it can't be stopped. Start the phone, stop the recording, then delete it. |
