[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-entities\u002Fdeals":3,"docs-tabs-entities\u002Fdeals":6},{"content":4,"lastmod":5},"# Сделки\n\nУправление сделками CRM: создание, получение, обновление, удаление, фильтрация.\n\nBitrix24 API: `crm.item.*`\nСкоуп: `crm`\n\n## Операции\n\n- [Создать сделку](.\u002Fdeals\u002Fcreate.md) — `POST \u002Fv1\u002Fdeals`\n- [Список сделок](.\u002Fdeals\u002Flist.md) — `GET \u002Fv1\u002Fdeals`\n- [Получить сделку](.\u002Fdeals\u002Fget.md) — `GET \u002Fv1\u002Fdeals\u002F:id`\n- [Обновить сделку](.\u002Fdeals\u002Fupdate.md) — `PATCH \u002Fv1\u002Fdeals\u002F:id`\n- [Удалить сделку](.\u002Fdeals\u002Fdelete.md) — `DELETE \u002Fv1\u002Fdeals\u002F:id`\n- [Поиск сделок](.\u002Fdeals\u002Fsearch.md) — `POST \u002Fv1\u002Fdeals\u002Fsearch`\n- [Поля сделки](.\u002Fdeals\u002Ffields.md) — `GET \u002Fv1\u002Fdeals\u002Ffields`\n- [Агрегация сделок](.\u002Fdeals\u002Faggregate.md) — `POST \u002Fv1\u002Fdeals\u002Faggregate`\n- [Получить товары](.\u002Fdeals\u002Fproducts-get.md) — `GET \u002Fv1\u002Fdeals\u002F:id\u002Fproducts`\n- [Установить товары](.\u002Fdeals\u002Fproducts-set.md) — `PUT \u002Fv1\u002Fdeals\u002F:id\u002Fproducts`\n- [Добавить товар](.\u002Fdeals\u002Fproducts-add.md) — `POST \u002Fv1\u002Fdeals\u002F:id\u002Fproducts`\n- [Удалить товар](.\u002Fdeals\u002Fproducts-delete.md) — `DELETE \u002Fv1\u002Fdeals\u002F:id\u002Fproducts\u002F:rowId`\n- [Получить товар](.\u002Fdeals\u002Fproducts-get-single.md) — `GET \u002Fv1\u002Fdeals\u002F:id\u002Fproducts\u002F:rowId`\n- [Обновить товар](.\u002Fdeals\u002Fproducts-update.md) — `PATCH \u002Fv1\u002Fdeals\u002F:id\u002Fproducts\u002F:rowId`\n- [Поля товаров](.\u002Fdeals\u002Fproducts-fields.md) — `GET \u002Fv1\u002Fdeals\u002F:id\u002Fproducts\u002Ffields`\n","2026-06-11",{"deals\u002Fcreate.md":7,"deals\u002Flist.md":8,"deals\u002Fget.md":9,"deals\u002Fupdate.md":10,"deals\u002Fdelete.md":11,"deals\u002Fsearch.md":12,"deals\u002Ffields.md":13,"deals\u002Faggregate.md":14,"deals\u002Fproducts-get.md":15,"deals\u002Fproducts-set.md":16,"deals\u002Fproducts-add.md":17,"deals\u002Fproducts-delete.md":18,"deals\u002Fproducts-get-single.md":19,"deals\u002Fproducts-update.md":20,"deals\u002Fproducts-fields.md":21},"\n## Создать сделку\n\n`POST \u002Fv1\u002Fdeals`\n\nСоздаёт новую сделку в CRM.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `title` | string | Название сделки |\n| `amount` | number | Сумма |\n| `currency` | string | Валюта. Список: `GET \u002Fv1\u002Fcurrencies` |\n| `stageId` | string | Стадия воронки. Стандартные: `NEW`, `PREPARATION`, `PREPAYMENT_INVOICE`, `EXECUTING`, `FINAL_INVOICE`, `WON`, `LOSE`. Портал может иметь свои — список: `GET \u002Fv1\u002Fstatuses?filter[entityId]=DEAL_STAGE` |\n| `categoryId` | number | ID воронки (0 = основная). Список: `GET \u002Fv1\u002Fdeal-categories` |\n| `companyId` | number | ID компании. Поиск: `GET \u002Fv1\u002Fcompanies` |\n| `contactId` | number | ID основного контакта. Поиск: `GET \u002Fv1\u002Fcontacts` |\n| `assignedById` | number | ID ответственного. Список сотрудников: `GET \u002Fv1\u002Fusers` |\n| `sourceId` | string | Источник. Список: `GET \u002Fv1\u002Fstatuses?filter[entityId]=SOURCE` |\n| `sourceDescription` | string | Описание источника |\n| `comments` | string | Комментарий |\n| `opened` | boolean | Доступна для всех |\n| `closedAt` | datetime | Дата закрытия |\n| `probability` | number | Вероятность успеха (%) |\n| `observers` | number[] | Массив ID наблюдателей. Список сотрудников: `GET \u002Fv1\u002Fusers` |\n\nПолный список полей: [GET \u002Fv1\u002Fdeals\u002Ffields](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields). Пользовательские поля (`ufCrm_*`) также принимаются.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"title\": \"Поставка оборудования\",\n    \"amount\": 50000,\n    \"currency\": \"RUB\",\n    \"stageId\": \"NEW\",\n    \"categoryId\": 0,\n    \"assignedById\": 1\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals \\\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    \"amount\": 50000,\n    \"currency\": \"RUB\",\n    \"stageId\": \"NEW\",\n    \"categoryId\": 0,\n    \"assignedById\": 1\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals', {\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    amount: 50000,\n    currency: 'RUB',\n    stageId: 'NEW',\n    categoryId: 0,\n    assignedById: 1,\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Deal ID:', data.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals', {\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    amount: 50000,\n    currency: 'RUB',\n    stageId: 'NEW',\n    categoryId: 0,\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| `amount` | number | Сумма |\n| `currency` | string | Валюта |\n| `stageId` | string | Стадия |\n| `categoryId` | number | ID воронки |\n| `assignedById` | number | Ответственный |\n| `createdBy` | number | Создатель |\n| `createdAt` | datetime | Дата создания |\n| `updatedAt` | datetime | Дата изменения |\n| `entityTypeId` | number | Тип сущности (2 = сделки) |\n\nОтвет содержит все поля сделки, включая пользовательские (`ufCrm_*`). Выше показаны основные.\n\nURL карточки сделки в Битрикс24 строится из `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcrm\u002Fdeal\u002Fdetails\u002F\u003Cid>\u002F\n```\n\n`\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 7689,\n    \"title\": \"Поставка оборудования\",\n    \"amount\": 50000,\n    \"currency\": \"RUB\",\n    \"stageId\": \"NEW\",\n    \"categoryId\": 0,\n    \"assignedById\": 1,\n    \"createdBy\": 1,\n    \"createdAt\": \"2026-04-14T08:43:59.000Z\",\n    \"updatedAt\": \"2026-04-14T08:43:59.000Z\",\n    \"companyId\": 0,\n    \"contactId\": 0,\n    \"opened\": true,\n    \"closed\": \"N\",\n    \"typeId\": \"SALE\",\n    \"observers\": [],\n    \"contactIds\": [],\n    \"entityTypeId\": 2\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\u002Fdeals\u002Flist) — получение с фильтрами\n- [Поля сделки](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields) — полный список полей\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы (пагинация, select, order)\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Batch](\u002Fdocs\u002Fbatch) — объединение операций\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Список сделок\n\n`GET \u002Fv1\u002Fdeals`\n\nВозвращает список сделок с поддержкой фильтрации, сортировки и авто-пагинации.\n\n## Параметры\n\n| Параметр | Тип | По умолч. | Описание |\n|----------|-----|-----------|---------|\n| `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у B24 |\n| `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` |\n| `select` | string | — | Выборка полей: `?select=id,title,amount` |\n| `order` | object | — | Сортировка: `?order[createdAt]=desc` |\n| `filter` | object | — | Фильтрация по полям `GET \u002Fv1\u002Fdeals\u002Ffields`.\u003Cbr>[Синтаксис фильтрации](\u002Fdocs\u002Ffiltering). Пример: `?filter[stageId]=NEW` |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals?limit=10&order[amount]=desc&filter[stageId]=NEW\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals?limit=10&order[amount]=desc&filter[stageId]=NEW\" \\\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\u002Fdeals?limit=10&order[amount]=desc&filter[stageId]=NEW', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\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\u002Fdeals?limit=10&order[amount]=desc&filter[stageId]=NEW', {\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 | Массив сделок (каждая содержит все поля — см. [Поля](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields)) |\n| `total` | number | Общее количество записей, соответствующих фильтру |\n| `page` | number | Текущая страница |\n| `limit` | number | Размер страницы |\n\nURL карточки любой сделки из массива `data` — её `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcrm\u002Fdeal\u002Fdetails\u002F\u003Cid>\u002F\n```\n\n`\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 741,\n      \"title\": \"Поставка оборудования\",\n      \"amount\": 50000,\n      \"currency\": \"RUB\",\n      \"stageId\": \"NEW\",\n      \"categoryId\": 0,\n      \"assignedById\": 1,\n      \"createdAt\": \"2026-04-14T08:43:59.000Z\",\n      \"contactId\": 71,\n      \"companyId\": 0,\n      \"opened\": true\n    }\n  ],\n  \"total\": 156,\n  \"page\": 1,\n  \"limit\": 10\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**Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Bitrix24 и возвращает все записи в одном ответе.\n\n**Ограничение offset:** при `offset ≥ 2500` Bitrix24 может вернуть `INTERNAL_ERROR`. Используйте `limit ≤ 500` при больших offset.\n\n**Когда использовать search вместо list:** для сложных фильтров с множеством условий удобнее `POST \u002Fv1\u002Fdeals\u002Fsearch` — параметры передаются в body, а не в query-строке. Также search поддерживает [оконный поиск по датам](\u002Fdocs\u002Fbatch) для больших выборок. См. [Поиск сделок](\u002Fdocs\u002Fentities\u002Fdeals\u002Fsearch).\n\n## Смотрите также\n\n- [Поиск сделок](\u002Fdocs\u002Fentities\u002Fdeals\u002Fsearch) — POST-запрос для сложных фильтров\n- [Создать сделку](\u002Fdocs\u002Fentities\u002Fdeals\u002Fcreate) — создание новой\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Entity API](\u002Fdocs\u002Fentity-api) — select, order, пагинация\n- [Batch](\u002Fdocs\u002Fbatch) — объединение нескольких list-запросов\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Получить сделку\n\n`GET \u002Fv1\u002Fdeals\u002F:id`\n\nВозвращает сделку по ID со всеми полями, включая пользовательские (`ufCrm_*`).\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\u002Fdeals\u002F741\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\u002F741\" \\\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\u002Fdeals\u002F741', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Сделка:', data.title, '—', data.amount, data.currency)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\u002F741', {\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Объект сделки со всеми полями — см. [Поля сделки](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields).\n\n## Связанные данные\n\nПолучить связанные сущности вместе со сделкой — параметр `include` в GET-запросе:\n\n```\nGET \u002Fv1\u002Fdeals\u002F741?include=contact,company\n```\n\nДоступные include: `contact`, `company`, `quote`. Результат в поле `_included`:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 741,\n    \"title\": \"Поставка оборудования\",\n    \"_included\": {\n      \"contacts\": [{ \"id\": 71, \"name\": \"Иван Петров\", ... }],\n      \"company\": { \"id\": 15, \"title\": \"ООО Ромашка\", ... }\n    }\n  }\n}\n```\n\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 741,\n    \"title\": \"Поставка оборудования\",\n    \"amount\": 50000,\n    \"currency\": \"RUB\",\n    \"stageId\": \"EXECUTING\",\n    \"categoryId\": 0,\n    \"assignedById\": 29,\n    \"createdBy\": 1,\n    \"createdAt\": \"2020-09-25T13:08:24.000Z\",\n    \"updatedAt\": \"2025-08-22T13:01:31.000Z\",\n    \"contactId\": 71,\n    \"companyId\": 0,\n    \"opened\": true,\n    \"observers\": [],\n    \"contactIds\": [],\n    \"entityTypeId\": 2\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\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Сделка с таким ID не найдена |\n| 403 | `ACCESS_DENIED` | Нет доступа к сделке |\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\u002Fdeals\u002Ffields) — все поля\n- [Обновить сделку](\u002Fdocs\u002Fentities\u002Fdeals\u002Fupdate) — изменение полей\n- [Список сделок](\u002Fdocs\u002Fentities\u002Fdeals\u002Flist) — поиск с фильтрами\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Обновить сделку\n\n`PATCH \u002Fv1\u002Fdeals\u002F:id`\n\nОбновляет поля существующей сделки. Передайте только изменяемые поля. Полный список в [справочнике полей](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields), включая пользовательские (`ufCrm_*`).\n\n## Часто обновляемые поля\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `stageId` | string | Стадия воронки. Список: `GET \u002Fv1\u002Fstatuses?filter[entityId]=DEAL_STAGE` |\n| `amount` | number | Сумма сделки |\n| `assignedById` | number | Ответственный. Список: `GET \u002Fv1\u002Fusers` |\n| `title` | string | Название |\n| `closedAt` | datetime | Дата закрытия |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X PATCH \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\u002F741\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"stageId\": \"WON\",\n    \"amount\": 75000\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X PATCH \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\u002F741\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"stageId\": \"WON\",\n    \"amount\": 75000\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\u002F741', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    stageId: 'WON',\n    amount: 75000,\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\u002Fdeals\u002F741', {\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    stageId: 'WON',\n    amount: 75000,\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data` | object | Обновлённый объект сделки со всеми полями — см. [Поля](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields) |\n\nОбновлённый объект сделки со всеми полями — см. [Поля сделки](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields).\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 741,\n    \"title\": \"Поставка оборудования\",\n    \"amount\": 75000,\n    \"currency\": \"RUB\",\n    \"stageId\": \"WON\",\n    \"categoryId\": 0,\n    \"assignedById\": 1,\n    \"updatedAt\": \"2026-04-14T09:15:00.000Z\",\n    \"entityTypeId\": 2\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 | `ACCESS_DENIED` | Нет доступа к сделке |\n| 400 | `INVALID_REQUEST` | Невалидные поля |\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\u002Fdeals\u002Fget) — текущие значения полей\n- [Поля сделки](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields) — какие поля можно изменять\n- [Batch](\u002Fdocs\u002Fbatch) — массовое обновление сделок\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Удалить сделку\n\n`DELETE \u002Fv1\u002Fdeals\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\u002Fdeals\u002F7689\" \\\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\u002Fdeals\u002F7689\" \\\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\u002Fdeals\u002F7689', {\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\u002Fdeals\u002F7689', {\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 | `ACCESS_DENIED` | Нет доступа к сделке |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Список сделок](\u002Fdocs\u002Fentities\u002Fdeals\u002Flist) — найти сделку перед удалением\n- [Batch](\u002Fdocs\u002Fbatch) — массовое удаление\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Поиск сделок\n\n`POST \u002Fv1\u002Fdeals\u002Fsearch`\n\nПоиск сделок с фильтрами и авто-пагинацией. Аналогичен `GET \u002Fv1\u002Fdeals` с фильтрами, но через POST — удобнее для сложных запросов с большим количеством условий.\n\n## Поля запроса (body)\n\n| Параметр | Тип | По умолч. | Описание |\n|----------|-----|-----------|---------|\n| `filter` | object | — | Фильтрация по полям `GET \u002Fv1\u002Fdeals\u002Ffields`.\u003Cbr>[Синтаксис фильтрации](\u002Fdocs\u002Ffiltering). Пример: `?filter[stageId]=NEW` |\n| `limit` | number | `50` | Количество записей (до 5000) |\n| `offset` | number | `0` | Пропустить N записей |\n| `order` | object | — | Сортировка: `{ \"createdAt\": \"desc\" }` |\n| `select` | string[] | — | Выборка полей: `[\"id\", \"title\", \"amount\"]` |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\u002Fsearch\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"filter\": { \"stageId\": \"NEW\" },\n    \"limit\": 10,\n    \"order\": { \"amount\": \"desc\" }\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\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\": { \"stageId\": \"NEW\" },\n    \"limit\": 10,\n    \"order\": { \"amount\": \"desc\" }\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\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: { stageId: 'NEW' },\n    limit: 10,\n    order: { amount: 'desc' },\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\u002Fdeals\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: { stageId: 'NEW' },\n    limit: 10,\n    order: { amount: 'desc' },\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `data` | array | Массив сделок (все поля — см. [Поля](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields)) |\n\nURL карточки любой сделки из массива `data` — её `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcrm\u002Fdeal\u002Fdetails\u002F\u003Cid>\u002F\n```\n\n`\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 3865,\n      \"title\": \"Шаблончик\",\n      \"amount\": 0,\n      \"currency\": \"RUB\",\n      \"stageId\": \"NEW\",\n      \"categoryId\": 0,\n      \"assignedById\": 29,\n      \"createdAt\": \"2021-01-13T13:52:44.000Z\"\n    }\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\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Отчёты по закрытым сделкам фильтруются по `closedAt`.** Дата закрытия сделки — поле `closedAt` (ISO 8601 с учётом часового пояса портала), заполняется при переходе сделки в финальную стадию. Имя поля именно `closedAt` — не `closedDate`. Для отчёта «выиграно\u002Fпроиграно за период» отбирайте по диапазону `closedAt`:\n\n```json\n{\n  \"filter\": {\n    \"closedAt\": { \"$gte\": \"2026-01-01\", \"$lte\": \"2026-01-31T23:59:59\" }\n  }\n}\n```\n\nЧтобы разделить выигранные и проигранные, добавьте к фильтру стадию (`stageId`); идентификаторы финальных стадий воронки — `GET \u002Fv1\u002Fstatuses?filter[entityId]=DEAL_STAGE`.\n\n## Смотрите также\n\n- [Список сделок](\u002Fdocs\u002Fentities\u002Fdeals\u002Flist) — GET-запрос с query-параметрами (для простых фильтров)\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Batch](\u002Fdocs\u002Fbatch) — объединение нескольких search в один запрос\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Поля сделки\n\n`GET \u002Fv1\u002Fdeals\u002Ffields`\n\nВозвращает полный список доступных полей, включая пользовательские (`ufCrm_*`).\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\u002Ffields\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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| Поле | Битрикс24 | Тип | RO | Описание |\n|------|----------|-----|:--:|---------|\n| `id` | `id` | number | да | ID сделки |\n| `title` | `title` | string | | Название |\n| `amount` | `opportunity` | number | | Сумма |\n| `currency` | `currencyId` | string | | Валюта. Список: `GET \u002Fv1\u002Fcurrencies` |\n| `stageId` | `stageId` | string | | Стадия воронки. Набор стадий и их идентификаторы настраиваются на стороне портала и отличаются между воронками. Актуальный список — `GET \u002Fv1\u002Fstatuses?filter[entityId]=DEAL_STAGE` для основной воронки, `GET \u002Fv1\u002Fstatuses?filter[entityId]=DEAL_STAGE_{N}` для воронки с `categoryId={N}` (значение `categoryId` берётся из `GET \u002Fv1\u002Fdeal-categories`) |\n| `categoryId` | `categoryId` | number | | ID воронки (0 = основная). Список: `GET \u002Fv1\u002Fdeal-categories` |\n| `companyId` | `companyId` | number | | ID компании. Поиск: `GET \u002Fv1\u002Fcompanies` |\n| `contactId` | `contactId` | number | | ID основного контакта. Поиск: `GET \u002Fv1\u002Fcontacts` |\n| `contactIds` | `contactIds` | number[] | да | Все привязанные контакты. Поиск: `GET \u002Fv1\u002Fcontacts` |\n| `assignedById` | `assignedById` | number | | Ответственный. Список: `GET \u002Fv1\u002Fusers` |\n| `createdBy` | `createdBy` | number | да | Создатель. Поиск: `GET \u002Fv1\u002Fusers` |\n| `updatedBy` | `updatedBy` | number | да | Кто изменил. Поиск: `GET \u002Fv1\u002Fusers` |\n| `createdAt` | `createdTime` | datetime | да | Дата создания |\n| `updatedAt` | `updatedTime` | datetime | да | Дата изменения |\n| `closedAt` | `closedate` | datetime | | Дата закрытия |\n| `sourceId` | `sourceId` | string | | Источник. Список: `GET \u002Fv1\u002Fstatuses?filter[entityId]=SOURCE` |\n| `sourceDescription` | `sourceDescription` | string | | Описание источника |\n| `probability` | `probability` | number | | Вероятность успеха (%) |\n| `opened` | `opened` | boolean | | Доступна для всех |\n| `comments` | `comments` | string | | Комментарий |\n| `observers` | `observers` | number[] | | Наблюдатели. Список: `GET \u002Fv1\u002Fusers` |\n| `typeId` | `typeId` | string | | Тип записи. Список: `GET \u002Fv1\u002Fstatuses?filter[entityId]=DEAL_TYPE` |\n| `isReturning` | `isReturnCustomer` | boolean | | Повторная сделка |\n\n**Пользовательские поля** (`ufCrm_*`) также возвращаются в ответах и принимаются при создании\u002Fобновлении.\n\n\n\n## Доступные include\n\nЭндпоинт `GET \u002Fv1\u002Fdeals\u002Ffields` возвращает список доступных include: `contact`, `company`, `quote`.\n\nПример использования: [Получить deals](\u002Fdocs\u002Fentities\u002Fdeals\u002Fget#связанные-данные).\n\nПодробнее об include: [Связанные данные](\u002Fdocs\u002Fincludes).\n\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## Пример ответа при ошибке\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\u002Fdeals\u002Fcreate) — какие поля передавать\n- [Пользовательские поля](\u002Fdocs\u002Fuserfields) — создание и управление `ufCrm_*`\n- [Entity API](\u002Fdocs\u002Fentity-api) — select для выборки нужных полей\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Агрегация сделок\n\n`POST \u002Fv1\u002Fdeals\u002Faggregate`\n\nПодсчёт количества, сумма, среднее, минимум и максимум по сделкам с фильтрацией и группировкой.\n\n**Стандартные поля:**\n\n- `amount` — сумма сделки (числовое агрегирование имеет смысл)\n- `stageId` — стадия (для `groupBy`)\n- `categoryId` — воронка (для `groupBy`)\n- `assignedById` — ответственный (для `groupBy`)\n- `sourceId` — источник (для `groupBy`)\n\n**Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ \"field\": \"amount\", \"function\": \"sum\" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Для `count` поле — `\"*\"`. Без массива — только `count` |\n| `filter` | object | нет | Фильтрация по полям `GET \u002Fv1\u002Fdeals\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\u002Fdeals\u002Faggregate\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"aggregate\": [\n      { \"field\": \"amount\", \"function\": \"sum\" },\n      { \"field\": \"amount\", \"function\": \"avg\" }\n    ],\n    \"filter\": { \"categoryId\": 0 },\n    \"groupBy\": \"stageId\"\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\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\": \"amount\", \"function\": \"sum\" },\n      { \"field\": \"amount\", \"function\": \"avg\" }\n    ],\n    \"filter\": { \"categoryId\": 0 },\n    \"groupBy\": \"stageId\"\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fdeals\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: 'amount', function: 'sum' },\n      { field: 'amount', function: 'avg' },\n    ],\n    filter: { categoryId: 0 },\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\u002Fdeals\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: 'amount', function: 'sum' },\n      { field: 'amount', function: 'avg' },\n    ],\n    filter: { categoryId: 0 },\n    groupBy: 'stageId',\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n> Для группировки по нескольким полям передайте массив: `\"groupBy\": [\"stageId\", \"sourceId\"]` (максимум 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_BUDGET\", \"function\": \"sum\" }],\n  \"groupBy\": \"UF_CRM_PRIORITY\"\n}\n```\n\nСводка по воронке — один запрос с группировкой по стадии и суммой даёт разбивку, из которой на стороне приложения считается конверсия в выигранные:\n\n```json\n{\n  \"aggregate\": [{ \"field\": \"amount\", \"function\": \"sum\" }],\n  \"filter\": { \"categoryId\": 0 },\n  \"groupBy\": \"stageId\"\n}\n```\n\nВ ответе `data.count` — всего сделок в воронке, `data.groups` — разбивка по стадиям с суммой и количеством. Идентификаторы стадий зависят от воронки — получить их можно из [Поля](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields). Конверсия считается из групп без отдельного запроса:\n\n```javascript\nconst total = data.count\nconst won = data.groups.find(g => g.stageId === 'WON')?.count ?? 0\nconst conversion = total ? Math.round((won \u002F total) * 100) : 0\nconsole.log(`Сделок в воронке: ${total}, выиграно: ${won}, конверсия: ${conversion}%`)\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data.count` | number | Общее количество записей под фильтр |\n| `data.aggregates` | object | Результаты агрегаций: `{ \"amount\": { \"sum\": 100000, \"avg\": 2439 } }` |\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\": 41,\n    \"aggregates\": {\n      \"amount\": { \"sum\": 100000, \"avg\": 2439 }\n    },\n    \"groups\": [\n      {\n        \"stageId\": \"NEW\",\n        \"count\": 25,\n        \"aggregates\": { \"amount\": { \"sum\": 60000 } }\n      },\n      {\n        \"stageId\": \"WON\",\n        \"count\": 16,\n        \"aggregates\": { \"amount\": { \"sum\": 40000 } }\n      }\n    ],\n    \"meta\": {\n      \"totalRecords\": 41,\n      \"recordsProcessed\": 41,\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: amount, stageId, categoryId, assignedById, sourceId\"\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\u002Fdeals\u002Flist) — получить записи с фильтрацией\n- [Поиск сделок](\u002Fdocs\u002Fentities\u002Fdeals\u002Fsearch) — POST-запрос с фильтрами\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Товарные позиции сделки\n\n`GET \u002Fv1\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\u002Fproducts-set) — заменить товарные позиции\n- [Получить сделку](\u002Fdocs\u002Fentities\u002Fdeals\u002Fget) — основные данные сделки\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Установить товары сделки\n\n`PUT \u002Fv1\u002Fdeals\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002Fproducts-get) — получить текущий список\n- [Получить сделку](\u002Fdocs\u002Fentities\u002Fdeals\u002Fget) — основные данные сделки\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Добавить товар в сделку\n\n`POST \u002Fv1\u002Fdeals\u002F:id\u002Fproducts`\n\nДобавляет одну товарную позицию в сделку. В отличие от `PUT \u002Fv1\u002Fdeals\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002Fproducts-get) — получить текущий список\n- [Установить товары](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-set) — заменить все позиции\n- [Удалить товар](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-delete) — удалить одну позицию\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n","\n## Удалить товар из сделки\n\n`DELETE \u002Fv1\u002Fdeals\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002F741\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\u002Fdeals\u002Fproducts-get) — получить текущий список\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-add) — добавить позицию\n- [Установить товары](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-set) — заменить все позиции\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n","\n## Получить товар из сделки\n\n`GET \u002Fv1\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\u002Fproducts-get) — получить все позиции\n- [Обновить товар](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-update) — обновить позицию\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-add) — добавить позицию\n- [Удалить товар](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-delete) — удалить позицию\n- [Товары каталога](\u002Fdocs\u002Fentities\u002Fproducts) — справочник товаров\n","\n## Обновить товар сделки\n\n`PATCH \u002Fv1\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\u002Fproducts-get-single) — получение одной позиции\n- [Получить товары](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-get) — список всех позиций\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-add) — добавление\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) — rate limits\n","\n## Поля товаров сделки\n\n`GET \u002Fv1\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\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\u002Fdeals\u002Fproducts-get) — получить товары сделки\n- [Добавить товар](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-add) — добавить позицию\n- [Установить товары](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-set) — заменить все позиции\n- [Поля сделки](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields) — описание полей самой сделки\n"]