## Загрузить CRM-документ

`POST /v1/crm-documents/upload`

Прикрепляет к записи CRM готовый файл документа, сформированный вне Битрикс24, без шаблона. Файл передаётся строкой base64, поля — внутри объекта fields.

## Поля запроса (body)

| Поле | Тип | Обяз. | Описание |
|------|-----|:-----:|---------|
| `fields.entityTypeId` | number | да | Тип записи CRM, положительное целое число: `2` — сделка, `3` — контакт, `4` — компания. Остальные типы — в списке «Типы записей CRM» на странице [`GET /v1/crm-documents`](/docs/entities/documents/crm-list) |
| `fields.entityId` | number | да | ID записи, положительное целое число. Источник зависит от типа: сделки — [`GET /v1/deals`](/docs/entities/deals/list), контакты — [`GET /v1/contacts`](/docs/entities/contacts/list), компании — [`GET /v1/companies`](/docs/entities/companies/list) |
| `fields.title` | string | да | Название документа |
| `fields.number` | string | да | Номер документа. Число вместо строки отклоняется |
| `fields.region` | string | да | Регион документа, например `ru` |
| `fields.fileContent` | string | да | Содержимое файла DOCX строкой base64, не больше 2 МиБ после декодирования |
| `fields.pdfContent` | string | нет | PDF-версия документа строкой base64, не больше 2 МиБ после декодирования |
| `fields.imageContent` | string | нет | Изображение документа строкой base64, не больше 2 МиБ после декодирования |

Тело запроса целиком — не больше 3 МиБ. Поля `id`, `fileId`, `pdfId`, `imageId`, `moduleId`, `providerClassName` и `value` заполняет Битрикс24: запрос с любым из них отклоняется с `400 READONLY_FIELD`.

## Примеры

В примерах `contract.docx` — ваш файл документа. Тело запроса собирается в файл `document.json`, затем отправляется.

### curl — личный ключ

```bash
printf '{"fields":{"entityTypeId":2,"entityId":8781,"title":"Договор поставки","number":"VD-1","region":"ru","fileContent":"%s"}}' \
  "$(base64 < contract.docx | tr -d '\n')" > document.json

curl -X POST "https://vibecode.bitrix24.tech/v1/crm-documents/upload" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @document.json
```

### curl — OAuth-приложение

```bash
printf '{"fields":{"entityTypeId":2,"entityId":8781,"title":"Договор поставки","number":"VD-1","region":"ru","fileContent":"%s"}}' \
  "$(base64 < contract.docx | tr -d '\n')" > document.json

curl -X POST "https://vibecode.bitrix24.tech/v1/crm-documents/upload" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @document.json
```

### JavaScript — личный ключ

```javascript
import { readFile } from 'node:fs/promises'

const fileContent = (await readFile('contract.docx')).toString('base64')

const res = await fetch('https://vibecode.bitrix24.tech/v1/crm-documents/upload', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fields: {
      entityTypeId: 2,
      entityId: 8781,
      title: 'Договор поставки',
      number: 'VD-1',
      region: 'ru',
      fileContent,
    },
  }),
})

const { success, data } = await res.json()
console.log('Документ:', data.id)
```

### JavaScript — OAuth-приложение

```javascript
import { readFile } from 'node:fs/promises'

const fileContent = (await readFile('contract.docx')).toString('base64')

const res = await fetch('https://vibecode.bitrix24.tech/v1/crm-documents/upload', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fields: {
      entityTypeId: 2,
      entityId: 8781,
      title: 'Договор поставки',
      number: 'VD-1',
      region: 'ru',
      fileContent,
    },
  }),
})

const { success, data } = await res.json()
```

## Поля ответа

Возвращается HTTP-статус `201 Created` и созданный документ. Полное описание полей документа — на странице [Получить CRM-документ](/docs/entities/documents/crm-get).

| Поле | Тип | Описание |
|------|-----|---------|
| `success` | boolean | Всегда `true` при успехе |
| `data.id` | string | Идентификатор документа |
| `data.title` | string | Название из `fields.title` |
| `data.number` | string | Номер из `fields.number` |
| `data.entityTypeId` | string | Тип записи CRM |
| `data.entityId` | string | ID записи CRM |
| `data.templateId` | string | Служебный шаблон загруженных документов. В списках шаблонов его нет |
| `data.createdBy` | string | ID сотрудника, загрузившего документ. Список: [`GET /v1/users`](/docs/entities/users) |
| `data.downloadUrlMachine` | string | Адрес [`/v1/crm-documents/:id/download`](/docs/entities/documents/download). Нужен `X-Api-Key` со скоупом `crm` |
| `data.pdfUrlMachine` | string | Адрес [`/v1/crm-documents/:id/pdf`](/docs/entities/documents/pdf). Сразу в ответе, если передан `fields.pdfContent` |

