# Recordings and transcripts

Every conversation an agent holds is transcribed, because transcription is how the agent hears the caller at all. Audio is only kept if you ask for it — and asking has legal consequences worth being deliberate about.

## Transcripts

Available on any call an agent held, with no configuration. Turn by turn, with who said what and when.

`GET /v1/calls/{id}/transcript`

**Shell**

```bash
curl -s https://voice.sphoro.com/v1/calls/$CALL_ID/transcript \
  -H "Authorization: Bearer $SPHORO_API_KEY"
```

**Response200 OK**

```json
{
  "call_id": "call_8b21f4c9a07e3d15",
  "turns": [
    { "role": "agent", "text": "Thanks for calling Acme Clinic. How can I help?", "at": "2026-09-08T09:41:09Z" },
    { "role": "user",  "text": "I need to move my appointment.",                  "at": "2026-09-08T09:41:14Z", "latency_ms": 690 },
    { "role": "agent", "text": "Of course. Which appointment is that?",           "at": "2026-09-08T09:41:15Z" }
  ]
}
```

`latency_ms` on a user turn is the gap between them finishing and the agent starting — the number the [latency budget](https://voice.sphoro.com/docs/latency) is about, per turn rather than averaged.

> **Two kinds of call have no transcript, for the same reason.** A `webrtc` call and a `simple` one both put two people on the line with nothing here listening. Both can be transcribed by setting `transcribe_calls` — which needs the clients to uplink their microphones, and is therefore a decision rather than a default.

## Live, while the call is happening

`call.transcript.updated` fires per line, carrying `role` and `text`, on [webhooks](https://voice.sphoro.com/docs/webhooks) and on the per-call stream:

`GET /v1/calls/{id}/events`

**Shell**

```bash
curl -sN https://voice.sphoro.com/v1/calls/$CALL_ID/events \
  -H "Authorization: Bearer $SPHORO_API_KEY"
```

For a live feed across every call at once, see the [realtime protocol](https://voice.sphoro.com/docs/realtime).

## Recording audio

`PATCH /v1/agents/{id}`

**Shell**

```bash
curl -s -X PATCH https://voice.sphoro.com/v1/agents/$AGENT_ID \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"record_calls": true}'
```

> **Recording is a legal decision before it is a technical one.** Most places require the caller to be told, and several require consent. Put the notice in the greeting — it is one sentence, and it is the sentence that makes the recording usable rather than a liability.

Because of that, recording behaves unlike every other setting in one specific way: an [agent group](https://voice.sphoro.com/docs/agent-groups) can never switch it on for members it already has. It must be adopted per agent, deliberately, by somebody who knows the consent position for that line.

## Fetching the audio

`GET /v1/calls/{id}/recording`

`GET /v1/calls/{id}/recording_url`

**Shell**

```bash
# Straight to a file.
curl -s https://voice.sphoro.com/v1/calls/$CALL_ID/recording \
  -H "Authorization: Bearer $SPHORO_API_KEY" -o call.wav

# Or a short-lived URL, for handing to a browser without proxying the bytes.
curl -s https://voice.sphoro.com/v1/calls/$CALL_ID/recording_url \
  -H "Authorization: Bearer $SPHORO_API_KEY"
```

Wait for `call.recording.ready` rather than polling. It fires when the recording is actually fetchable and carries its duration — a request before that answers `404`, which looks like a call that was never recorded.

> **The URL is short-lived on purpose.** It is a bearer credential for a customer's voice: anybody holding it can play the call. Mint one when somebody asks to listen, rather than storing it alongside the call.

## How long things are kept

| What | Kept |
| --- | --- |
| The call record — times, numbers, end reason, cost | For as long as the account |
| The transcript | With the call record |
| The summary and extractions | With the call record |
| The audio recording | On a retention window agreed with your account |

Retention is set per account rather than per agent, because it is a policy rather than a setting. See [security and data](https://voice.sphoro.com/docs/security), and [talk to us](https://voice.sphoro.com/docs/support) if the default does not match your obligations.

## Getting them out

There is no bulk export endpoint. What there is instead is a list endpoint that pages, and transcripts fetched per call — which is what an export script does anyway:

**Shell**

```bash
curl -s "https://voice.sphoro.com/v1/calls?from=2026-09-01&to=2026-09-30&limit=100" \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
| jq -r '.data[].id' \
| while read -r id; do
    curl -s "https://voice.sphoro.com/v1/calls/$id/transcript" \
      -H "Authorization: Bearer $SPHORO_API_KEY" > "transcripts/$id.json"
  done
```

Pagination is covered on [using your API key](https://voice.sphoro.com/docs/authentication).
