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

# Call recordings

> The recording state on a phone call and the short-lived download link, and what that link needs.

Sempera stores a phone call's audio when the workspace's data policy has recording on, and keeps it for the retention period the workspace owner set. The API tells you whether a recording exists and hands out a short-lived link to it; it does not stream audio itself.

## Whether a call has a recording

A phone call's `recording` field (`GET /v1/calls`, `GET /v1/calls/{call_id}`, `GET /v1/sessions/{id}`) reads:

```json theme={null}
{"id": "8f6c...", "state": "available", "expires_at": "2026-12-28T12:00:00+00:00",
 "deleted_at": null, "delete_reason": null, "access_ends_at": null}
```

| `state` | Meaning |
| - | - |
| `none` | No recording was stored (`id` is null) |
| `available` | Stored and playable |
| `held` | Past its expiry but kept, because a legal hold is on the workspace |
| `expired` | Past its expiry date and awaiting deletion |
| `access_ended` | Still kept, but the workspace's recording security setting has ended access to it |
| `deleted` | Deleted; `deleted_at` and `delete_reason` say when and why |

`id` is the value for `{recording_id}` below. `recording_stored` on the `call.completed` webhook ([Webhooks](https://docs.sempera.org/webhooks.md)) says whether one was stored.

## The download link

| Route | Scope | Notes |
| - | - | - |
| `GET /v1/recordings/{recording_id}` | `calls:read` | A signed link that is valid for 5 minutes, for a recording your workspace owns |

```json theme={null}
{"object": "recording", "id": "8f6c...", "download": true,
 "url": "/api/recordings/audio?id=8f6c...&exp=1790688433&sig=...&download=1",
 "expires_at": "2026-09-29T13:27:13+00:00"}
```

The route looks the recording up before it signs anything. `recording_id` must be a recording of a phone call on an agent the credential can read, in the workspace that agent belongs to; take ids from the `recording` field of a call you can read. An id that does not exist and an id that belongs to another workspace both answer `404 not_found`, identically, and no link is made for either. A recording that was deleted answers `410 gone` with `reason: deleted`, one whose access ended under the workspace's recording security answers `410 gone` with `reason: access_ended`, and a workspace that plays recordings only to its own signed-in members answers any other caller `403 forbidden` with `reason: members_only`; none of them is signed. Every link this route issues is recorded in the workspace's audit log, as the App's are.

`url` is a path on the Sempera App (`https://app.sempera.org`), not on this API ([API overview](https://docs.sempera.org/api-overview.md)). The App checks the link's signature, checks its expiry, and requires a signed-in member of the workspace that owns the recording before it sends any audio. The link carries no access by itself. The audio path answers `410` for a recording that was deleted or whose access ended, and every play is recorded in the workspace's audit log.

The signature is bound to the identity that asked for the link, and only that identity can use it:

| Who asked | Who can play the link |
| - | - |
| A signed-in member, with their App session (the App serves `/v1` on its own origin) | That member, while signed in and still a member of the owning workspace |
| An API key | Nobody. The audio path does not accept an API key (`403`), and a signed-in member presenting a key's link is a different identity (`403`) |

So with an API key this route confirms that a recording exists and is yours, but it does not deliver audio: downloading call audio server to server is not offered. To listen, open the call in the App.

Recording on or off, the retention period, legal holds, how long access lasts and deletion are the workspace owner's settings in the App; no `/v1` route changes them.


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