## Пример ответа

Показаны основные поля. Полный список: [Получить CRM-документ](/docs/entities/documents/crm-get).

```json
{
  "success": true,
  "data": {
    "downloadUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=crm.documentgenerator.document.download&SITE_ID=s1&id=1985",
    "publicUrl": null,
    "title": "Договор поставки",
    "number": "VD-1",
    "id": "1985",
    "createTime": "2026-10-08T17:59:45+03:00",
    "createdBy": "1317",
    "stampsEnabled": false,
    "isTransformationError": false,
    "templateId": "275",
    "entityId": "8781",
    "entityTypeId": "2",
    "downloadUrlMachine": "https://vibecode.bitrix24.tech/v1/crm-documents/1985/download"
  }
}
```

## Пример ответа при ошибке

400 — `fileContent` не строка base64:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "fileContent must be base64"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `MISSING_REQUIRED_FIELDS` | Нет объекта `fields`. Сообщение: `fields is required` |
| 400 | `MISSING_REQUIRED_FIELDS` | Обязательное поле не передано или пустое. Сообщение называет поля: `Empty required fields: number` |
| 400 | `READONLY_FIELD` | В `fields` передано поле, которое заполняет Битрикс24, например `id` |
| 400 | `INVALID_PARAMS` | `entityTypeId` или `entityId` не положительное целое число |
| 400 | `INVALID_PARAMS` | `title`, `number` или `region` не строка |
| 400 | `INVALID_PARAMS` | `fileContent`, `pdfContent` или `imageContent` не строка base64. Сообщение называет поле |
| 400 | `INVALID_PARAMS` | Тип `entityTypeId` не поддерживается для документов, например `999`. Сообщение: `Wrong "entityTypeId" field value` |
| 413 | `PAYLOAD_TOO_LARGE` | Файл больше 2 МиБ после декодирования. Сообщение называет поле: `fileContent must not exceed 2 MiB` |
| 413 | `PAYLOAD_TOO_LARGE` | Тело запроса больше 3 МиБ. Сообщение: `Request body too large` |
| 429 | `LARGE_BODY_BACKEND_BUSY` | Тело больше 1 МиБ, а платформа уже обрабатывает предельный объём крупных тел. Повторите запрос через `Retry-After` секунд |
| 502 | `BITRIX_INVALID_RESPONSE` | Битрикс24 ответил без документа |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ работает в режиме только для чтения |
| 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `crm` |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `TOKEN_MISSING` | Ключу не сопоставлены токены — ключ OAuth-приложения вызван без пользовательской сессии |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

**Формат файла не проверяется.** Проверяется только то, что `fileContent` — корректная строка base64. Файл сохраняется как передан, даже если это не DOCX, и [скачивание DOCX](/docs/entities/documents/download) вернёт те же байты.

**Существование записи не проверяется.** Документ создаётся и для `entityId`, которого нет среди записей этого типа: ответ `201`, в том числе для контакта — в отличие от [создания по шаблону](/docs/entities/documents/crm-create). Документ, прикреплённый к несуществующему контакту, потом не читается и не удаляется: все методы отвечают `403 BITRIX_ACCESS_DENIED`. Проверяйте запись заранее, например через [`GET /v1/contacts/:id`](/docs/entities/contacts/get).

**PDF без `pdfContent` формируется позже.** Если PDF-версия не передана, PDF формируется из DOCX после загрузки, и до этого скачивание [PDF](/docs/entities/documents/pdf) отвечает `409 DOCUMENT_NOT_READY`.

## Смотрите также

- [Создать CRM-документ](/docs/entities/documents/crm-create)
- [Получить CRM-документ](/docs/entities/documents/crm-get)
- [Документы по CRM-сущности](/docs/entities/documents/crm-list)
- [Скачать DOCX документа](/docs/entities/documents/download)
- [Документы](/docs/entities/documents)
