## Call recording

`POST /v1/calls/:callId/record`

Attaches an audio recording to a completed external telephony call. Pass the file in the request body as base64 or as a link to a public HTTPS URL.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|-------|----------|
| `callId` (path) | string | yes | ID of a completed call — the `data.callId` field from [call registration](/docs/telephony/crm/register). To complete a call, use [`POST /v1/calls/:callId/finish`](/docs/telephony/crm/finish) |

## Request fields (body)

Pass either `fileContent` or `recordUrl`, not both.

| Field | Type | Required | Description |
|------|-----|-------|----------|
| `fileContent` | string | no | Audio file in base64. Required if `recordUrl` is not passed. Up to 2 MiB after decoding; an empty file is not accepted |
| `recordUrl` | string | no | Public HTTPS URL of the recording file. Required if `fileContent` is not passed. The URL must not contain a login, password or access tokens and must not point to an internal network |
| `fileName` | string | no | File name with a lowercase `.mp3` or `.wav` extension. Required together with `fileContent`. With `recordUrl`, the last segment of the URL path is used by default |

## Examples

### curl — personal key

```bash
curl -X POST 'https://vibecode.bitrix24.com/v1/calls/externalCall.00000000000000000000000000000000.1700000000/record' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"fileName":"record.wav","fileContent":"UklGRjQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YRAAAAAAAAAAAAAAAAAAAAAAAAAA"}'
```

### curl — OAuth application

```bash
curl -X POST 'https://vibecode.bitrix24.com/v1/calls/externalCall.00000000000000000000000000000000.1700000000/record' \
  -H 'X-Api-Key: YOUR_APP_KEY' \
  -H 'Authorization: Bearer USER_SESSION_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"fileName":"record.wav","fileContent":"UklGRjQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YRAAAAAAAAAAAAAAAAAAAAAAAAAA"}'
```

### JavaScript — personal key

```javascript
const callId = 'externalCall.00000000000000000000000000000000.1700000000';
const response = await fetch(`https://vibecode.bitrix24.com/v1/calls/${callId}/record`, {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fileName: 'record.wav',
    fileContent: 'UklGRjQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YRAAAAAAAAAAAAAAAAAAAAAAAAAA',
  }),
});
const { data } = await response.json();
console.log(data.fileId);
```

### JavaScript — OAuth application

```javascript
const callId = 'externalCall.00000000000000000000000000000000.1700000000';
const response = await fetch(`https://vibecode.bitrix24.com/v1/calls/${callId}/record`, {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fileName: 'record.wav',
    fileContent: 'UklGRjQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YRAAAAAAAAAAAAAAAAAAAAAAAAAA',
  }),
});
const { data } = await response.json();
console.log(data.fileId);
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` on success |
| `data` | object | Operation result |
| `data.fileId` | integer | ID of the recording file attached to the call |

## Response example

```json
{
  "success": true,
  "data": {
    "fileId": 10209
  }
}
```

## Error response example

422 — a call with this `callId` is not found or has not ended yet:

```json
{
  "success": false,
  "error": {
    "code": "BITRIX_ERROR",
    "message": "Call is not found in the statistic table. Looks like it is not finished yet."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `INVALID_PARAMS` | The request body is not a JSON object |
| 400 | `INVALID_PARAMS` | Both `recordUrl` and `fileContent` are passed, or `recordUrl` is empty |
| 400 | `INVALID_PARAMS` | `recordUrl` is not an HTTPS URL, contains credentials or points to an internal network |
| 400 | `INVALID_PARAMS` | `fileContent` is not base64 or the file is empty |
| 400 | `INVALID_PARAMS` | `fileName` does not end in `.mp3` or `.wav` |
| 400 | `INVALID_PARAMS` | Bitrix24 rejected the parameter value |
| 400 | `MISSING_REQUIRED_FIELDS` | `recordUrl` is not passed, and `fileContent` or `fileName` is missing |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is missing |
| 401 | `INVALID_API_KEY` | The key is not found or has been revoked |
| 401 | `TOKEN_MISSING` | The key has no portal tokens. An OAuth application key requires the `Authorization: Bearer` header |
| 403 | `SCOPE_DENIED` | The key has no `telephony` scope |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is read-only |
| 403 | `BITRIX_ACCESS_DENIED` | Bitrix24 denied access. For possible causes, see [Authorization, keys and permissions](/docs/errors/auth#bitrix_access_denied-403) |
| 404 | `ENTITY_NOT_FOUND` | Bitrix24 reported that the object was not found |
| 413 | `PAYLOAD_TOO_LARGE` | The file exceeds 2 MiB after decoding, or the request body exceeds 3 MiB |
| 422 | `BITRIX_ERROR` | A call with this `callId` is not found or has not ended yet |
| 422 | `BITRIX_ERROR` | Bitrix24 did not return the recording file ID |
| 429 | `LARGE_BODY_BACKEND_BUSY` | The server is processing other requests with a large body. Retry the request after a delay |
| 429 | `RATE_LIMITED` | Request rate exceeded on the Bitrix24 side |
| 502 | `BITRIX_UNAVAILABLE` | Bitrix24 is unavailable |
| 503 | `BITRIX_TIMEOUT` | Bitrix24 did not respond in time |

The full list of common API errors — [Error codes](/docs/errors).

## See also

- [Calls](/docs/calls)
- [Register a call](/docs/telephony/crm/register)
- [CRM cards by phone](/docs/calls/crm-entities)
- [Error codes](/docs/errors)
