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

# Call Recording

Two endpoints are available for accessing call recordings:

1. **Stream endpoint** - Returns a JSON object with a presigned URL for browser-native streaming
2. **Download endpoint** - Returns the binary audio file for download

***

## Stream Recording

Get a presigned URL for streaming the call recording in a browser.

### Endpoint

`GET /api/calls/{call_sid}/recording/stream`

### Path Parameters

<ParamField path="call_sid" type="string" required>
  The unique identifier of the call (format: `call_` prefix + alphanumeric).
</ParamField>

### Response

Returns a JSON object containing a presigned S3 URL that can be used directly with an HTML5 audio element.

<ResponseField name="success" type="boolean">
  Indicates if the request was successful.
</ResponseField>

<ResponseField name="data" type="object">
  Recording URL data.
</ResponseField>

<ResponseField name="data.url" type="string" required>
  Presigned S3 URL for accessing the recording. Expires after 1 hour.
</ResponseField>

<ResponseField name="data.expires_in" type="number" required>
  URL expiration time in seconds (3600 = 1 hour).
</ResponseField>

<ResponseField name="data.content_type" type="string" required>
  Content type of the recording (e.g., `audio/wav`, `audio/mpeg`).
</ResponseField>

<ResponseField name="data.filename" type="string" required>
  Suggested filename for the recording.
</ResponseField>

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "url": "https://bucket.s3.amazonaws.com/recordings/call_abc123.wav?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
      "expires_in": 3600,
      "content_type": "audio/wav",
      "filename": "recording_+15559876543.wav"
    }
  }
  ```
</ResponseExample>

<Note>
  The presigned URL supports HTTP range requests, allowing the browser to stream
  the audio file without downloading the entire file first. Use this endpoint
  for playback in audio players.
</Note>

***

## Download Recording

Download the recording as a binary audio file.

### Endpoint

`GET /api/calls/{call_sid}/recording/download`

### Path Parameters

<ParamField path="call_sid" type="string" required>
  The unique identifier of the call (format: `call_` prefix + alphanumeric).
</ParamField>

### Response

Returns the audio file as a binary stream with appropriate headers for download.

<ResponseField name="Content-Type" type="string">
  `audio/wav`
</ResponseField>

<ResponseField name="Content-Disposition" type="string">
  `attachment; filename="recording_{to_number}.wav"`
</ResponseField>

<ResponseField name="Content-Length" type="number">
  Size of the audio file in bytes.
</ResponseField>

<ResponseExample>
  ```
  HTTP/1.1 200 OK
  Content-Type: audio/wav
  Content-Disposition: attachment; filename="recording_+15559876543.wav"
  Content-Length: 1924506

  [Binary WAV data...]
  ```
</ResponseExample>

<Note>
  This endpoint returns binary audio data, not JSON. The presigned URL used
  internally expires after 5 minutes. Use this endpoint when you want to save
  the recording to disk.
</Note>

***

## Comparison

| Feature           | Stream Endpoint     | Download Endpoint     |
| ----------------- | ------------------- | --------------------- |
| Endpoint          | `/recording/stream` | `/recording/download` |
| Response Type     | JSON                | Binary (WAV)          |
| Content-Type      | `application/json`  | `audio/wav`           |
| URL Expiration    | 1 hour              | 5 minutes             |
| Use Case          | Browser streaming   | File download         |
| Supports Seeking  | Yes                 | No                    |
| Must Download All | No                  | Yes                   |

***

## Frontend Usage Examples

### Streaming (for playback)

```typescript theme={null}
// Get presigned URL
const response = await fetch(`/api/calls/${callSid}/recording/stream`, {
  headers: { 'X-Organization-Id': 'org_123' }
});
const { data } = await response.json();

// Use with HTML5 Audio element
const audio = new Audio(data.url);
audio.play();
```

### Download (for saving)

```typescript theme={null}
// Fetch binary data
const response = await fetch(`/api/calls/${callSid}/recording/download`, {
  headers: { 'X-Organization-Id': 'org_123' }
});
const blob = await response.blob();

// Create download link
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `recording_${toNumber}.wav`;
a.click();
window.URL.revokeObjectURL(url);
```
