[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-entities\u002Finvoices":3,"docs-tabs-entities\u002Finvoices":6},{"content":4,"lastmod":5},"# Счета\n\nУправление счетами CRM: создание, получение, обновление, удаление, фильтрация.\n\nBitrix24 API: `crm.item.*` (SPA-сущность, entityTypeId = 31)\nСкоуп: `crm`\n\n## Операции\n\n- [Создать счёт](.\u002Finvoices\u002Fcreate.md) — `POST \u002Fv1\u002Finvoices`\n- [Список счетов](.\u002Finvoices\u002Flist.md) — `GET \u002Fv1\u002Finvoices`\n- [Получить счёт](.\u002Finvoices\u002Fget.md) — `GET \u002Fv1\u002Finvoices\u002F:id`\n- [Обновить счёт](.\u002Finvoices\u002Fupdate.md) — `PATCH \u002Fv1\u002Finvoices\u002F:id`\n- [Удалить счёт](.\u002Finvoices\u002Fdelete.md) — `DELETE \u002Fv1\u002Finvoices\u002F:id`\n- [Поиск счетов](.\u002Finvoices\u002Fsearch.md) — `POST \u002Fv1\u002Finvoices\u002Fsearch`\n- [Поля счёта](.\u002Finvoices\u002Ffields.md) — `GET \u002Fv1\u002Finvoices\u002Ffields`\n- [Агрегация счетов](.\u002Finvoices\u002Faggregate.md) — `POST \u002Fv1\u002Finvoices\u002Faggregate`\n- [Получить товары](.\u002Finvoices\u002Fproducts-get.md) — `GET \u002Fv1\u002Finvoices\u002F:id\u002Fproducts`\n- [Установить товары](.\u002Finvoices\u002Fproducts-set.md) — `PUT \u002Fv1\u002Finvoices\u002F:id\u002Fproducts`\n- [Добавить товар](.\u002Finvoices\u002Fproducts-add.md) — `POST \u002Fv1\u002Finvoices\u002F:id\u002Fproducts`\n- [Удалить товар](.\u002Finvoices\u002Fproducts-delete.md) — `DELETE \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002F:rowId`\n- [Получить товар](.\u002Finvoices\u002Fproducts-get-single.md) — `GET \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002F:rowId`\n- [Обновить товар](.\u002Finvoices\u002Fproducts-update.md) — `PATCH \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002F:rowId`\n- [Поля товаров](.\u002Finvoices\u002Fproducts-fields.md) — `GET \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002Ffields`\n","2026-06-11",{"invoices\u002Fcreate.md":7,"invoices\u002Flist.md":8,"invoices\u002Fget.md":9,"invoices\u002Fupdate.md":10,"invoices\u002Fdelete.md":11,"invoices\u002Fsearch.md":12,"invoices\u002Ffields.md":13,"invoices\u002Faggregate.md":14,"invoices\u002Fproducts-get.md":15,"invoices\u002Fproducts-set.md":16,"invoices\u002Fproducts-add.md":17,"invoices\u002Fproducts-delete.md":18,"invoices\u002Fproducts-get-single.md":19,"invoices\u002Fproducts-update.md":20,"invoices\u002Fproducts-fields.md":21},"\n## Создать счёт\n\n`POST \u002Fv1\u002Finvoices`\n\nСоздаёт новый счёт в CRM.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `title` | string | Название счёта |\n| `stageId` | string | Стадия. Формат: `DT31_{categoryId}:{stage}`. Список стадий: `GET \u002Fv1\u002Fstatuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId зависит от портала. Узнать: `GET \u002Fv1\u002Finvoices?limit=1&select=categoryId` или запросить у администратора |\n| `categoryId` | number | ID воронки |\n| `contactId` | number | ID контакта-плательщика. Поиск: `GET \u002Fv1\u002Fcontacts` |\n| `companyId` | number | ID компании-плательщика. Поиск: `GET \u002Fv1\u002Fcompanies` |\n| `mycompanyId` | number | ID своей компании |\n| `opportunity` | number | Сумма счёта |\n| `currencyId` | string | Валюта. Список: `GET \u002Fv1\u002Fcurrencies` |\n| `assignedById` | number | Ответственный. Список: `GET \u002Fv1\u002Fusers` |\n| `comments` | string | Комментарий |\n\nПолный список полей: [GET \u002Fv1\u002Finvoices\u002Ffields](\u002Fdocs\u002Fentities\u002Finvoices\u002Ffields). Пользовательские поля (`ufCrm_*`) также принимаются.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"title\": \"Счёт за услуги\",\n    \"stageId\": \"DT31_5:N\",\n    \"contactId\": 42,\n    \"companyId\": 15,\n    \"opportunity\": 150000,\n    \"currencyId\": \"RUB\",\n    \"assignedById\": 1\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"title\": \"Счёт за услуги\",\n    \"stageId\": \"DT31_5:N\",\n    \"contactId\": 42,\n    \"companyId\": 15,\n    \"opportunity\": 150000,\n    \"currencyId\": \"RUB\",\n    \"assignedById\": 1\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    title: 'Счёт за услуги',\n    stageId: 'DT31_5:N',\n    contactId: 42,\n    companyId: 15,\n    opportunity: 150000,\n    currencyId: 'RUB',\n    assignedById: 1,\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Invoice ID:', data.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    title: 'Счёт за услуги',\n    stageId: 'DT31_5:N',\n    contactId: 42,\n    companyId: 15,\n    opportunity: 150000,\n    currencyId: 'RUB',\n    assignedById: 1,\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `id` | number | ID созданного счёта |\n| `title` | string | Название |\n| `stageId` | string | Стадия |\n| `contactId` | number | ID контакта |\n| `companyId` | number | ID компании |\n| `opportunity` | number | Сумма |\n| `currencyId` | string | Валюта |\n| `assignedById` | number | Ответственный |\n| `createdBy` | number | Создатель |\n| `createdTime` | datetime | Дата создания |\n| `updatedTime` | datetime | Дата изменения |\n\nОтвет содержит все поля счёта, включая пользовательские (`ufCrm_*`).\n\nURL карточки счёта в Битрикс24 строится из `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcrm\u002Ftype\u002F31\u002Fdetails\u002F\u003Cid>\u002F\n```\n\n`31` — `entityTypeId` смарт-счёта в Битрикс24. `\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 891,\n    \"title\": \"Счёт за услуги\",\n    \"stageId\": \"DT31_5:N\",\n    \"categoryId\": 5,\n    \"contactId\": 42,\n    \"companyId\": 15,\n    \"opportunity\": 150000,\n    \"currencyId\": \"RUB\",\n    \"assignedById\": 1,\n    \"createdBy\": 1,\n    \"createdTime\": \"2026-04-15T14:30:00+03:00\",\n    \"updatedTime\": \"2026-04-15T14:30:00+03:00\"\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n403 — нет скоупа:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SCOPE_DENIED\",\n    \"message\": \"This endpoint requires 'crm' scope\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 400 | `INVALID_REQUEST` | Невалидные поля |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Работа с файлами в полях CRM](\u002Fdocs\u002Frecipes\u002Fcrm-files)\n- [Список счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Flist) — получение с фильтрами\n- [Поля счёта](\u002Fdocs\u002Fentities\u002Finvoices\u002Ffields) — полный список полей\n- [Контакты](\u002Fdocs\u002Fentities\u002Fcontacts) — привязка через `contactId`\n- [Компании](\u002Fdocs\u002Fentities\u002Fcompanies) — привязка через `companyId`\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы\n","\n## Список счетов\n\n`GET \u002Fv1\u002Finvoices`\n\nВозвращает список счетов с фильтрацией, сортировкой и пагинацией.\n\n## Параметры\n\n| Параметр | Тип | По умолч. | Описание |\n|----------|-----|-----------|---------|\n| `limit` | number | `50` | Количество записей (до 5000) |\n| `offset` | number | `0` | Пропустить N записей |\n| `order` | object | — | Сортировка: `?order[createdTime]=desc` |\n| `select` | string | — | Выборка полей: `?select=id,title,stageId` |\n| `filter` | object | — | Фильтрация по полям `GET \u002Fv1\u002Finvoices\u002Ffields`.\u003Cbr>[Синтаксис фильтрации](\u002Fdocs\u002Ffiltering). Пример: `?filter[stageId]=DT31_5:N` |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X GET \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices?limit=10&sort=-createdTime&filter[stageId]=DT31_5:N\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X GET \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices?limit=10&sort=-createdTime&filter[stageId]=DT31_5:N\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst params = new URLSearchParams({\n  limit: '10',\n  sort: '-createdTime',\n  'filter[stageId]': 'DT31_5:N',\n})\n\nconst res = await fetch(`https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices?${params}`, {\n  headers: { 'X-Api-Key': 'YOUR_API_KEY' },\n})\n\nconst { success, data, total } = await res.json()\nconsole.log(`Найдено: ${total}`)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst params = new URLSearchParams({\n  limit: '10',\n  sort: '-createdTime',\n  'filter[stageId]': 'DT31_5:N',\n})\n\nconst res = await fetch(`https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices?${params}`, {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data, total } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data` | array | Массив счетов |\n| `total` | number | Общее количество записей |\n| `data[].id` | number | ID счёта |\n| `data[].title` | string | Название |\n| `data[].stageId` | string | Стадия |\n| `data[].opportunity` | number | Сумма |\n| `data[].currencyId` | string | Валюта |\n| `data[].contactId` | number | ID контакта |\n| `data[].companyId` | number | ID компании |\n| `data[].assignedById` | number | Ответственный |\n| `data[].createdTime` | datetime | Дата создания |\n\nURL карточки любого счёта из массива `data` — его `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcrm\u002Ftype\u002F31\u002Fdetails\u002F\u003Cid>\u002F\n```\n\n`31` — `entityTypeId` смарт-счёта в Битрикс24. `\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 891,\n      \"title\": \"Счёт за услуги\",\n      \"stageId\": \"DT31_5:N\",\n      \"categoryId\": 5,\n      \"contactId\": 42,\n      \"companyId\": 15,\n      \"opportunity\": 150000,\n      \"currencyId\": \"RUB\",\n      \"assignedById\": 1,\n      \"createdBy\": 1,\n      \"createdTime\": \"2026-04-15T14:30:00+03:00\",\n      \"updatedTime\": \"2026-04-15T14:30:00+03:00\"\n    }\n  ],\n  \"total\": 47\n}\n```\n\n## Пример ответа при ошибке\n\n403 — нет скоупа:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SCOPE_DENIED\",\n    \"message\": \"This endpoint requires 'crm' scope\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Получить счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fget) — получение по ID с include\n- [Поиск счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Fsearch) — расширенный поиск с датами\n- [Поля счёта](\u002Fdocs\u002Fentities\u002Finvoices\u002Ffields) — полный список полей\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Получить счёт\n\n`GET \u002Fv1\u002Finvoices\u002F:id`\n\nВозвращает счёт по ID. Поддерживает включение связанных сущностей через `include`.\n\n## Параметры запроса\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `id` | number | ID счёта (в URL) |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X GET \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X GET \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891', {\n  headers: { 'X-Api-Key': 'YOUR_API_KEY' },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Получено:', data.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\nПодробнее об include: [Связанные данные](\u002Fdocs\u002Fincludes).\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `id` | number | ID счёта |\n| `title` | string | Название |\n| `stageId` | string | Стадия |\n| `categoryId` | number | ID воронки |\n| `contactId` | number | ID контакта |\n| `companyId` | number | ID компании |\n| `opportunity` | number | Сумма |\n| `currencyId` | string | Валюта |\n| `assignedById` | number | Ответственный |\n| `createdBy` | number | Создатель |\n| `createdTime` | datetime | Дата создания |\n| `updatedTime` | datetime | Дата изменения |\n| `_included` | object | Связанные сущности (при `include`) |\n\n## Связанные данные\n\n (include)\n\n```\nGET \u002Fv1\u002Finvoices\u002F1?include=contact,company\n```\n\nДоступные include: `contact`, `company`. Результат в поле `_included`.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 891,\n    \"title\": \"Счёт за услуги\",\n    \"stageId\": \"DT31_5:N\",\n    \"categoryId\": 5,\n    \"contactId\": 42,\n    \"companyId\": 15,\n    \"opportunity\": 150000,\n    \"currencyId\": \"RUB\",\n    \"assignedById\": 1,\n    \"createdBy\": 1,\n    \"createdTime\": \"2026-04-15T14:30:00+03:00\",\n    \"updatedTime\": \"2026-04-15T14:30:00+03:00\",\n    \"_included\": {\n      \"contact\": {\n        \"id\": 42,\n        \"name\": \"Иван\",\n        \"lastName\": \"Петров\"\n      },\n      \"company\": {\n        \"id\": 15,\n        \"title\": \"ООО Ромашка\"\n      }\n    }\n  }\n}\n```\n\n\n## Пример ответа при ошибке\n\n404 — счёт не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"NOT_FOUND\",\n    \"message\": \"Entity not found\"\n  }\n}\n```\n\nПодробнее об include: [Связанные данные](\u002Fdocs\u002Fincludes).\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `NOT_FOUND` | Счёт с указанным ID не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Работа с файлами в полях CRM](\u002Fdocs\u002Frecipes\u002Fcrm-files)\n- [Список счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Flist) — получение с фильтрами\n- [Обновить счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fupdate) — изменение полей\n- [Контакты](\u002Fdocs\u002Fentities\u002Fcontacts) — данные контакта через `include`\n- [Компании](\u002Fdocs\u002Fentities\u002Fcompanies) — данные компании через `include`\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы\n","\n## Обновить счёт\n\n`PATCH \u002Fv1\u002Finvoices\u002F:id`\n\nОбновляет поля счёта. Передавайте только изменяемые поля.\n\n## Параметры запроса\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `id` | number | ID счёта (в URL) |\n\n## Поля запроса (body)\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `title` | string | Название счёта |\n| `stageId` | string | Стадия. Формат: `DT31_{categoryId}:{stage}`. Список стадий: `GET \u002Fv1\u002Fstatuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId зависит от портала. Узнать: `GET \u002Fv1\u002Finvoices?limit=1&select=categoryId` или запросить у администратора |\n| `contactId` | number | ID контакта-плательщика |\n| `companyId` | number | ID компании-плательщика |\n| `opportunity` | number | Сумма |\n| `currencyId` | string | Валюта. Список: `GET \u002Fv1\u002Fcurrencies` |\n| `assignedById` | number | Ответственный. Список: `GET \u002Fv1\u002Fusers` |\n| `comments` | string | Комментарий |\n\nПолный список полей: [GET \u002Fv1\u002Finvoices\u002Ffields](\u002Fdocs\u002Fentities\u002Finvoices\u002Ffields). Пользовательские поля (`ufCrm_*`) также принимаются.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X PATCH https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891 \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"opportunity\": 200000,\n    \"stageId\": \"DT31_5:WON\"\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X PATCH https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891 \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"opportunity\": 200000,\n    \"stageId\": \"DT31_5:WON\"\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    opportunity: 200000,\n    stageId: 'DT31_5:WON',\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Обновлён:', data.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    opportunity: 200000,\n    stageId: 'DT31_5:WON',\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `id` | number | ID счёта |\n| `title` | string | Название |\n| `stageId` | string | Стадия |\n| `opportunity` | number | Сумма |\n| `currencyId` | string | Валюта |\n| `assignedById` | number | Ответственный |\n| `updatedTime` | datetime | Дата изменения |\n\nОтвет содержит все поля счёта после обновления.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 891,\n    \"title\": \"Счёт за услуги\",\n    \"stageId\": \"DT31_5:WON\",\n    \"categoryId\": 5,\n    \"contactId\": 42,\n    \"companyId\": 15,\n    \"opportunity\": 200000,\n    \"currencyId\": \"RUB\",\n    \"assignedById\": 1,\n    \"createdBy\": 1,\n    \"createdTime\": \"2026-04-15T14:30:00+03:00\",\n    \"updatedTime\": \"2026-04-15T15:10:00+03:00\"\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n404 — счёт не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"NOT_FOUND\",\n    \"message\": \"Entity not found\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `NOT_FOUND` | Счёт с указанным ID не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 400 | `INVALID_REQUEST` | Невалидные поля |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Работа с файлами в полях CRM](\u002Fdocs\u002Frecipes\u002Fcrm-files)\n- [Получить счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fget) — получение по ID\n- [Поля счёта](\u002Fdocs\u002Fentities\u002Finvoices\u002Ffields) — полный список полей\n- [Создать счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fcreate) — создание нового счёта\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы\n","\n## Удалить счёт\n\n`DELETE \u002Fv1\u002Finvoices\u002F:id`\n\nУдаляет счёт по ID. Восстановить удалённый счёт через API нельзя — создавайте новый при необходимости.\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID счёта |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X DELETE \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X DELETE \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891', {\n  method: 'DELETE',\n  headers: { 'X-Api-Key': 'YOUR_API_KEY' },\n})\n\nif (res.status === 204) {\n  console.log('Счёт удалён')\n}\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F891', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nif (res.status === 204) {\n  console.log('Удалено')\n}\n```\n\n## Ответ\n\nПри успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу.\n\n## Пример ответа\n\n```\nHTTP\u002F1.1 204 No Content\n```\n\n## Пример ответа при ошибке\n\n404 — счёт не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Счёт с указанным ID не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Список счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Flist) — получение с фильтрами\n- [Создать счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fcreate) — создание нового счёта\n- [Batch](\u002Fdocs\u002Fbatch) — массовое удаление\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Поиск счетов\n\n`POST \u002Fv1\u002Finvoices\u002Fsearch`\n\nРасширенный поиск счетов с фильтрацией, сортировкой и авто-пагинацией. Поддерживает до 5000 записей.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `filter` | object | Фильтрация по полям `GET \u002Fv1\u002Finvoices\u002Ffields`.\u003Cbr>[Синтаксис фильтрации](\u002Fdocs\u002Ffiltering). Пример: `?filter[stageId]=DT31_5:N` |\n| `sort` | string | Сортировка. Префикс `-` — по убыванию |\n| `limit` | number | Количество записей (по умолчанию 50, макс. 5000) |\n| `select` | array | Список возвращаемых полей |\n| `autoWindow` | boolean | Авто-разбивка по датам (по умолчанию `true`) |\n\n### Синтаксис фильтров\n\nПоддерживаются три формата:\n\n```json\n{ \"filter\": { \">=opportunity\": 100000 } }\n{ \"filter\": { \"opportunity\": { \"$gte\": 100000 } } }\n{ \"filter\": { \"opportunity\": { \">=\": 100000 } } }\n```\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Fsearch \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"filter\": {\n      \">=opportunity\": 100000,\n      \"assignedById\": 1\n    },\n    \"sort\": \"-createdTime\",\n    \"limit\": 100\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Fsearch \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"filter\": {\n      \">=opportunity\": 100000,\n      \"assignedById\": 1\n    },\n    \"sort\": \"-createdTime\",\n    \"limit\": 100\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Fsearch', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    filter: { '>=opportunity': 100000, assignedById: 1 },\n    sort: '-createdTime',\n    limit: 100,\n  }),\n})\n\nconst { success, data, total } = await res.json()\nconsole.log(`Найдено: ${total}`)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Fsearch', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    filter: { '>=opportunity': 100000, assignedById: 1 },\n    sort: '-createdTime',\n    limit: 100,\n  }),\n})\n\nconst { success, data, total } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data` | array | Массив счетов |\n| `total` | number | Общее количество |\n\nURL карточки любого счёта из массива `data` — его `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcrm\u002Ftype\u002F31\u002Fdetails\u002F\u003Cid>\u002F\n```\n\n`31` — `entityTypeId` смарт-счёта в Битрикс24. `\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 891,\n      \"title\": \"Счёт за услуги\",\n      \"stageId\": \"DT31_5:N\",\n      \"opportunity\": 150000,\n      \"currencyId\": \"RUB\",\n      \"assignedById\": 1,\n      \"createdTime\": \"2026-04-15T14:30:00+03:00\"\n    }\n  ],\n  \"total\": 12\n}\n```\n\n## Пример ответа при ошибке\n\n403 — нет скоупа:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SCOPE_DENIED\",\n    \"message\": \"This endpoint requires 'crm' scope\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 400 | `INVALID_REQUEST` | Невалидный фильтр или параметры |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Список счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Flist) — простое получение с фильтрами\n- [Поля счёта](\u002Fdocs\u002Fentities\u002Finvoices\u002Ffields) — полный список полей\n- [Пакетные запросы](\u002Fdocs\u002Fbatch) — поиск через batch\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы\n","\n## Поля счёта\n\n`GET \u002Fv1\u002Finvoices\u002Ffields`\n\nВозвращает описание всех полей счёта, включая пользовательские (`ufCrm_*`).\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X GET https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Ffields \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X GET https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Ffields \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Ffields', {\n  headers: { 'X-Api-Key': 'YOUR_API_KEY' },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Полей:', Object.keys(data).length)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Ffields', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Только чтение | Описание |\n|------|-----|:---:|---------|\n| `id` | number | да | ID счёта |\n| `title` | string | | Название |\n| `stageId` | string | | Стадия. Формат: `DT31_{categoryId}:{stage}`. Список стадий: `GET \u002Fv1\u002Fstatuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId зависит от портала. Узнать: `GET \u002Fv1\u002Finvoices?limit=1&select=categoryId` или запросить у администратора |\n| `categoryId` | number | | ID воронки |\n| `contactId` | number | | ID контакта-плательщика. Поиск: `GET \u002Fv1\u002Fcontacts` |\n| `companyId` | number | | ID компании-плательщика. Поиск: `GET \u002Fv1\u002Fcompanies` |\n| `mycompanyId` | number | | ID своей компании |\n| `opportunity` | number | | Сумма |\n| `currencyId` | string | | Валюта. Список: `GET \u002Fv1\u002Fcurrencies` |\n| `assignedById` | number | | Ответственный. Список: `GET \u002Fv1\u002Fusers` |\n| `createdBy` | number | да | ID создателя |\n| `createdTime` | datetime | да | Дата создания |\n| `updatedTime` | datetime | да | Дата изменения |\n\nПользовательские поля (`ufCrm_*`) возвращаются в ответе и доступны для записи.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"fields\": {\n      \"id\": { \"type\": \"number\", \"readonly\": true },\n      \"title\": { \"type\": \"string\", \"readonly\": false },\n      \"assignedById\": { \"type\": \"number\", \"readonly\": false }\n    },\n    \"batch\": [\"create\", \"update\", \"delete\"]\n  }\n}\n```\n\nПоказаны 3 из множества полей. Полный список в таблице выше.\n\n## Доступные include\n\nЭндпоинт `GET \u002Fv1\u002Finvoices\u002Ffields` возвращает список доступных include: `contact`, `company`.\n\nПример использования: [Получить invoices](\u002Fdocs\u002Fentities\u002Finvoices\u002Fget#связанные-данные).\n\nПодробнее об include: [Связанные данные](\u002Fdocs\u002Fincludes).\n\n## Пример ответа при ошибке\n\n404 — не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Создать счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fcreate) — создание с полями\n- [Список счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Flist) — фильтрация по полям\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы\n","\n## Агрегация счетов\n\n`POST \u002Fv1\u002Finvoices\u002Faggregate`\n\nПодсчёт количества, сумма, среднее, минимум и максимум по счетам с фильтрацией и группировкой.\n\n**Стандартные поля:**\n\n- `opportunity` — сумма счёта (числовое агрегирование имеет смысл)\n- `stageId` — стадия (для `groupBy`)\n- `assignedById` — ответственный (для `groupBy`)\n\n**Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ \"field\": \"opportunity\", \"function\": \"sum\" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Для `count` поле — `\"*\"`. Без массива — только `count` |\n| `filter` | object | нет | Фильтрация по полям `GET \u002Fv1\u002Finvoices\u002Ffields`. [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering) |\n| `groupBy` | string \\| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Faggregate\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"aggregate\": [\n      { \"field\": \"opportunity\", \"function\": \"sum\" },\n      { \"field\": \"opportunity\", \"function\": \"avg\" }\n    ],\n    \"filter\": { \"assignedById\": 1 },\n    \"groupBy\": \"stageId\"\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Faggregate\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"aggregate\": [\n      { \"field\": \"opportunity\", \"function\": \"sum\" },\n      { \"field\": \"opportunity\", \"function\": \"avg\" }\n    ],\n    \"filter\": { \"assignedById\": 1 },\n    \"groupBy\": \"stageId\"\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Faggregate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    aggregate: [\n      { field: 'opportunity', function: 'sum' },\n      { field: 'opportunity', function: 'avg' },\n    ],\n    filter: { assignedById: 1 },\n    groupBy: 'stageId',\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Всего счетов:', data.count)\nconsole.log('По стадиям:', data.groups)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002Faggregate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    aggregate: [\n      { field: 'opportunity', function: 'sum' },\n      { field: 'opportunity', function: 'avg' },\n    ],\n    filter: { assignedById: 1 },\n    groupBy: 'stageId',\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n> Для группировки по нескольким полям передайте массив: `\"groupBy\": [\"stageId\", \"assignedById\"]` (максимум 5).\n\n## Другие сценарии\n\nПодсчёт записей — `count` с полем `\"*\"`, самый быстрый запрос без выгрузки записей. Без массива `aggregate` результат тот же:\n\n```json\n{ \"aggregate\": [{ \"field\": \"*\", \"function\": \"count\" }] }\n```\n\nРабота с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF:\n\n```json\n{\n  \"aggregate\": [{ \"field\": \"UF_CRM_TAX\", \"function\": \"sum\" }],\n  \"groupBy\": \"UF_CRM_PAYMENT_METHOD\"\n}\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data.count` | number | Общее количество записей под фильтр |\n| `data.aggregates` | object | Результаты агрегаций: `{ \"opportunity\": { \"sum\": 120000, \"avg\": 2200 } }` |\n| `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` |\n| `data.meta.totalRecords` | number | Общее количество записей под фильтр |\n| `data.meta.recordsProcessed` | number | Сколько записей обработано для числовых агрегаций (максимум 5000) |\n| `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей |\n\n## Пример ответа\n\nОтвет на основной запрос (агрегации + `groupBy: \"stageId\"`):\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"count\": 55,\n    \"aggregates\": {\n      \"opportunity\": { \"sum\": 120000, \"avg\": 2200 }\n    },\n    \"groups\": [\n      {\n        \"stageId\": \"DT31_5:N\",\n        \"count\": 30,\n        \"aggregates\": { \"opportunity\": { \"sum\": 70000 } }\n      },\n      {\n        \"stageId\": \"DT31_5:P\",\n        \"count\": 25,\n        \"aggregates\": { \"opportunity\": { \"sum\": 50000 } }\n      }\n    ],\n    \"meta\": {\n      \"totalRecords\": 55,\n      \"recordsProcessed\": 55,\n      \"truncated\": false\n    }\n  }\n}\n```\n\nБез `groupBy` поле `data.groups` в ответе отсутствует.\n\n## Пример ответа при ошибке\n\n400 — неверное имя функции, несуществующее поле или `groupBy` по неаггрегируемому полю:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INVALID_PARAMS\",\n    \"message\": \"Field 'foo' not found. Available numeric fields: opportunity, stageId, assignedById\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_PARAMS` | Невалидное имя функции, несуществующее поле, нечисловое поле в `sum`\u002F`avg`\u002F`min`\u002F`max`, `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**`count` vs числовые функции.** `count` считается одним вызовом в Битрикс24 на любом объёме данных. Функции `sum`\u002F`avg`\u002F`min`\u002F`max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод — если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true`, агрегация выполнится по первым 5000. Для точных счётчиков на больших выборках используйте `count` или сужайте фильтр.\n\n**Money-поля.** UF-поля типа `money` хранятся в формате `\"сумма|валюта\"` (`\"1500|RUB\"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга.\n\n**Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ \"filter\": { \"ufCrm_1234\": \"value\" } }` вернёт количество счетов с этим значением UF.\n\n## Смотрите также\n\n- [Список счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Flist) — получить записи с фильтрацией\n- [Поиск счетов](\u002Fdocs\u002Fentities\u002Finvoices\u002Fsearch) — POST-запрос с фильтрами\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Товарные позиции счёта\n\n`GET \u002Fv1\u002Finvoices\u002F:id\u002Fproducts`\n\nВозвращает список товарных позиций, привязанных к счёту.\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID счёта |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Товаров:', data.length)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data` | array | Массив товарных позиций |\n| `data[].productId` | number | ID товара. Каталог: `GET \u002Fv1\u002Fproducts` |\n| `data[].productName` | string | Название товара |\n| `data[].price` | number | Цена за единицу |\n| `data[].quantity` | number | Количество |\n| `data[].discount` | number | Сумма скидки |\n| `data[].taxRate` | number\u002Fnull | Ставка налога (%) |\n| `data[].taxIncluded` | boolean | Налог включён в цену |\n\nПоказаны основные поля. Полный список (20 полей, включая priceAccount, measureCode и др.): [Поля товаров](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-fields).\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"productId\": 1,\n      \"productName\": \"Серверное оборудование\",\n      \"price\": 1000,\n      \"quantity\": 2,\n      \"discount\": 0,\n      \"taxRate\": null,\n      \"taxIncluded\": false\n    }\n  ]\n}\n```\n\n## Пример ответа при ошибке\n\n404 — счёт не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Счёт не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Установить товары](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-set) — заменить товарные позиции\n- [Получить счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fget) — основные данные счёта\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Установить товары счёта\n\n`PUT \u002Fv1\u002Finvoices\u002F:id\u002Fproducts`\n\nУстанавливает товарные позиции счёта. Полностью заменяет текущий список — передайте все нужные позиции.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `items` | array | да | Массив товарных позиций |\n| `items[].productId` | number | да | ID товара. Каталог: `GET \u002Fv1\u002Fproducts` |\n| `items[].price` | number | да | Цена за единицу |\n| `items[].quantity` | number | да | Количество |\n| `items[].discount` | number | нет | Сумма скидки |\n| `items[].taxRate` | number | нет | Ставка налога (%) |\n| `items[].taxIncluded` | boolean | нет | Налог включён в цену |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X PUT \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"items\": [\n      { \"productId\": 1, \"price\": 25000, \"quantity\": 2 },\n      { \"productId\": 5, \"price\": 5000, \"quantity\": 1, \"discount\": 500 }\n    ]\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X PUT \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"items\": [\n      { \"productId\": 1, \"price\": 25000, \"quantity\": 2 },\n      { \"productId\": 5, \"price\": 5000, \"quantity\": 1, \"discount\": 500 }\n    ]\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts', {\n  method: 'PUT',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    items: [\n      { productId: 1, price: 25000, quantity: 2 },\n      { productId: 5, price: 5000, quantity: 1, discount: 500 },\n    ],\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts', {\n  method: 'PUT',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    items: [\n      { productId: 1, price: 25000, quantity: 2 },\n      { productId: 5, price: 5000, quantity: 1, discount: 500 },\n    ],\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data` | array | Массив установленных позиций с полями productId, productName, price, quantity, discount, taxRate, taxIncluded |\n\nМассив установленных позиций с полями `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"productId\": 1,\n      \"productName\": \"Серверное оборудование\",\n      \"price\": 25000,\n      \"quantity\": 2,\n      \"discount\": 0,\n      \"taxRate\": null,\n      \"taxIncluded\": false\n    },\n    {\n      \"productId\": 5,\n      \"productName\": \"Установка и настройка\",\n      \"price\": 5000,\n      \"quantity\": 1,\n      \"discount\": 500,\n      \"taxRate\": null,\n      \"taxIncluded\": false\n    }\n  ]\n}\n```\n\n## Пример ответа при ошибке\n\n400 — неверный формат:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INVALID_PARAMS\",\n    \"message\": \"items must be an array\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_PARAMS` | `items` не является массивом |\n| 404 | `ENTITY_NOT_FOUND` | Счёт не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Полная замена:** PUT заменяет весь список товаров. Чтобы добавить позицию — сначала получите текущие (`GET`), добавьте новую в массив, отправьте всё (`PUT`).\n\n## Смотрите также\n\n- [Товарные позиции](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-get) — получить текущий список\n- [Получить счёт](\u002Fdocs\u002Fentities\u002Finvoices\u002Fget) — основные данные счёта\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Добавить товар в счёт\n\n`POST \u002Fv1\u002Finvoices\u002F:id\u002Fproducts`\n\nДобавляет одну товарную позицию в счёт. В отличие от `PUT \u002Fv1\u002Finvoices\u002F:id\u002Fproducts`, не заменяет существующие позиции.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID счёта |\n| `productId` | number | нет | ID товара из каталога. Если задан без `productName`, имя подставляется из каталога. Каталог: `GET \u002Fv1\u002Fproducts` |\n| `productName` | string | нет | Название товарной позиции — для произвольной строки без товара из каталога. Укажите хотя бы одно из `productId` \u002F `productName`. |\n| `price` | number | нет | Цена за единицу |\n| `quantity` | number | нет | Количество |\n| `discount` | number | нет | Сумма скидки |\n| `taxRate` | number | нет | Ставка налога (%) |\n| `taxIncluded` | boolean | нет | Налог включён в цену |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"productId\": 1, \"price\": 25000, \"quantity\": 2 }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"productId\": 1, \"price\": 25000, \"quantity\": 2 }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('ID строки:', data.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data.id` | number | ID созданной товарной строки |\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1465\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n404 — счёт не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Счёт не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Товарные позиции](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-get) — получить текущий список\n- [Установить товары](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-set) — заменить все позиции\n- [Удалить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-delete) — удалить одну позицию\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n","\n## Удалить товар из счёта\n\n`DELETE \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002F:rowId`\n\nУдаляет одну товарную позицию из счёта по ID строки. Восстановить удалённую позицию через API нельзя — добавляйте новую при необходимости.\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID счёта |\n| `rowId` (path) | number | да | ID товарной строки (из ответа add или list) |\n\n`rowId` — это ID товарной строки, а не `productId` из каталога товаров.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X DELETE \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\u002F1465\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X DELETE \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\u002F1465\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\u002F1465', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nif (res.status === 204) {\n  console.log('Товар удалён из счёта')\n}\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F58\u002Fproducts\u002F1465', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nif (res.status === 204) {\n  console.log('Удалено')\n}\n```\n\n## Ответ\n\nПри успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу.\n\n## Пример ответа\n\n```\nHTTP\u002F1.1 204 No Content\n```\n\n## Пример ответа при ошибке\n\n404 — счёт не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Счёт или товарная строка не найдена |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Товарные позиции](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-get) — получить текущий список\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-add) — добавить позицию\n- [Установить товары](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-set) — заменить все позиции\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n","\n## Получить товар из счёта\n\n`GET \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002F:rowId`\n\nВозвращает одну товарную позицию счёта по ID строки.\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID счёта |\n| `rowId` (path) | number | да | ID товарной строки (из ответа add или list) |\n\n`rowId` — это ID товарной строки, а не `productId` из каталога товаров.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X GET \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X GET \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Цена:', data.price)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data.id` | number | ID товарной строки |\n| `data.productId` | number | ID товара из каталога |\n| `data.productName` | string | Название товара |\n| `data.price` | number | Цена за единицу |\n| `data.quantity` | number | Количество |\n| `data.discount` | number | Сумма скидки |\n| `data.discountRate` | number | Процент скидки |\n| `data.discountTypeId` | number | Тип скидки (1 — сумма, 2 — процент) |\n| `data.taxRate` | number \\| null | Ставка налога (%) |\n| `data.taxIncluded` | boolean | Налог включён в цену |\n| `data.priceExclusive` | number | Цена без скидки |\n| `data.priceNetto` | number | Цена нетто |\n| `data.priceBrutto` | number | Цена брутто |\n| `data.priceAccount` | number | Цена в валюте учёта |\n| `data.measureCode` | number | Код единицы измерения |\n| `data.measureName` | string | Название единицы измерения |\n| `data.sort` | number | Сортировка |\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1471,\n    \"productId\": 1,\n    \"productName\": \"День добрый!\",\n    \"price\": 5000,\n    \"priceAccount\": 5000,\n    \"priceExclusive\": 5000,\n    \"priceNetto\": 5000,\n    \"priceBrutto\": 5000,\n    \"quantity\": 3,\n    \"discountTypeId\": 2,\n    \"discountRate\": 0,\n    \"discount\": 0,\n    \"taxRate\": null,\n    \"taxIncluded\": false,\n    \"customized\": \"Y\",\n    \"measureCode\": 796,\n    \"measureName\": \"шт\",\n    \"sort\": 0,\n    \"xmlId\": \"sale_basket_995\",\n    \"type\": 1\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n404 — счёт или товарная строка не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Счёт или товарная строка не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Товарные позиции](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-get) — получить все позиции\n- [Обновить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-update) — обновить позицию\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-add) — добавить позицию\n- [Удалить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-delete) — удалить позицию\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n","\n## Обновить товар счёта\n\n`PATCH \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002F:rowId`\n\nОбновляет товарную позицию счёта. Передайте только изменяемые поля.\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID счёта |\n| `rowId` (path) | number | да | ID товарной позиции (из ответа list или add, не productId из каталога) |\n\n## Поля запроса (body)\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `price` | number | Цена за единицу |\n| `quantity` | number | Количество |\n| `productId` | number | ID товара. Каталог: `GET \u002Fv1\u002Fproducts` |\n| `discount` | number | Сумма скидки |\n| `taxRate` | number | Ставка налога (%) |\n| `taxIncluded` | boolean | Налог включён в цену |\n| `sort` | number | Сортировка |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X PATCH \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"price\": 9999, \"quantity\": 10 }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X PATCH \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"price\": 9999, \"quantity\": 10 }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({ price: 9999, quantity: 10 }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Обновлено:', data.price, 'x', data.quantity)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002F1471', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({ price: 9999, quantity: 10 }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\nОбновлённый объект товарной позиции: `id`, `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1471,\n    \"productId\": 1,\n    \"productName\": \"Серверное оборудование\",\n    \"price\": 9999,\n    \"quantity\": 10,\n    \"discount\": 0,\n    \"taxRate\": null,\n    \"taxIncluded\": false\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n404 — позиция не найдена:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Позиция не найдена |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Получить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-get-single) — получение одной позиции\n- [Получить товары](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-get) — список всех позиций\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-add) — добавление\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Поля товаров счёта\n\n`GET \u002Fv1\u002Finvoices\u002F:id\u002Fproducts\u002Ffields`\n\nВозвращает описание полей товарных позиций счёта: названия, типы, доступность для чтения и записи.\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID счёта |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002Ffields\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002Ffields\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002Ffields', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Полей:', Object.keys(data).length)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Finvoices\u002F741\u002Fproducts\u002Ffields', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | RO | Обяз. | Описание |\n|------|-----|:--:|:-----:|---------|\n| `id` | integer | да | | ID позиции |\n| `productId` | integer | | да | ID товара. Каталог: `GET \u002Fv1\u002Fproducts` |\n| `productName` | string | | | Название товара |\n| `price` | double | | | Цена |\n| `quantity` | double | | | Количество |\n| `discountSum` | double | | | Сумма скидки |\n| `discountRate` | double | | | Величина скидки (%) |\n| `discountTypeId` | integer | | | Тип скидки |\n| `taxRate` | double | | | Налог (%) |\n| `taxIncluded` | char | | | Налог включён в цену (`Y`\u002F`N`) |\n| `priceExclusive` | double | да | | Цена без налога со скидкой |\n| `priceNetto` | double | да | | Цена нетто |\n| `priceBrutto` | double | да | | Цена брутто |\n| `measureCode` | integer | | | Код единицы измерения |\n| `measureName` | string | | | Единица измерения |\n| `customized` | char | | | Изменён (`Y`\u002F`N`) |\n| `sort` | integer | | | Сортировка |\n| `type` | integer | да | | Тип |\n| `storeId` | integer | да | | ID склада |\n| `ownerId` | integer | | да | ID владельца (счёта) |\n| `ownerType` | string | | да | Тип владельца |\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": true, \"title\": \"ID\" },\n    \"ownerId\": { \"type\": \"integer\", \"isRequired\": true, \"isReadOnly\": false, \"isImmutable\": true, \"title\": \"ID владельца\" },\n    \"ownerType\": { \"type\": \"string\", \"isRequired\": true, \"isReadOnly\": false, \"isImmutable\": true, \"title\": \"Тип владельца\" },\n    \"productId\": { \"type\": \"integer\", \"isRequired\": true, \"isReadOnly\": false, \"title\": \"Товар\" },\n    \"productName\": { \"type\": \"string\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Название товара\" },\n    \"price\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Цена\" },\n    \"priceExclusive\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": true, \"title\": \"Цена без налога со скидкой\" },\n    \"priceNetto\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": true, \"title\": \"PRICE_NETTO\" },\n    \"priceBrutto\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": true, \"title\": \"PRICE_BRUTTO\" },\n    \"quantity\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Количество\" },\n    \"discountTypeId\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Тип скидки\" },\n    \"discountRate\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Величина скидки\" },\n    \"discountSum\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Сумма скидки\" },\n    \"taxRate\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Налог\" },\n    \"taxIncluded\": { \"type\": \"char\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Налог включен в цену\" },\n    \"customized\": { \"type\": \"char\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Изменен\" },\n    \"measureCode\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Код единицы измерения\" },\n    \"measureName\": { \"type\": \"string\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Единица измерения\" },\n    \"sort\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": false, \"title\": \"Сортировка\" },\n    \"type\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": true, \"title\": \"TYPE\" },\n    \"storeId\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": true, \"title\": \"STORE_ID\" }\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n404 — счёт не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Элемент не найден\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Счёт не найден |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Товарные позиции](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-get) — получить товары счёта\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-add) — добавить позицию\n- [Установить товары](\u002Fdocs\u002Fentities\u002Finvoices\u002Fproducts-set) — заменить все позиции\n- [Поля счёта](\u002Fdocs\u002Fentities\u002Finvoices\u002Ffields) — описание полей счёта\n"]