# Recordings and Transcriptions

> Record Edesy calls per number or application, list and download recordings over signed links, and transcribe audio with the speech-to-text API.

Source: https://edesy.in/docs/voice-api/calls/recordings-and-transcriptions

Turn on recording for a number or an application and every call on it is recorded automatically. Recordings are kept in encrypted cloud storage and served through short-lived signed links, never public URLs. You list them with `GET /v1/recordings`, read one call's recording on the call object, and transcribe audio with `POST /v1/ai/stt`.

## Turn recording on

| Where | How |
|---|---|
| A number | Recording toggle on the number's page, or `PATCH /v1/phone-numbers/{id}` with `{"recording_enabled": true}` |
| An application | `recording_enabled: true` on the application. Applies to inbound calls on its numbers and to outbound calls placed with its `application_id` |
| A campaign | `recording_enabled: true` when you create it |
| A live call | `POST /v1/calls/{CallSid}/recordings/start` |
| Part of a call | The VoiceML [`record`](https://edesy.in/docs/voice-api/calls/voiceml#record) verb, for voicemail-style messages |

Tell callers they are being recorded where the law or your policy requires it, for example with a `say` at the start of the call.

## Recording on the call object

`GET /v1/calls/{CallSid}` includes a `recording` block once a recording exists:

```json
"recording": {
  "recording_sid": "RE_1a2b3c4d-0000-4000-8000",
  "status": "completed",
  "duration": 48,
  "url": "https://voice-api.edesy.in/v1/recordings/RE_1a2b3c4d-0000-4000-8000/media?t=..."
}
```

`url` is present only when the audio can be played, and it expires. Fetch a fresh one when you need it rather than storing it.

## Recording endpoints

| Method | Path | Description |
|---|---|---|
| `GET` | `/v1/recordings` | List recordings. Filters: `call_id`, `status`, `start_date`, `end_date`, `page`, `per_page` |
| `GET` | `/v1/recordings/{RecordingSid}` | One recording |
| `GET` | `/v1/recordings/{RecordingSid}/download` | A short-lived, browser-playable URL for the audio |
| `GET` | `/v1/recordings/{RecordingSid}/media` | The audio itself |
| `POST` | `/v1/recordings/{RecordingSid}/stop` | Stop a recording started with `recordings/start` |
| `DELETE` | `/v1/recordings/{RecordingSid}` | Delete a recording |
| `GET` | `/v1/calls/{CallSid}/recordings` | Recordings of one call |
| `POST` | `/v1/calls/{CallSid}/recordings/start` | Start recording a live call |

`POST /v1/calls/{CallSid}/recordings/start` accepts optional `channels` (`mono` or `dual`), `trim` (`trim-silence` or `do-not-trim`), `status_callback` and `status_callback_method`. It returns `409 CALL_ENDED` if the call is already over.

### The recording object

| Field | Description |
|---|---|
| `recording_sid` | Recording ID, `RE_...` |
| `call_id` | The call it belongs to |
| `kind` | `call` (whole call) or `voicemail` (a `record` capture) |
| `status` | `processing`, `completed`, `failed` or `deleted` |
| `duration` | Seconds |
| `file_size`, `mime_type`, `channels` | File details |
| `transcription_status`, `transcription_text` | Transcript, when one exists |
| `created_at` | When it was created |

## Transcriptions

Send audio to the speech-to-text API and the result is stored as a transcription:

```bash
curl -X POST https://voice-api.edesy.in/v1/ai/stt \
  -H "Authorization: Bearer $EDESY_KEY" \
  -F "audio=@message.wav" \
  -F "language=hi-IN"
```

| Method | Path | Description |
|---|---|---|
| `POST` | `/v1/ai/stt` | Transcribe an uploaded audio file (`audio` form field, optional `language`) |
| `GET` | `/v1/transcriptions` | List transcriptions. Filters: `source`, `source_id`, `status`, `language`, `page`, `per_page` |
| `GET` | `/v1/transcriptions/{id}` | One transcription with `text`, `confidence`, `words` and `segments` |

Transcription `status` is `pending`, `processing`, `completed` or `failed`.

The same AI speech API also offers text-to-speech: `POST /v1/ai/tts`, `POST /v1/ai/tts/stream` and `GET /v1/ai/tts/voices`.
