# VibeCode — Complete Documentation # https://vibecode.bitrix24.tech # Generated: 2026-06-09T21:28:00.109Z --- # Начало работы с Битрикс24 Вайбкод Битрикс24 Вайбкод — платформа, где искусственный интеллект (AI) создаёт приложения для Битрикс24. Вы описываете задачу обычными словами — и получаете рабочее приложение за часы, без программиста и без навыков разработки. ## Почему это для вас - **Без навыков программирования.** AI пишет код — вам не нужно разбираться в API, серверах и базах данных. - **Часы, а не месяцы.** Не нужно искать разработчика, ставить техзадание и ждать неделями. От идеи до работающего приложения — один разговор с AI-моделью. - **Под вашим контролем.** Доступ к данным открывает ключ, который вы создаёте и в любой момент отзываете сами. Приложение работает на отдельном сервере, закрытом от интернета. - **Дешевле работы программиста.** Разработку делает AI, оплата — за работу сервера и отдельные функции. ## Что понадобится Перед началом убедитесь, что у вас есть: - **Портал Битрикс24 с активной подпиской BitrixGPT + Маркетплейс.** С ней доступна вся платформа Вайбкод — создание ключей, обращение к данным портала, серверы, деплой и публикация приложений. Без активной подписки эти возможности закрыты. - **AI-инструмент, который сам работает с файлами и выполняет команды** — например, Claude Code, Cursor или OpenAI Codex. Такой инструмент не просто отвечает в чате, а действует автономно: сам читает документацию, создаёт файлы приложения, пишет код и отправляет запросы к платформе Вайбкод. Обычный чат с нейросетью, где можно только переписываться, для этого не подойдёт — иначе все шаги пришлось бы выполнять вручную. ## Шаг 1. Создайте ключ Ключ — это доступ к данным вашего Битрикс24, который вы передаёте AI-модели. Есть два вида ключей: - **Для себя** (`vibe_api_…`) — приложение работает от вашего имени. Подходит для личных сводок, отчётов и автоматизаций. Создаётся в разделе [Ключи API](/keys). - **Для команды и для встраивания в портал** (`vibe_app_…`) — каждый сотрудник входит через свой Битрикс24 и видит свои данные. Этот же ключ нужен, чтобы приложение открывалось внутри Битрикс24 — в левом меню, вкладке CRM или виджете. Создаётся в разделе [Ключи авторизации](/apps). Не уверены — начните с ключа «для себя»: переключиться на командный можно позже. Если приложение должно открываться внутри Битрикс24, сразу создавайте ключ авторизации (`vibe_app_…`). 1. Войдите в [личный кабинет](/dashboard). 2. Откройте [Ключи API](/keys) (для себя) или [Ключи авторизации](/apps) (для команды и встраивания в портал). 3. Нажмите **Создать**, укажите название и отметьте [разрешения](./scopes.md) — с какими данными приложение сможет работать. 4. Скопируйте ключ — он показывается один раз. Подробный разбор формы создания — [Создание и использование ключа](./keys-auth.md). ## Шаг 2. Дайте ключ AI-модели Откройте Claude Code, Cursor или другой AI-инструмент и вставьте промпт: ``` Мой API ключ для платформы Вайбкод: vibe_api_xxx... Документация: https://vibecode.bitrix24.tech/v1/me Сделай мне приложение [описание приложения] и задеплой на вайбкод ``` Для ключа авторизации (приложение для команды или со встраиванием в портал): ``` Мой API ключ для платформы Вайбкод: vibe_app_xxx... Документация: https://vibecode.bitrix24.tech/v1/me Сделай мне приложение [описание приложения] с авторизацией, встрой его в Битрикс24 и задеплой на вайбкод ``` Модель вызовет `GET /v1/me` с вашим ключом и получит доступные данные, разрешения и инструкции по размещению приложения. ## Шаг 3. Что произойдёт дальше AI-модель делает всё сама: 1. Узнаёт по вашему ключу, к каким данным и возможностям есть доступ (`GET /v1/me`). 2. Пишет код приложения, используя данные вашего Битрикс24 (сделки, задачи, контакты и другие). 3. Создаёт сервер и размещает приложение через `POST /v1/infra/servers/:id/deploy`. 4. Приложение доступно по адресу вида `https://app-xxx.vibecode.bitrix24.tech`. Сервер можно создать и заранее, вручную в разделе [Black Hole](/black-hole). Подробнее — [Инфраструктура](./infra.md). ## Что дальше - [Создание и использование ключа](./keys-auth.md) — как создать ключ, ограничить срок действия и отозвать в любой момент. - [Разрешения (скоупы)](./scopes.md) — что означают разрешения и какие данные вы открываете приложению. - [Бот-платформа](./bots.md) — как сделать чат-бота для клиентов или сотрудников. Готовые примеры: [аналитика воронки продаж](./recipes/crm-analytics.md), [Telegram-бот для CRM](./recipes/telegram-bot.md), [массовая рассылка по контактам](./recipes/mass-messaging.md), [автоматизация задач](./recipes/task-automation.md), [синхронизация с 1С/ERP](./recipes/erp-sync.md). Для разработчика и AI-модели: [работа с данными](./entity-api.md), [фильтрация](./filtering.md), [Batch API](./batch.md), [оптимизация](./optimization.md), [инфраструктура](./infra.md), [коды ошибок](./errors.md). --- # Создание и использование ключа Ключ — это учётные данные для доступа к Vibe API. Эта страница проводит через создание ключа в личном кабинете шаг за шагом и разбирает каждый параметр формы: название, скоупы, срок действия, лимит запросов и список разрешённых IP. Какие скоупы выбрать под задачу — на отдельной странице [Скоупы](./scopes.md). ## Типы ключей | Тип | Префикс | Назначение | Авторизация | |-----|---------|------------|-------------| | **API-ключ** | `vibe_api_` | Доступ к данным портала через Vibe API | Заголовок `X-Api-Key` | | **Ключ авторизации** | `vibe_app_` | Встраивание приложения в портал и OAuth-авторизация Битрикс24 | `X-Api-Key` + токен сессии | | **Менеджмент-ключ** | `vibe_live_` | Администрирование платформы | Заголовок `X-Api-Key` | **API-ключ (`vibe_api_`).** Создаётся в личном кабинете и привязан к одному порталу Битрикс24. Все запросы идут от лица владельца ключа, токен сессии не требуется. Подходит для личных дашбордов, скриптов, серверных интеграций и ботов на своём портале. **Ключ авторизации (`vibe_app_`).** Привязан к Вайбкод-приложению с OAuth-учётными данными Битрикс24. Каждый запрос отправляется от лица пользователя, установившего приложение и прошедшего авторизацию, — поэтому нужен заголовок `Authorization: Bearer`. Подходит для приложений из каталога, которые работают на разных порталах под разными пользователями. Этот же ключ нужен, чтобы приложение открывалось внутри Битрикс24 — в левом меню, вкладке CRM или виджете (раздел [Встраивание приложения в портал](#встраивание-приложения-в-портал)). **Менеджмент-ключ (`vibe_live_`).** Не привязан к одному порталу, предназначен для администрирования: управления ключами, просмотра порталов, работы с обратной связью. Доступа к данным сущностей Битрикс24 не имеет. Полное описание — [Менеджмент-ключи](./management-keys.md). Дальше — создание обоих ключей портала: API-ключа (`vibe_api_`) и ключа авторизации (`vibe_app_`). Формы немного отличаются, отличие описано ниже. Менеджмент-ключ (`vibe_live_`) описан отдельно — [Менеджмент-ключи](./management-keys.md). ## Создание API-ключа 1. Войдите в [личный кабинет](/dashboard). 2. Откройте раздел [Ключи API](/keys). 3. Нажмите **Создать**. 4. Заполните форму (шаги ниже). 5. Скопируйте ключ — он показывается один раз. ### Шаг 1. Название Произвольное название для самого себя — по нему ключ виден в списке. На доступ не влияет. Заведите отдельный ключ с понятным названием для каждого сервиса или интеграции — это упрощает отзыв при компрометации. ### Шаг 2. Скоупы Скоупы — это разрешения на доступ к данным. В форме они сгруппированы во вкладки «Битрикс24» и «Вайбкод»; нужно отметить минимум один. Полный список скоупов, описание каждого и подбор набора под задачу — на странице [Скоупы](./scopes.md). Короткий ориентир: `crm` — данные CRM, `tasks` — задачи, `imbot` + `im` — чат-бот, `disk` — файлы. Четыре скоупа платформы (`vibe:infra`, `vibe:ai`, `vibe:search`, `vibe:storage`) добавляются к ключу автоматически — отмечать их не нужно. Набор скоупов Битрикс24 закрепляется за ключом в момент выпуска. Если добавить скоуп Битрикс24 в настройках уже существующего ключа, `GET /v1/me` покажет его в списке, но запросы, которым он нужен, вернут `BITRIX_ACCESS_DENIED`: к данным Битрикс24 ключ обращается с тем набором скоупов, с которым был выпущен. Чтобы выдать ключу новый скоуп Битрикс24: - **API-ключ (`vibe_api_`)** — [перевыпустите ключ](#перевыпуск) или создайте новый с отмеченным скоупом. - **Ключ авторизации (`vibe_app_`)** — создайте приложение заново с нужным скоупом и пройдите авторизацию заново (перевыпуск ключа здесь скоуп не выдаёт). Скоуп выдаётся при выпуске только если он доступен на портале Битрикс24. Если после перевыпуска или повторной авторизации вызов всё ещё возвращает `BITRIX_ACCESS_DENIED`, значит скоуп для этого ключа на портале не предоставлен. ### Шаг 3. Срок действия Когда ключ перестанет действовать. Варианты: без ограничения, 30, 90, 180 или 365 дней. После истечения срока запросы с ключом отклоняются с кодом `KEY_EXPIRED`. Для серверных интеграций задавайте конечный срок и обновляйте ключ заранее. ### Шаг 4. Лимит запросов Необязательный индивидуальный лимит для этого ключа. Если поле пустое — применяются общие лимиты платформы и портала (раздел «Лимиты запросов» ниже). Значение, действующее для ключа, возвращает `GET /v1/me` в поле `rateLimit.requestsPerSecond`. ### Шаг 5. Список разрешённых IP В блоке «Расширенные настройки». Ограничивает вызовы ключа списком IP-адресов. Поддерживаются точные адреса IPv4 и IPv6, по одному в строке; подсети в формате CIDR не поддерживаются. ``` 192.168.1.100 203.0.113.42 2001:db8::1 ``` Запрос с адреса вне списка отклоняется с кодом `403 IP_NOT_ALLOWED`. Если список пуст — ограничения по IP нет. ### Шаг 6. Сохраните ключ Полный ключ показывается **один раз** сразу после создания. Скопируйте и сохраните его в надёжном месте — повторно его получить нельзя, только перевыпустить. ## Создание ключа авторизации Ключ авторизации (`vibe_app_`) создаётся в разделе [Ключи авторизации](/apps) личного кабинета. Форма короче, чем у API-ключа: всего два поля. 1. Откройте раздел [Ключи авторизации](/apps) и нажмите **Создать**. 2. **Название** — под ним приложение видно в списке. 3. **Скоупы** — те же две группы «Битрикс24» и «Вайбкод», минимум один; подбор набора описан на странице [Скоупы](./scopes.md). 4. Скопируйте ключ — он показывается один раз. Срок действия, лимит запросов и список разрешённых IP в этой форме не задаются — этим она и отличается от формы API-ключа. После создания ключ авторизации работает в паре с токеном сессии: каждый запрос отправляется с заголовками `X-Api-Key` и `Authorization: Bearer` (раздел «Передача ключа»). ## Встраивание приложения в портал Если приложение должно открываться **внутри Битрикс24** — пунктом в левом меню, вкладкой в карточке CRM или виджетом на рабочем столе, — для этого нужен **ключ авторизации** (`vibe_app_`). API-ключ (`vibe_api_`) встраивание в интерфейс портала не поддерживает: с ним приложение обращается к данным, но не размещается в окне Битрикс24. Ключ авторизации даёт две возможности, которых нет у API-ключа: - **Размещение в интерфейсе.** Приложение появляется в выбранном месте портала — за это отвечает привязка размещения `POST /v1/placements/bind`. Доступные места возвращает `GET /v1/placements/available`. - **Прозрачная авторизация.** Пользователь открывает приложение внутри Битрикс24 без отдельного входа: Gateway сам определяет, кто открыл приложение, и передаёт его данные серверу приложения. Браузер токен сессии не видит. Порядок действий: 1. Создайте ключ авторизации в разделе [Ключи авторизации](/apps) — форма описана выше в разделе «Создание ключа авторизации». 2. Передайте AI-модели именно ключ авторизации (`vibe_app_`) и попросите приложение со встраиванием в портал. 3. Модель вызовет `GET /v1/me` с этим ключом и получит раздел `placements` с полным порядком встраивания. Полный жизненный цикл встроенного приложения, BFF-паттерн (Backend-for-Frontend) и скелеты обработчика на Node, Python и Go — [Авторизация в приложении на BlackHole](./infra/app-runtime.md). ## Передача ключа Ключ передаётся в заголовке `X-Api-Key`: ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/deals ``` Клиенты, которые умеют отправлять только `Authorization: Bearer` (например, OpenAI-совместимые), могут передать сам API-ключ (`vibe_api_…`) в этом заголовке вместо `X-Api-Key` — для ключа оба заголовка равнозначны. Это работает на всех V1-эндпоинтах, включая бот-платформу: ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/bots ``` У ключа авторизации (`vibe_app_…`) заголовок `Authorization: Bearer` занят токеном сессии, поэтому сам ключ всегда идёт в `X-Api-Key` (см. ниже). Для ключа авторизации (`vibe_app_`) дополнительно передаётся токен сессии в заголовке `Authorization: Bearer`: ```bash curl -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ https://vibecode.bitrix24.tech/v1/deals ``` Если для ключа `vibe_app_` не передан `Authorization: Bearer`, эндпоинты, которым нужен пользовательский контекст, возвращают `401 TOKEN_MISSING`: у запроса нет данных, от чьего имени обращаться к Битрикс24. Эндпоинты `/v1/me` и `/v1/oauth/*` работают без `Bearer`. **Токен сессии живёт 24 часа и не обновляется.** `POST /v1/oauth/token` (и `GET /v1/oauth/poll`) выдают `access_token` с `expires_in: 86400` — без `refresh_token` и без grant'а обновления. Механизма «тихого» продления нет — это сознательное решение. После истечения 24 часов получите новый токен сессии, заново пройдя OAuth-флоу: `GET /v1/oauth/authorize` → `POST /v1/oauth/token`. До истечения вызовы за пользователя возвращают `401 TOKEN_EXPIRED` — это сигнал заново авторизоваться. Для фоновых сценариев — `cron`, серверные интеграции, скрипты без пользователя у экрана, которому нечем пройти авторизацию заново каждые 24 часа — используйте персональный API-ключ (`vibe_api_…`): он работает от лица владельца ключа без токена сессии, и единственное ограничение по сроку — собственный «срок действия» ключа (см. выше). Ключ авторизации (`vibe_app_…`) предназначен для приложений, где пользователь присутствует и проходит OAuth. Самоописание `/v1/me` отвечает в двух режимах: | Заголовки | `currentUser` в ответе | Когда применимо | |-----------|------------------------|-----------------| | только `X-Api-Key` | `null` | Server-to-server обращения и bootstrap приложения до OAuth. Поля `portal`, `tariff`, `trial`, `capabilities`, `scopes`, `api` и список доступных эндпоинтов — те же. | | `X-Api-Key` + `Authorization: Bearer vibe_session_*` | объект `{ bitrixUserId, _note }` | Запрос за конкретного пользователя — после редиректа Gateway или ручного OAuth-флоу. Все остальные поля — те же, что и без `Bearer`. | Верхний уровень ответа одинаковый в обоих режимах — отличает только заполненность поля `currentUser`. Поле `capabilities.servers.create.available` тоже зависит от режима: для `vibe_app_` ключа без сессии возвращается `false` с причиной `SESSION_REQUIRED`, потому что инфраструктурные `POST`-эндпоинты требуют пользовательский контекст. Эндпоинты создания инфраструктуры (`POST /v1/infra/servers`, а также `POST /api/agents` и `POST /api/managed-bots` через личный кабинет) требуют, чтобы платформа точно знала **кто** создаёт сервер — это нужно для тарифной проверки и учёта в лимитах. Для ключей `vibe_app_` это значит наличие `Authorization: Bearer `; без сессии ответ — `401 UNAUTHENTICATED` с `error.hint`, в котором указан рабочий вариант (пройти OAuth-флоу или использовать персональный ключ `vibe_api_`). На чтение (`GET /v1/infra/servers`, `GET /v1/me`) сессия не нужна. ## Жизненный цикл ключа ``` Создание → Активен → Перевыпуск / Отзыв / Удаление ``` ### Состояния ключа | Состояние | Значение в API | Описание | |-----------|----------------|----------| | **Активен** | `ACTIVE` | Ключ готов к использованию | | **Истёк** | `EXPIRED` | Срок действия ключа прошёл | | **Отозван** | `REVOKED` | Ключ деактивирован, запросы отклоняются | ### Перевыпуск Перевыпуск создаёт новый ключ и оставляет старому переходный период 24 часа — это позволяет обновить ключ в приложениях без простоя: 1. Запустите перевыпуск в личном кабинете. 2. Получите новый ключ. 3. Обновите ключ в своих приложениях. 4. Старый ключ действует ещё 24 часа. 5. По истечении переходного периода старый ключ становится недействительным. ### Отзыв и удаление Отзыв переводит ключ в состояние `REVOKED`: последующие запросы отклоняются с `401 KEY_INACTIVE`. Если на ключе есть активные серверы, удаление возвращает `409 KEY_HAS_ACTIVE_SERVERS` — сначала удалите серверы. ### Если ключ скомпрометирован 1. Отзовите ключ в личном кабинете. 2. Создайте новый ключ с теми же скоупами. 3. Обновите ключ во всех приложениях. 4. Проверьте журнал запросов на обращения с неизвестных адресов. 5. Включите список разрешённых IP. ## Рекомендации по безопасности - Храните ключи в переменных окружения или менеджере секретов, не в коде и не в git. - Не передавайте ключи через мессенджеры и почту. - Назначайте ключу только необходимые скоупы — подбор набора описан на странице [Скоупы](./scopes.md). - Заводите отдельный ключ для каждого сервиса и отзывайте неиспользуемые. - Для серверных интеграций включайте список разрешённых IP и конечный срок действия. - Перевыпускайте ключи по расписанию (например, раз в 90 дней). ## Технические подробности Ниже — детали для AI-моделей и продвинутых интеграций. ### Самоописание ключа (`/v1/me`) `GET /v1/me` возвращает тип ключа, портал, скоупы, лимиты и карту доступных эндпоинтов. Это основная точка входа для AI-моделей: достаточно передать модели ключ и ссылку `https://vibecode.bitrix24.tech/v1/me`. ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/me ``` Ответ для API-ключа (`vibe_api_`), показаны характерные поля: ```json { "success": true, "data": { "type": "personal", "portal": "mycompany.bitrix24.ru", "scopes": ["crm", "tasks", "user", "vibe:infra", "vibe:ai", "vibe:search", "vibe:storage"], "rateLimit": { "requestsPerSecond": 10 }, "auth": { "personalKey": "X-Api-Key: vibe_api_… (no Bearer)", "oauthKey": "X-Api-Key: vibe_app_… + Authorization: Bearer " }, "owner": { "name": "Иван Петров", "userId": "1" }, "expiresAt": null } } ``` Кроме показанных полей ответ содержит разделы `api` (карта доступных эндпоинтов и сущностей), `capabilities`, `tariff` и `errorCodes` — модель использует их, чтобы построить запросы без чтения остальной документации. Ответ для ключа авторизации (`vibe_app_`): ```json { "success": true, "data": { "type": "oauth_app", "portal": "mycompany.bitrix24.ru", "scopes": ["crm", "tasks"], "app": { "title": "CRM Dashboard", "id": "f2342f7a-…" }, "oauth": { "authorizeUrl": "https://vibecode.bitrix24.tech/v1/oauth/authorize?app_key=vibe_app_…", "authorizeUrlNote": "Template URL — append required query params before redirecting the user…", "requiredParams": { "state": { "required": true, "minLength": 16, "maxLength": 512 }, "redirect_uri": { "required": false }, "scope": { "required": false } }, "tokenUrl": "https://vibecode.bitrix24.tech/v1/oauth/token", "revokeUrl": "https://vibecode.bitrix24.tech/v1/oauth/revoke" }, "auth": { "header": "X-Api-Key: + Authorization: Bearer ", "steps": [ "1. Redirect user to oauth.authorizeUrl + state (+ redirect_uri)", "2. Exchange code for session token", "3. Call API with both headers" ], "gatewayInjected": { "description": "Для приложения, встроенного в Битрикс24 через placement и работающего за BlackHole, Gateway сам аутентифицирует пользователя и инжектирует заголовок на каждый запрос. Браузер токен не видит.", "header": "X-Vibe-Authorization: Bearer vibe_session_*", "docs": "https://vibecode.bitrix24.tech/docs/infra/app-runtime" } } } } ``` > ⚠ **`oauth.authorizeUrl` — это шаблон, а не готовая ссылка.** Эндпоинт `/v1/oauth/authorize` требует обязательный параметр `state` (16–512 символов) — это CSRF-токен по RFC 6749 §10.12, который **генерирует клиент**: создайте криптослучайную строку, добавьте её в URL и сверьте значение, вернувшееся в callback. Сервер не может сгенерировать `state` за вас — иначе защита от CSRF не работает. Открытие `authorizeUrl` как есть вернёт `400 INVALID_REQUEST "state: Required"`. Опционально добавьте `redirect_uri` (ваш callback; без него используется встроенная страница `/oauth/complete`) и `scope`. Пример полной ссылки: > > ``` > https://vibecode.bitrix24.tech/v1/oauth/authorize?app_key=vibe_app_…&state=aAbBcCdDeEfFgGhH&redirect_uri=https://myapp.com/callback > ``` Структура ответа для менеджмент-ключа отличается — она описана на странице [Менеджмент-ключи](./management-keys.md#get-v1me--самоописание-ключа). ### Полная передача ключа Ключ можно передать через `Authorization: Bearer ` без заголовка `X-Api-Key` — этот вариант поддерживается для OpenAI-совместимых клиентов. При вызове через OAuth-приложение токен сессии в этом случае передать нельзя, поэтому способ применим только к ключам `vibe_api_` и `vibe_live_`. Для приложения, встроенного в Битрикс24 как `placement` и работающего за BlackHole, токен сессии не приходит ни в адресе, ни в теле — Gateway сам аутентифицирует пользователя и инжектирует заголовок `X-Vibe-Authorization: Bearer vibe_session_*` на каждый запрос к серверу приложения. Браузер не видит и не хранит токен (`sessionStorage` остаётся пустым). Идентификатор пользователя приложение читает одним вызовом `GET /v1/me`, передавая `Authorization: Bearer` из заголовка `X-Vibe-Authorization`: в ответе будет `currentUser.bitrixUserId` (числовой ID пользователя Битрикс24) и `portal` (домен портала на верхнем уровне). Полный жизненный цикл запроса, BFF-паттерн (Backend-for-Frontend) и скелеты обработчика на Node/Python/Go — [Авторизация в приложении на BlackHole](./infra/app-runtime.md). ## Лимиты запросов К каждому ключу одновременно применяются две независимые системы лимитов: лимит платформы Вайбкод и лимит портала Битрикс24. ### Лимит платформы Вайбкод | Параметр | Значение | |----------|----------| | Лимит запросов | 300 запросов в минуту на источник | | Окно лимита | Скользящее окно 60 секунд | | Заголовок лимита | `X-RateLimit-Limit` | | Заголовок остатка | `X-RateLimit-Remaining` | | Заголовок сброса | `X-RateLimit-Reset` (секунды до сброса окна) | При превышении возвращается `429 Too Many Requests` с кодом `RATE_LIMITED`. ``` X-RateLimit-Limit: 300 X-RateLimit-Remaining: 245 X-RateLimit-Reset: 25 ``` ### Лимит портала Битрикс24 Портал ограничивает скорость обращений (по умолчанию около 10 запросов в секунду, лимит делится между всеми ключами портала). При превышении возвращается `502 BITRIX_UNAVAILABLE`. Действующее для ключа значение возвращает `GET /v1/me` в поле `rateLimit.requestsPerSecond`. Один вызов считается за единицу. Один `POST /v1/batch` с 50 операциями расходует одну единицу — это самый экономный способ уложиться в лимит. ### Рекомендации при лимитах - Объединяйте запросы через `POST /v1/batch` (до 50 операций за вызов). - Кэшируйте данные, которые меняются редко. - При `429` повторяйте запрос с увеличением паузы (1 с → 2 с → 4 с). - Опирайтесь на заголовки `X-RateLimit-*`, чтобы не доводить до отказа. ### Коды ошибок ключа | HTTP | Код | Когда возвращается | |------|-----|---------------------| | 401 | `KEY_INACTIVE` | Ключ в состоянии `REVOKED` или `EXPIRED` | | 401 | `KEY_EXPIRED` | У ключа задан срок действия, и он прошёл | | 401 | `INVALID_API_KEY` | Ключ не найден | | 401 | `TOKEN_MISSING` | Для ключа `vibe_app_` не передан `Authorization: Bearer` | | 403 | `IP_NOT_ALLOWED` | Запрос с адреса вне списка разрешённых IP | | 403 | `WRITE_BLOCKED_READONLY_KEY` | У ключа задан режим «только чтение», а вызов выполняет запись — [Режим доступа](#режим-доступа) | Полный справочник кодов — [Коды ошибок](./errors.md). ## Режим доступа У каждого ключа есть отдельное поле `accessMode` — оно отвечает за то, разрешает ли ключ запись, или ограничивает его операциями чтения. Это независимая от скоупов настройка: скоупы определяют, к каким разделам данных у ключа есть доступ, а режим доступа — может ли ключ менять эти данные. ### Два режима | Режим | Значение в API | Что разрешено | |-------|----------------|---------------| | **Чтение и запись** | `READWRITE` | Все операции — чтение и запись. Значение по умолчанию для новых ключей. | | **Только чтение** | `READONLY` | Чтение разрешено. Любая попытка записи возвращает `403 WRITE_BLOCKED_READONLY_KEY`. | Какие вызовы попадают под блокировку в режиме `READONLY`: - **API-ключи и ключи авторизации (`vibe_api_`, `vibe_app_`)** — блокируется любой запрос, который проксируется в Битрикс24 как операция записи: создание, обновление, удаление, действия над сущностями. `GET`-запросы и операции агрегации (`POST /v1//aggregate`) выполняются без ограничений. - **Менеджмент-ключи (`vibe_live_`)** — блокировка идёт по HTTP-методу: `POST`, `PATCH`, `PUT`, `DELETE` отклоняются, `GET` и `HEAD` проходят. Это значит, что менеджмент-ключ в режиме «только чтение» не может создавать новые ключи, менять портал или отправлять обратную связь, но может читать настройки и журнал событий. Эндпоинт `GET /v1/me` возвращает действующий режим ключа в поле `data.accessMode`: ```json { "success": true, "data": { "type": "personal", "portal": "mycompany.bitrix24.ru", "accessMode": "READONLY", "scopes": ["crm", "tasks"] } } ``` ### Изменение режима Владелец ключа меняет режим в личном кабинете в разделе [Ключи API](/keys): 1. Откройте карточку нужного ключа. 2. В блоке **Режим доступа** выберите «Только чтение» или «Чтение и запись». 3. Сохраните изменения — режим применяется к следующему запросу. Перевыпуск не нужен — режим меняется у действующего ключа без замены значения. При создании нового ключа режим задаётся отдельным переключателем в форме. Администратор портала видит чужие ключи в общем списке и может изменить режим любого ключа на портале. После сохранения владелец получает сообщение от Companion-бота с информацией о том, что режим его ключа был изменён администратором. ### Политика портала по умолчанию Администратор задаёт режим, который применяется ко всем новым ключам портала. Настройка живёт в разделе [Ключи API](/keys) в блоке «Политика портала по умолчанию» и видна только администраторам. Возможные значения: - **Чтение и запись (`READWRITE`)** — значение по умолчанию для портала. Любой пользователь создаёт ключи с любым режимом на своё усмотрение. - **Только чтение (`READONLY`)** — обычные участники портала могут создавать только ключи с режимом «только чтение». Попытка выпустить ключ с режимом `READWRITE` отклоняется с кодом `403 KEY_POLICY_READONLY_REQUIRED`. Администратор портала не подпадает под это ограничение и при необходимости создаёт ключи с записью или меняет режим чужого ключа в его карточке. Существующие ключи политика портала не затрагивает — она применяется только в момент создания нового ключа. Для уже выпущенных ключей администратор меняет режим вручную в карточке ключа. ### Пример ответа при блокировке записи `POST /v1/leads` с ключом в режиме `READONLY` возвращает `403`: ```json { "success": false, "error": { "code": "WRITE_BLOCKED_READONLY_KEY", "message": "Key is in read-only mode. Switch to read+write in /keys to enable writes.", "details": { "method": "crm.item.add", "keyName": "MCP key", "currentMode": "READONLY", "switchUrl": "/keys" } } } ``` Поле `details.method` присутствует только в ответе на блокировку при проксировании в Битрикс24 — оно содержит имя метода, который был бы вызван при успешной записи. Для менеджмент-ключей `details.method` не возвращается: в блокировке участвует только HTTP-метод запроса. Подробное описание кода ошибки, причины срабатывания и шаги для разблокировки — [`WRITE_BLOCKED_READONLY_KEY`](./errors.md#write_blocked_readonly_key-403). ## Смотрите также - [Скоупы](./scopes.md) - [Быстрый старт](./quickstart.md) - [Менеджмент-ключи](./management-keys.md) - [Коды ошибок](./errors.md) --- # Обзор API Вайбкод предоставляет единый REST-интерфейс для работы с сущностями Битрикс24: CRM, задачи, пользователи, календарь, диск, каталог, документооборот и другие. Все сущности имеют одинаковый набор операций. > Базовый URL: `https://vibecode.bitrix24.tech` > Авторизация: заголовок `X-Api-Key: ваш_ключ` ## Доступные операции Каждая сущность поддерживает стандартный набор операций. Путь строится по шаблону `/v1/{entity}`. ### Список — `GET /v1/{entity}` Получить записи с пагинацией, сортировкой и выборкой полей. ```bash curl -H "X-Api-Key: $KEY" \ "https://vibecode.bitrix24.tech/v1/deals?limit=100&offset=0" ``` Параметры: | Параметр | Тип | Описание | |----------|-----|---------| | `limit` | number | Количество записей (по умолчанию 50, максимум 5000) | | `offset` | number | Пропустить N записей | | `select` | string[] | Выборка полей: `?select=id,title,amount` | | `order` | object | Сортировка: `?order[createdAt]=desc` | **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 и возвращает все записи в одном ответе. ### Получить по ID — `GET /v1/{entity}/{id}` ```bash curl -H "X-Api-Key: $KEY" \ "https://vibecode.bitrix24.tech/v1/deals/123" ``` Ответ: `{ success: true, data: { id: 123, title: "...", ... } }` ### Создать — `POST /v1/{entity}` ```bash curl -X POST -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ "https://vibecode.bitrix24.tech/v1/deals" \ -d '{"title": "Новая сделка", "stageId": "NEW", "amount": 150000}' ``` Ответ: `{ success: true, data: { id: 456, ... } }` (HTTP 201) ### Обновить — `PATCH /v1/{entity}/{id}` ```bash curl -X PATCH -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ "https://vibecode.bitrix24.tech/v1/deals/123" \ -d '{"stageId": "WON", "amount": 200000}' ``` ### Удалить — `DELETE /v1/{entity}/{id}` ```bash curl -X DELETE -H "X-Api-Key: $KEY" \ "https://vibecode.bitrix24.tech/v1/deals/123" ``` ### Поиск — `POST /v1/{entity}/search` Поиск с фильтрацией. Подробнее о синтаксисе фильтров: [Фильтрация](./filtering.md) ```bash curl -X POST -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ "https://vibecode.bitrix24.tech/v1/deals/search" \ -d '{"filter": {"stageId": "NEW", "amount": {"$gte": 100000}}, "sort": {"createdAt": "desc"}, "limit": 200}' ``` Параметры: | Параметр | Тип | Описание | |----------|-----|---------| | `filter` | object | Условия фильтрации ([три синтаксиса](./filtering.md)) | | `sort` | string \| object \| array | Сортировка. Поддерживаются: `"id"` / `"-amount"` / `"id,-createdAt"` (string), `{ id: "asc", amount: "desc" }` или `{ id: 1, amount: -1 }` (object), `["id", "-amount"]` (array). Невалидный тип → `400 INVALID_SORT_TYPE`. Подробнее про пагинацию — см. [filtering.md](./filtering.md#pagination-patterns). | | `limit` | number | Количество записей (по умолчанию 50, максимум 5000, авто-пагинация при > 50) | | `offset` | number | Пропустить N записей | | `autoWindow` | boolean | `false` — отключить разбивку по дате для больших выборок | **Windowed search:** для больших наборов данных поиск автоматически разбивает запрос на временные окна. Если это вызывает таймауты — отключите через `autoWindow: false`. ### Агрегация — `POST /v1/{entity}/aggregate` Подсчёт количества и числовые агрегации (`sum`, `avg`, `min`, `max`) с фильтрацией. ```bash curl -X POST -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "stageId": "WON" } }' \ "https://vibecode.bitrix24.tech/v1/deals/aggregate" ``` Параметры (body): | Параметр | Тип | Описание | |----------|-----|---------| | `aggregate` | array | Массив агрегаций: `{ "field": "amount", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без массива — только `count` | | `filter` | object | Фильтрация по полям сущности | | `groupBy` | string \| string[] | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка `aggregatable` конкретной сущности. Для entities без `aggregatable` (items, requisites) параметр не поддерживается | > **Как это работает:** `count` считается одним быстрым вызовом в Битрикс24. Для `sum`/`avg`/`min`/`max` платформа подгружает записи под фильтр (до 5000 — больше помечается `meta.truncated: true`) и считает на стороне Вайбкод. При невалидном поле ответ содержит список доступных. > **Пользовательские поля (UF)** поддерживаются в `sum`/`avg`/`min`/`max` для UF-типов `integer`, `double`, `money`. `groupBy` принимает UF-поля любого типа. Подробно — в разделе [Агрегация POST — UF-поля](#агрегация-post-uf-поля) ниже. > **Смарт-процессы (items)** используют path-параметр: `POST /v1/items/:entityTypeId/aggregate`. Зарезервированные `entityTypeId` (1, 2, 3, 4, 7, 31) обслуживаются специализированными API сделок, лидов, контактов, компаний, предложений, счетов. ### Агрегация POST — UF-поля Канонический POST-вариант агрегации принимает массив выражений и поддерживает пользовательские поля (`UF_CRM_*`, `ufCrm_*`). ```bash curl -X POST https://vibecode.bitrix24.tech/v1/deals/aggregate \ -H "X-Api-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "function": "sum", "field": "amount" }, { "function": "sum", "field": "UF_CRM_BUDGET" }, { "function": "avg", "field": "UF_CRM_SCORE" } ], "groupBy": "UF_CRM_PRIORITY" }' ``` **Правила UF-поддержки:** | Функция | Принимает UF-типы | |---------|-------------------| | `sum`, `avg`, `min`, `max` | только `integer`, `double`, `money` | | `groupBy` | любой UF-тип (string, enumeration, date, integer, …) | **Money-поля** хранятся в Битрикс24 как строка `"сумма|валюта"` (например `"1500.50|RUB"`). Агрегат извлекает числовую часть до `|` — все арифметические операции корректны. **Ошибки:** | HTTP | Код | Когда | |------|-----|-------| | 400 | `INVALID_PARAMS` | UF-тип не из списка `integer`/`double`/`money` для `sum`/`avg`/`min`/`max` — в `message` указан фактический тип | | 400 | `INVALID_PARAMS` | Поле не найдено ни в схеме, ни в UF-кэше — в `message` перечислены доступные стандартные и UF-поля | **Кэш UF-полей:** одно обращение к `crm.{entity}.fields` на комбинацию `портал+сущность` (+entityTypeId для items). TTL 5 минут — повторные агрегаты в пределах окна не вызывают дополнительных запросов. ### Схема полей — `GET /v1/{entity}/fields` Получить описание всех полей сущности с типами. ```bash curl -H "X-Api-Key: $KEY" \ "https://vibecode.bitrix24.tech/v1/deals/fields" ``` ### Пакетные операции — `POST /v1/{entity}/batch` Массовое создание, обновление или удаление записей одной сущности. ```json { "action": "create", "items": [{ "title": "Сделка 1" }, { "title": "Сделка 2" }] } ``` Для работы с **разными сущностями** в одном запросе используйте [Batch API](./batch.md). ## Формат ответа Все эндпоинты возвращают единый формат: ```json { "success": true, "data": [ ... ], "total": 150, "meta": { "hasMore": true } } ``` | Поле | Описание | |------|---------| | `success` | `true` при успешном выполнении | | `data` | Массив записей (list/search) или объект (get/create) | | `total` | Общее количество записей (для list/search) | | `meta.hasMore` | Есть ли ещё записи для загрузки | ## Преобразование полей Вайбкод автоматически преобразует имена полей при отправке запроса. В запросах всегда используйте camelCase: ```json { "title": "Сделка", "stageId": "NEW", "assignedById": 1 } ``` В ответах формат полей зависит от Bitrix24 API конкретной сущности: | Формат ответа | Сущности | Пример ответа | |---------------|----------|---------------| | camelCase | CRM (deals, contacts, companies, leads, quotes, invoices), **tasks**, catalog, sale, documents, bookings | `{ "id": 1, "title": "Сделка", "stageId": "NEW" }` | | UPPER_CASE (только сырые/недекларированные поля) | users, departments, files, folders, calendar-events, activities, workgroups | `{ "ID": 1, "NAME": "…" }` | > Сущности с объявленной схемой полей (включая **tasks**) возвращают **описанные** поля в camelCase (`id`/`title`/`status`/`responsibleId`/…). `tasks` ранее ошибочно числилась в UPPER_CASE-строке — её ответы `list`/`get` полностью camelCase. UPPER_CASE-форму могут сохранять только сырые/недекларированные поля сущностей из второй строки. ## Пользовательские поля (UF) Пользовательские поля передаются и возвращаются **без преобразования имени**. Поддерживаются оба формата Bitrix24: - Старый API: `UF_CRM_1234567890` - SPA API: `ufCrm_1234567890` ```json { "UF_CRM_1234567890": "значение" } ``` Имя поля в ответе совпадает с тем, что возвращает Bitrix24. Для получения списка пользовательских полей используйте `GET /v1/userfields/:entity`. Управление пользовательскими полями: [Custom Fields](./userfields.md) ## Особые сущности ### Smart Processes (Items) Смарт-процессы используют `entityTypeId` в URL: `GET /v1/items/{entityTypeId}`. ```bash # Список записей смарт-процесса с entityTypeId = 1058 curl -H "X-Api-Key: $KEY" \ "https://vibecode.bitrix24.tech/v1/items/1058?limit=10" ``` Список доступных смарт-процессов: `GET /v1/smart-processes`. ### Calendar Events Требуют обязательные параметры: `type` (user/group/company) и `ownerId`. ```bash curl -H "X-Api-Key: $KEY" \ "https://vibecode.bitrix24.tech/v1/calendar-events?type=user&ownerId=1" ``` ### Files Требуют `folderId`. Получите его из `GET /v1/storages` → поле `rootFolderId`. ## Rate Limit 10 запросов/секунду — лимит Битрикс24 на уровне портала, общий для всех ключей. **Как укладываться в лимит:** - [Batch API](./batch.md) — 50 вызовов за 1 единицу лимита - `POST /v1/{entity}/batch` — до 500 записей CRUD за 10 единиц (а не за 500) - `POST /v1/{entity}/aggregate` — `count` идёт одним быстрым вызовом; `sum`/`avg`/`min`/`max` подгружают до 5000 записей и считаются на стороне Вайбкод - Параметр `select` — загрузка только нужных полей сокращает объём ответа Подробнее: [Оптимизация](./optimization.md) — паттерны для дашбордов, массовых операций, сканирования больших объёмов ## Паттерны использования | Задача | Подход | |--------|--------| | Дашборд / аналитика | `POST /v1/{entity}/aggregate` — счётчики и суммы по фильтру | | Массовое обновление | `POST /v1/{entity}/batch` с action=update | | Данные из нескольких сущностей | `POST /v1/batch` — deals + tasks + contacts в 1 запросе | | Запись + связанные данные | `?include=company,contact` — [связанные данные](./includes.md) в одном ответе | | Сканирование 1000+ записей | `POST /v1/{entity}/search` с limit + offset | ## Связанные разделы - [Связанные данные (include)](./includes.md) — загрузка связанных сущностей в одном запросе - [Фильтрация](./filtering.md) — три синтаксиса фильтров, даты, NOT-фильтры - [Batch API](./batch.md) — до 50 вызовов в одном запросе - [Все сущности](./entities-index.md) — полный список сущностей со ссылками - [Оптимизация](./optimization.md) — rate limits, паттерны производительности - [Коды ошибок](./errors.md) — справочник ошибок платформы --- # Фильтрация и поиск Три синтаксиса фильтрации для API сущностей. Все стили можно **смешивать** в одном запросе. > Фильтрация работает в двух местах: > - `GET /v1/{entity}?filter[field]=value` — параметр URL для списка > - `POST /v1/{entity}/search` — тело запроса `{ "filter": { ... } }` **Быстрый переход:** [Логика ИЛИ](#логика-или) · [Эндпоинт поиска](#эндпоинт-поиска) · [Постраничный вывод](#постраничный-вывод) · [Коды ошибок](#коды-ошибок) ## Синтаксис 1: операторы со знаком `$` Операторы с префиксом `$` внутри объекта поля. Форма удобна AI-агентам. ```json { "filter": { "amount": { "$gte": 50000 }, "stageId": { "$ne": "LOST" }, "createdAt": { "$gte": "2026-01-01T00:00:00" } } } ``` Найдёт записи с суммой от 50 000, стадией, отличной от LOST, созданные с начала 2026 года. ### Доступные операторы | Оператор | Значение | Пример | |----------|---------|--------| | `$gt` | > (больше) | `{ "amount": { "$gt": 10000 } }` | | `$gte` | >= (больше или равно) | `{ "amount": { "$gte": 50000 } }` | | `$lt` | < (меньше) | `{ "amount": { "$lt": 100000 } }` | | `$lte` | <= (меньше или равно) | `{ "amount": { "$lte": 200000 } }` | | `$ne` | != (не равно) | `{ "stageId": { "$ne": "LOST" } }` | | `$contains` | поиск по подстроке | `{ "title": { "$contains": "поставка" } }` | | `$in` | входит в массив | `{ "stageId": { "$in": ["NEW", "WON"] } }` | Точное совпадение задаётся значением напрямую, без оператора: `{ "stageId": "NEW" }`. ### Комбинирование Несколько условий на одном поле объединяются логикой И. Условия на разные поля — тоже логикой И. Для ИЛИ-логики см. раздел [Логика ИЛИ](#логика-или) ниже. ```json { "filter": { "amount": { "$gte": 50000, "$lte": 200000 }, "stageId": { "$ne": "LOST" } } } ``` Найдёт записи с суммой от 50 000 до 200 000 и стадией, отличной от LOST. ## Синтаксис 2: префикс в имени поля Оператор как часть имени поля. Форма, которую напрямую понимает Битрикс24. ```json { "filter": { ">=amount": 50000, "<=amount": 200000, "!stageId": "LOST" } } ``` Найдёт записи с суммой от 50 000 до 200 000 и стадией, отличной от LOST. ### Операторы | Префикс | Значение | |---------|---------| | `>=` | больше или равно | | `>` | больше | | `<=` | меньше или равно | | `<` | меньше | | `!` | не равно | | `%` | подстрока | ## Синтаксис 3: оператор как ключ объекта Оператор как ключ вложенного объекта. Та же форма, что в синтаксисе 2, но с разделением имени поля и условия. ```json { "filter": { "amount": { ">=": 50000 }, "stageId": { "!": "LOST" } } } ``` Найдёт записи с суммой от 50 000 и стадией, отличной от LOST. ## Фильтрация по дате Поля даты (`createdAt`, `updatedAt`, `closedAt`, `beginDate` и др.) принимают строки **ISO 8601**: ```json { "filter": { "createdAt": { "$gte": "2026-01-01T00:00:00" }, "closedAt": { "$lte": "2026-03-31T23:59:59" } } } ``` Найдёт записи, созданные с начала 2026 года и закрытые до конца марта. ### Примеры ```json { "filter": { ">=createdAt": "2026-03-01T00:00:00" } } ``` Найдёт записи, созданные с 1 марта 2026. ```json { "filter": { "updatedAt": { "$gte": "2026-05-01T00:00:00" } } } ``` Найдёт записи, обновлённые с указанного момента. ## NOT-фильтры Исключение значений: ```json { "filter": { "stageId": { "$ne": "LOST" } } } ``` ```json { "filter": { "!stageId": "LOST" } } ``` ```json { "filter": { "stageId": { "!": "LOST" } } } ``` Все три варианта найдут записи, у которых стадия отличается от LOST. ## Логика ИЛИ Все условия в объекте `filter` объединяются логикой И. Логический оператор ИЛИ между разными полями нельзя выразить прямо в `filter` — попытка передать `LOGIC: "OR"` или `$or` возвращает `400 INVALID_FILTER_OPERATOR`. Ниже три способа получить тот же результат. ### Способ 1: `$in` — несколько значений одного поля Когда нужно «поле равно A **или** B **или** C», используйте оператор `$in` из таблицы выше: ```json { "filter": { "stageId": { "$in": ["NEW", "WON"] } } } ``` Найдёт сделки в стадии NEW или WON. Оператор работает на любом поле, для которого имеет смысл точное сравнение: `assignedById`, `categoryId`, `id`, `sourceId` и так далее. ### Способ 2: Batch — несколько фильтров одним запросом Когда условия ИЛИ затрагивают разные поля («сделки в стадии NEW **или** с суммой больше 100 000»), вынесите каждое условие в отдельный вызов внутри [Batch API](./batch.md): ```json { "calls": [ { "id": "by_stage", "entity": "deals", "action": "list", "params": { "filter": { "stageId": "NEW" }, "limit": 200 } }, { "id": "by_amount", "entity": "deals", "action": "list", "params": { "filter": { "amount": { "$gte": 100000 } }, "limit": 200 } } ] } ``` Ответ придёт в форме `data.results.by_stage` и `data.results.by_amount` — два независимых массива, которые клиент объединяет самостоятельно. ### Способ 3: параллельные запросы + клиентская склейка Когда нужен единый список без дубликатов, выполните вызовы параллельно и объедините результаты по `id`: ```js const [a, b] = await Promise.all([ fetch('/v1/deals/search', { method: 'POST', headers: { 'X-Api-Key': key, 'Content-Type': 'application/json' }, body: JSON.stringify({ filter: { stageId: 'NEW' }, limit: 200 }), }), fetch('/v1/deals/search', { method: 'POST', headers: { 'X-Api-Key': key, 'Content-Type': 'application/json' }, body: JSON.stringify({ filter: { stageId: 'WON' }, limit: 200 }), }), ]) const { data: dataA } = await a.json() const { data: dataB } = await b.json() const byId = new Map(dataA.map(d => [d.id, d])) for (const d of dataB) byId.set(d.id, d) const merged = [...byId.values()] ``` `Map` по `id` устраняет повторы, если запись попадает под оба условия. ### Чего делать нельзя ```json { "filter": { "LOGIC": "OR", "0": { "stageId": "NEW" }, "1": { "stageId": "WON" } } } ``` Ответ: ```json { "success": false, "error": { "code": "INVALID_FILTER_OPERATOR", "message": "Unknown filter operator: stageId. Supported: $gt, $gte, $lt, $lte, $ne, $contains, $in, >, >=, <, <=, !, %, !=" } } ``` Аналогично попытка передать `$or` возвращает `400` с подсказкой использовать Batch API. ## Смешивание синтаксисов Все три стиля можно комбинировать в одном фильтре: ```json { "filter": { "amount": { "$gte": 50000 }, "!stageId": "LOST", "createdAt": { ">=": "2026-01-01T00:00:00" } } } ``` Найдёт записи с суммой от 50 000, стадией, отличной от LOST, созданные с начала 2026 года. Здесь все три синтаксиса используются вместе. ## Эндпоинт поиска `POST /v1/{entity}/search` — полнофункциональный поиск: ```bash curl -X POST -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ "https://vibecode.bitrix24.tech/v1/deals/search" \ -d '{ "filter": { "stageId": { "$ne": "LOST" }, "amount": { "$gte": 100000 } }, "sort": { "amount": "desc" }, "limit": 200 }' ``` | Параметр | Тип | Описание | |----------|-----|---------| | `filter` | object | Условия фильтрации | | `sort` | string, object или array | Сортировка. Принимаются три формы: строка (`"id"` / `"-amount"` / `"id,-createdAt"`), объект (`{ id: "asc", amount: "desc" }` — ключи в порядке вставки) или массив (`["id", "-amount"]`). Вместо `asc`/`desc` принимаются `1`/`-1`. Некорректный тип возвращает `400 INVALID_SORT_TYPE`, неизвестное направление — `INVALID_SORT_DIRECTION`. | | `limit` | number | Количество записей (по умолчанию 50, максимум 5000) | | `offset` | number | Пропустить N записей | | `autoWindow` | boolean | `false` — отключить разбивку по дате | ## Коды ошибок | HTTP | Код | Условие | |------|-----|---------| | 400 | `INVALID_FILTER_OPERATOR` | Неизвестный оператор в значении поля или попытка передать `LOGIC` / `$or` | | 400 | `INVALID_FILTER_FIELD` | Имя поля начинается с `@` — такой префикс не поддерживается | | 400 | `UNKNOWN_FILTER_FIELD` | Поле отсутствует в схеме сущности (для сущностей с camelCase-полями) | | 400 | `INVALID_SORT_TYPE` | `sort` не строка, не объект и не массив | | 400 | `INVALID_SORT_DIRECTION` | Направление сортировки не `asc` / `desc` / `1` / `-1` | | 400 | `UNSTABLE_OFFSET_PAGINATION` | `offset > 0` при широком диапазоне дат (см. [Постраничный вывод](#постраничный-вывод)) | | 502 | `WINDOWED_SEARCH_FAILED` | Сервис не смог получить часть результатов при автоматической пагинации — повторите запрос | Полный список общих ошибок API — [Коды ошибок](./errors.md). ## Примеры по сущностям ### Сделки — по стадии и сумме ```json { "filter": { "stageId": "NEW", "amount": { "$gte": 100000 } }, "sort": { "createdAt": "desc" } } ``` Найдёт сделки в стадии NEW с суммой от 100 000, отсортированные по дате создания (новые первыми). ### Контакты — по телефону ```json { "filter": { "phone": { "$contains": "+7916" } } } ``` Найдёт контакты, у которых номер телефона содержит подстроку «+7916». ### Задачи — незакрытые ```json { "filter": { "status": { "$ne": 5 } } } ``` Найдёт все задачи со статусом, отличным от 5 (завершена). Статусы: 2 = ждёт выполнения, 3 = выполняется, 4 = ожидает контроля, 5 = завершена, 6 = отложена. ### Лиды — за период ```json { "filter": { "createdAt": { "$gte": "2026-01-01T00:00:00", "$lte": "2026-03-31T23:59:59" } } } ``` Найдёт лиды, созданные в первом квартале 2026 года. ### Календарные события ```json { "filter": { "dateFrom": { "$gte": "2026-04-01T00:00:00" } } } ``` Найдёт события с датой начала от 1 апреля 2026. Для `calendar-events` обязательны параметры `type` и `ownerId` в URL: `/v1/calendar-events?type=user&ownerId=1`. ## Фильтрация в Batch Фильтры работают и в [Batch API](./batch.md): ```json { "calls": [ { "id": "new_deals", "entity": "deals", "action": "list", "params": { "filter": { "stageId": "NEW" } } }, { "id": "search_contacts", "entity": "contacts", "action": "search", "params": { "filter": { "phone": { "$contains": "+7" } } } } ] } ``` Одним запросом получит список сделок в стадии NEW и найдёт контакты с российскими номерами. ## Постраничный вывод Два готовых способа — выбирайте по задаче. ### Получить весь результат сразу Подходит для отчётов, выгрузок и любых случаев, когда нужны все записи. Укажите `limit` до 5000 — сервис вернёт весь подходящий результат одним ответом. ```js const res = await fetch('/v1/deals/search', { method: 'POST', headers: { 'X-Api-Key': key, 'Content-Type': 'application/json' }, body: JSON.stringify({ filter: { closedAt: { $gte: '2026-03-22T00:00:00Z', $lte: '2026-04-22T00:00:00Z' } }, limit: 5000, }), }) const { data, meta } = await res.json() // data — все записи; meta.total — общее количество подходящих записей ``` ### Идти по страницам вручную Подходит, когда нужно обрабатывать записи порциями (например, импорт по 50 штук с сохранением прогресса). Добавьте `autoWindow: false`, сортировку по `id` и увеличивайте `offset` на каждой итерации. ```js let offset = 0 while (true) { const res = await fetch('/v1/deals/search', { method: 'POST', headers: { 'X-Api-Key': key, 'Content-Type': 'application/json' }, body: JSON.stringify({ filter: { closedAt: { $gte: '2026-03-22T00:00:00Z', $lte: '2026-04-22T00:00:00Z' } }, sort: 'id', limit: 50, offset, autoWindow: false, }), }) const { data, meta } = await res.json() for (const deal of data) process(deal) offset += data.length if (offset >= meta.total) break } ``` ### Чего делать нельзя Не запускайте параллельные запросы с разным `offset` на одном фильтре — сервис вернёт `400 UNSTABLE_OFFSET_PAGINATION`. Выберите один из двух способов выше. ## Смотрите также - [Обзор API](./entity-api.md) - [Связанные данные](./includes.md) - [Batch API](./batch.md) - [Все сущности](./entities-index.md) - [Коды ошибок](./errors.md) --- # Коды ошибок Справочник кодов ошибок Vibe API: единый формат ответа, перечень кодов, типичные причины и способы устранения. Применяется ко всем эндпоинтам `/v1/...`. ## Формат ответа при ошибке Каждый ответ с ошибкой возвращается в едином виде. `error` — объект. ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|----------| | `success` | boolean | да | При ошибке всегда `false` | | `error.code` | string | да | Машиночитаемый код ошибки. Используйте для различения типов ошибок в коде клиента | | `error.message` | string | да | Описание ошибки на языке backend (русский или английский) | | `error.hint` | string | нет | Подсказка для разработчика: что попробовать дальше, на какие пределы обратить внимание | | `error.userMessage` | string | нет | Сообщение для конечного пользователя на русском языке. Появляется в биллинговых, инфраструктурных и тарифных ошибках | | `error.warning` | string | нет | Появляется при повторяющихся одинаковых ошибках на одном ключе. Сигнал, что в коде клиента, скорее всего, баг | | `error.retryAfter` | number | нет | Секунды до следующей попытки. Появляется в `429` (rate-limit) и `504` (queue timeout) | Пример ответа с дополнительными полями (`429 RATE_LIMITED`): ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "QUERY_LIMIT_EXCEEDED", "hint": "Wait 1-2 seconds and retry. Use POST /v1/batch to combine up to 50 calls in 1 request.", "retryAfter": 2 } } ``` HTTP-заголовок `Retry-After` дублирует значение `error.retryAfter` для совместимости со стандартом HTTP. ## Сводная таблица кодов Таблица покрывает основные коды, которые встречаются на любом эндпоинте Vibe API. Доменные коды (`BOT_NOT_FOUND`, `SERVER_NOT_RUNNING`, `AGENT_LIMIT_REACHED` и подобные) описаны на страницах соответствующих разделов. ### Авторизация и ключи | Код | HTTP | Когда возникает | |-----|------|-----------------| | `MISSING_API_KEY` | 401 | Запрос без заголовка `X-Api-Key` | | `INVALID_API_KEY` | 401 | Ключ не найден в системе или формат не распознан | | `INVALID_APP_KEY` | 401 | Передан `vibe_app_*`, но без сопровождающего `Authorization: Bearer ...` | | `TOKEN_EXPIRED` | 401 | Срок действия OAuth-токена истёк | | `TOKEN_REFRESH_FAILED` | 401 | Не удалось обновить OAuth-токен на стороне Битрикс24 | | `WRONG_KEY_TYPE` | 401 | Тип ключа не подходит к эндпоинту: например, management-ключ на entity-маршруте | ### Права и скоупы | Код | HTTP | Когда возникает | |-----|------|-----------------| | `SCOPE_DENIED` | 403 | У ключа нет нужного скоупа (например, `crm` для сделок, `imbot` для ботов) | | `WRITE_BLOCKED_READONLY_KEY` | 403 | У ключа задан режим «только чтение», а вызов выполняет запись | | `INFRA_FORBIDDEN_FOR_COWORK_KEY` | 403 | Ключ подписки Co-work (`vibe:cowork`) — только data-plane: запрещены provision / deploy / exec / upload / lifecycle сервера и публикация в каталог. Используйте проектный ключ с правами на деплой | | `INFRA_SCOPE_REQUIRED` | 403 | У ключа нет скоупа `vibe:infra` — управление инфраструктурой недоступно. Добавьте скоуп или используйте ключ с правами на инфраструктуру | | `KEY_POLICY_READONLY_REQUIRED` | 403 | Политика портала разрешает обычным пользователям создавать только ключи с режимом «только чтение» — выпуск ключа с записью отклонён | | `MANAGEMENT_KEY_READ_ONLY` | 403 | Management-ключ без прав на запись пытается выполнить `POST/PATCH/DELETE` | | `MANAGEMENT_KEY_NO_ENTITY_ACCESS` | 403 | Management-ключ обращается к entity-эндпоинту — нужен APP-ключ с нужным скоупом | | `BITRIX_ACCESS_DENIED` | 403 | Битрикс24 ответил `ACCESS_DENIED`: у пользователя нет прав на операцию или сущность | | `OAUTH_REQUIRED` | 403 | Эндпоинт требует пользовательский контекст — нужен ключ типа `vibe_app_*` + Bearer-токен | | `WAITLIST_PENDING` | 403 | Аккаунт ожидает активации в waitlist | ### Валидация запроса | Код | HTTP | Когда возникает | |-----|------|-----------------| | `VALIDATION_ERROR` | 400 | Тело или query не прошли проверку схемы. `message` содержит подробности по полям | | `INVALID_PARAMS` | 400 | Битрикс24 вернул `INVALID_PARAMS` или route-handler нашёл некорректное значение параметра | | `INVALID_REQUEST` | 400 | Структура запроса не соответствует требуемой (например, `calls` в `/v1/batch` пустой массив или содержит больше 50 элементов) | | `MISSING_PARAMS` | 400 | Не передан обязательный параметр, явно перечисленный в схеме эндпоинта | | `MISSING_REQUIRED_FILTER` | 400 | Не передан обязательный фильтр для list-эндпоинтов, требующих контекста (`timelines`, `task-comments` и подобные) | | `INVALID_FILTER_FIELD` | 400 | Фильтр по несуществующему полю сущности | | `UNKNOWN_SORT_FIELD` | 400 | Сортировка по несуществующему полю (для сущностей, у которых валидатор сортировки активен) | | `BATCH_LIMIT_EXCEEDED` | 400 | Запрос содержит больше 50 элементов в массивной операции (vipchats, task-comments и подобные) | | `INVALID_EVENT` | 400 | Код события подписки портала не соответствует формату `^[A-Z][A-Z0-9_]+$`. См. [Подписки на события портала](./infra/event-subscriptions.md) | | `INVALID_APP_PATH` | 400 | Путь доставки `appPath` не начинается с `/` либо содержит управляющие символы. См. [Подписки на события портала](./infra/event-subscriptions.md) | ### Предусловия подписок на события портала | Код | HTTP | Когда возникает | |-----|------|-----------------| | `NOT_OAUTH_APP` | 400 | Сервер не привязан к OAuth-приложению с `application_token` — подписку на событие зарегистрировать нельзя | | `NO_USER_TOKEN` | 400 | У приложения нет OAuth-токена — сначала авторизуйте приложение на портале | Полное описание операций — [Подписки на события портала](./infra/event-subscriptions.md). ### Ресурс не найден | Код | HTTP | Когда возникает | |-----|------|-----------------| | `ENTITY_NOT_FOUND` | 404 | Запись CRM-сущности с указанным `id` не существует. Канонический код для `/v1/deals/:id`, `/v1/contacts/:id` и подобных | | `NOT_FOUND` | 404 | Только `GET /:id`: Битрикс24 вернул `success`, но `result` пустой (применимо к нескольким смарт-методам) | Доменные `*_NOT_FOUND` (`BOT_NOT_FOUND`, `SERVER_NOT_FOUND`, `AGENT_NOT_FOUND`, `PORTAL_NOT_FOUND`, `USER_NOT_FOUND`, `FILE_NOT_FOUND`, `SUBSCRIPTION_NOT_FOUND`) описаны на страницах соответствующих разделов. ### Конфликты состояния | Код | HTTP | Когда возникает | |-----|------|-----------------| | `CONFLICT` | 409 | Текущее состояние ресурса несовместимо с запросом | | `ALREADY_EXISTS` | 409 | Запись с такими ключевыми полями уже существует | | `EVENT_BOUND_ELSEWHERE` | 409 | Событие портала уже привязано к другому серверу того же OAuth-приложения. См. [Подписки на события портала](./infra/event-subscriptions.md) | ### Биллинг и тариф Возникают на эндпоинтах создания и пробуждения инфраструктуры (серверы, агенты, управляемые боты). Ответ содержит `userMessage` на русском языке для показа в интерфейсе клиента. | Код | HTTP | Когда возникает | |-----|------|-----------------| | `BILLING_EXHAUSTED` | 402 | Баланс ушёл в красную зону, аккаунт заморожен. Нужен top-up | | `ACCOUNT_FROZEN` | 402 | Платёжный аккаунт заморожен по другим причинам | | `COMMERCIAL_PLAN_REQUIRED` | 402 | Бесплатный тариф Битрикс24, пробный период недоступен или уже использован | | `TRIAL_EXPIRED` | 402 | 14-дневный пробный период завершён | | `TRIAL_PORTAL_LIMIT` | 402 | На пробном периоде превышен общий лимит серверов на портал | | `TRIAL_USER_LIMIT` | 402 | На пробном периоде превышен лимит серверов на пользователя | | `PLAN_NOT_ALLOWED_ON_TRIAL` | 402 | Запрошенный план сервера/агента недоступен на пробном периоде | | `SERVER_WAKE_BLOCKED` | 403 | Пробуждение сервера заблокировано по небиллинговой причине | ### Ограничение частоты | Код | HTTP | Когда возникает | |-----|------|-----------------| | `RATE_LIMITED` | 429 | Битрикс24 ограничил частоту запросов или превышен внутренний лимит. В ответе — `retryAfter` (секунды) и заголовок `Retry-After` | | `ERROR_LOOP_DETECTED` | 429 | Блокировка на стороне Вайбкод: один и тот же запрос повторяется с одинаковой ошибкой. Сигнал о баге в коде клиента. Каждый N-й запрос пробрасывается дальше для проверки восстановления | ### Backend и сторонние сервисы | Код | HTTP | Когда возникает | |-----|------|-----------------| | `BITRIX_ERROR` | 422 | Битрикс24 вернул бизнес-ошибку, не подпадающую под более узкие категории (`ACCESS_DENIED`, `NOT_FOUND`, `INVALID_PARAMS`) | | `BITRIX_UNAVAILABLE` | 502 | Битрикс24 вернул 5xx или не ответил вовремя | | `BIND_FAILED` | 502 | Битрикс24 отклонил регистрацию события (`event.bind`) — например, портал не на коммерческом тарифе. См. [Подписки на события портала](./infra/event-subscriptions.md) | | `WINDOWED_SEARCH_FAILED` | 502 | Все под-окна `/search` завершились с ошибкой | | `QUEUE_TIMEOUT` | 504 | Очередь портала перегружена: больше 30 секунд ожидания на стороне Вайбкод | | `INTERNAL_ERROR` | 500 | Непредвиденная ошибка backend Вайбкод | ## Подробное описание ### `MISSING_API_KEY` (401) Запрос не содержит заголовка `X-Api-Key`. ```json { "success": false, "error": { "code": "MISSING_API_KEY", "message": "API key required. Pass via X-Api-Key header." } } ``` **Причины:** - Не передан заголовок `X-Api-Key` или `Authorization`. - Заголовок передан с пустым значением. **Решение:** - Добавить заголовок `X-Api-Key: vibe_api_...` или `X-Api-Key: vibe_app_...`. - Проверить, что переменная окружения с ключом установлена корректно (для CLI-утилит и SDK). --- ### `INVALID_API_KEY` (401) Переданный ключ не существует или его формат не распознан. ```json { "success": false, "error": { "code": "INVALID_API_KEY", "message": "Invalid API key" } } ``` **Причины:** - Опечатка или лишние пробелы в ключе. - Ключ удалён владельцем или администратором. - Ключ от другого окружения (staging/production). - Префикс не из числа поддерживаемых: `vibe_api_`, `vibe_app_`, `vibe_live_`, `vibe_mgmt_`. **Решение:** - Сверить ключ в личном кабинете на странице `/keys`. - Создать новый ключ, если старый удалён. --- ### `SCOPE_DENIED` (403) У ключа нет нужного скоупа для запрошенной операции. ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` **Причины:** - Для CRM-сущностей нужен скоуп `crm`, для задач — `task`, для бот-платформы — `imbot`, для AI Router — `vibe:ai`, для инфраструктуры — `vibe:infra`. - Скоуп ключа сужен на этапе создания. **Решение:** - Открыть страницу ключа в личном кабинете и выпустить новый ключ с расширенным набором скоупов. - Полный список скоупов и их назначение — на странице [Ключи и авторизация](./keys-auth.md). --- ### `BITRIX_ACCESS_DENIED` (403) Битрикс24 ответил `ACCESS_DENIED`: у пользователя или приложения нет прав на сущность или операцию. ```json { "success": false, "error": { "code": "BITRIX_ACCESS_DENIED", "message": "ACCESS_DENIED" } } ``` **Причины:** - У пользователя нет прав на сущность в CRM (например, чужая сделка с ограничением видимости). - Приложение Битрикс24 не имеет нужного scope в правах на портале. - Запрашиваемый модуль выключен на портале (отсутствует CRM, бот-платформа и тому подобное). **Решение:** - Проверить права пользователя в карточке сущности Битрикс24. - Открыть настройки приложения на портале и расширить набор разрешений. --- ### `WRITE_BLOCKED_READONLY_KEY` (403) У ключа задан режим «только чтение» (`accessMode: "READONLY"`), а запрос выполняет запись. Полное описание режима, переключения и политики портала — [Режим доступа](./keys-auth.md#режим-доступа). ```json { "success": false, "error": { "code": "WRITE_BLOCKED_READONLY_KEY", "message": "Key is in read-only mode. Switch to read+write in /keys to enable writes.", "details": { "method": "crm.item.add", "keyName": "MCP key", "currentMode": "READONLY", "switchUrl": "/keys" } } } ``` **Поля `details`:** | Поле | Когда возвращается | Описание | |------|-------------------|----------| | `method` | Только при проксировании в Битрикс24 | Имя метода Битрикс24, который был бы вызван при успешной записи (например, `crm.item.add`). Для менеджмент-ключей не возвращается — блокировка идёт по HTTP-методу запроса | | `keyName` | Всегда | Название ключа из личного кабинета. Если у ключа нет названия — возвращается `"unnamed"` | | `currentMode` | Всегда | Действующий режим ключа — всегда `"READONLY"` для этой ошибки | | `switchUrl` | Всегда | Путь до страницы личного кабинета, где режим переключается, — `"/keys"` | **Причины:** - **API-ключ или ключ авторизации (`vibe_api_`, `vibe_app_`)** в режиме `READONLY` выполнил вызов, который проксируется в Битрикс24 как операция записи: создание, обновление, удаление, действие над сущностью. - **Менеджмент-ключ (`vibe_live_`)** в режиме `READONLY` выполнил запрос с HTTP-методом `POST`, `PATCH`, `PUT` или `DELETE` — например, попытка создать ключ через `POST /v1/keys` или удалить запись обратной связи. **Решение:** - Владельцу ключа — открыть [Ключи API](/keys), в карточке нужного ключа в блоке **Режим доступа** выбрать «Чтение и запись» и сохранить. Режим применяется к следующему запросу, перевыпуск не нужен. - Если в карточке выбор переключателя недоступен — администратор портала ограничил режим. Запросить у администратора снятие ограничения для этого ключа. - При работе через AI-агента — действующий режим возвращает `GET /v1/me` в поле `data.accessMode`. Если запись нужна постоянно, выпустить отдельный ключ с режимом «чтение и запись». --- ### `VALIDATION_ERROR` (400) Тело или query-параметры не прошли проверку схемы. Для большинства V1-эндпоинтов обработка реализована через Zod, поэтому сообщение содержит конкретные поля с проблемами. ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "fields.title: Required; fields.stageId: Expected string, received number" } } ``` **Причины:** - Отсутствуют обязательные поля. - Тип значения не соответствует схеме (строка вместо числа, неверный формат даты). - Тело запроса — некорректный JSON либо отсутствует заголовок `Content-Type: application/json`. **Решение:** - Сверить body со схемой эндпоинта в [справочнике сущностей](./entity-api.md) или на странице конкретного эндпоинта. - Числа передавать без кавычек, даты — в формате ISO 8601 (`2026-04-29T10:00:00`). - Добавить заголовок `Content-Type: application/json`. --- ### `INVALID_PARAMS` (400) Битрикс24 или route-handler нашёл некорректное значение параметра. Часто появляется как обёртка для ошибок Битрикс24 формата `INVALID_PARAMS: ...`. ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Path parameter :id must be a positive integer" } } ``` **Причины:** - Некорректное значение path-параметра (например, не число там, где ожидается число). - Битрикс24 отверг параметр запроса (например, неподходящее значение enum-поля). **Решение:** - Проверить страницу эндпоинта: какие значения допустимы для каждого параметра. - Для `filter` использовать список полей из `GET /v1//fields`. --- ### `MISSING_REQUIRED_FILTER` (400) Не передан обязательный фильтр на list-эндпоинте, который требует контекста. ```json { "success": false, "error": { "code": "MISSING_REQUIRED_FILTER", "message": "filter[entityType] and filter[entityId] are required for /v1/timelines" } } ``` **Причины:** - Список тайм-лайн-записей, комментариев и других «вложенных» данных требует пары родительских идентификаторов. **Решение:** - Добавить обязательные параметры фильтра, перечисленные в `message` или на странице эндпоинта. --- ### `BATCH_LIMIT_EXCEEDED` (400) Запрос превышает лимит элементов в массивной операции. На уровне `/v1/batch` лимит проверяется через `INVALID_REQUEST` со ссылкой на `Array must contain at most 50 element(s)`. На доменных bulk-эндпоинтах (например, `chats`, `task-comments`) — отдельный код `BATCH_LIMIT_EXCEEDED`. ```json { "success": false, "error": { "code": "BATCH_LIMIT_EXCEEDED", "message": "Maximum 50 dialogs per bulk request (Bitrix24 batch limit)." } } ``` **Причины:** - В массиве больше 50 элементов. **Решение:** - Разделить операцию на несколько запросов по 50 элементов. - Использовать [batch-запросы](./batch.md) для последовательных вызовов с одного ключа. --- ### `ENTITY_NOT_FOUND` (404) Запись CRM-сущности с указанным `id` не существует или была удалена. ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` **Причины:** - Запись с таким `id` действительно не существует. - Запись была удалена параллельным процессом. - Перепутана сущность: запрос идёт на `/v1/deals/:id`, а ID — от лида. **Решение:** - Проверить наличие записи через list-эндпоинт сущности. - Восстановить из корзины Битрикс24, если запись была удалена недавно (через интерфейс портала). --- ### `RATE_LIMITED` (429) Битрикс24 ограничил частоту запросов либо сработал внутренний лимит Вайбкод. ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "QUERY_LIMIT_EXCEEDED", "hint": "Wait 1-2 seconds and retry. Use POST /v1/batch to combine up to 50 calls in 1 request.", "retryAfter": 2 } } ``` **Заголовки ответа:** ``` Retry-After: 2 ``` **Причины:** - Сложилось слишком много одновременных запросов от одного ключа. - Превышен лимит запросов в секунду на стороне Битрикс24. **Решение:** - Дождаться времени из `error.retryAfter` или заголовка `Retry-After`. - Реализовать повторные попытки с экспоненциальной задержкой. - Объединять до 50 вызовов через [`POST /v1/batch`](./batch.md). - Кэшировать редко изменяемые справочные данные (поля, статусы, валюты). --- ### `ERROR_LOOP_DETECTED` (429) Вайбкод фиксирует серию одинаковых ошибок на одном ключе для одного метода Битрикс24 — и временно блокирует запрос на стороне Вайбкод, чтобы не накручивать счётчики Битрикс24. Каждый N-й запрос пробрасывается дальше: если backend восстановился, блокировка снимается автоматически. ```json { "success": false, "error": { "code": "ERROR_LOOP_DETECTED", "message": "Vibe-side block (not a Bitrix24 limit). 12 failures on crm.deal.list in the last hour.", "hint": "Every 50th request will probe for recovery — keep retrying with backoff. If you suspect a platform-side issue (e.g. 5xx during an outage), platform admin can clear the block via POST /api/platform/analytics/circuit-breaker//clear.", "retryAfter": 60 } } ``` **Причины:** - В коде клиента баг: запрос с одинаковыми параметрами повторяется и стабильно даёт ошибку. - Платформенная авария на стороне Битрикс24 в момент серии запросов. **Решение:** - Прочитать `message` — там указан конкретный метод с серией ошибок. - Найти источник запроса в коде, исправить параметры или логику. - При платформенной аварии — администратор платформы может сбросить блокировку через `POST /api/platform/analytics/circuit-breaker//clear`. --- ### `BILLING_EXHAUSTED` (402) Платёжный аккаунт ушёл в красную зону: баланс отрицательный, грейс-период исчерпан. Запросы на создание и пробуждение инфраструктуры блокируются до пополнения. ```json { "success": false, "error": { "code": "BILLING_EXHAUSTED", "message": "Account is frozen due to negative balance.", "userMessage": "Платёжный аккаунт заморожен из-за отрицательного баланса. Пополните счёт, чтобы продолжить работу с серверами и агентами.", "hint": "Top up the account at /billing/topup, then call POST /v1/portals/:id/refresh-tariff." } } ``` **Причины:** - На балансе нет средств для оплаты часовой стоимости серверов и агентов. **Решение:** - Пополнить баланс на странице `/billing/topup`. - После пополнения вызвать `POST /v1/portals/:id/refresh-tariff` для обновления статуса. --- ### `COMMERCIAL_PLAN_REQUIRED` (402) Создание серверов и агентов недоступно на бесплатном тарифе Битрикс24 после окончания пробного периода. ```json { "success": false, "error": { "code": "COMMERCIAL_PLAN_REQUIRED", "message": "Commercial Bitrix24 plan required for infrastructure operations.", "userMessage": "Создание инфраструктуры доступно на коммерческих тарифах Битрикс24. Пробный период уже использован.", "hint": "Upgrade plan at https://www.bitrix24.ru/prices/, then call POST /v1/portals/:id/refresh-tariff." } } ``` **Решение:** - Обновить тариф Битрикс24 до коммерческого. - После обновления вызвать `POST /v1/portals/:id/refresh-tariff` либо `GET /v1/me?refresh=tariff`. --- ### `TRIAL_EXPIRED` (402) 14-дневный пробный период завершился, тариф остался бесплатным. ```json { "success": false, "error": { "code": "TRIAL_EXPIRED", "message": "Trial period has ended.", "userMessage": "Пробный период (14 дней) завершён. Перейдите на коммерческий тариф Битрикс24, чтобы продолжить пользоваться серверами и агентами." } } ``` **Решение:** - Перейти на коммерческий тариф Битрикс24. - Обновить статус через `POST /v1/portals/:id/refresh-tariff`. --- ### `BITRIX_ERROR` (422) Битрикс24 вернул бизнес-ошибку, которая не подпадает под более узкие категории (`ACCESS_DENIED`, `NOT_FOUND`, `INVALID_PARAMS`, `RATE_LIMITED`). ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Invalid filter: field 'NON_EXISTENT_FIELD' is not allowed in filter", "hint": "Known Bitrix24 limitation: …" } } ``` **Причины:** - Битрикс24 отверг операцию по бизнес-причине: несовместимое состояние, неподдерживаемое значение, бизнес-правило. - Запрос работает на портале, где соответствующий модуль отключён. **Решение:** - Прочитать `message` — там оригинальный текст ошибки от Битрикс24. - При наличии `hint` — использовать его как первый шаг диагностики. --- ### `BITRIX_UNAVAILABLE` (502) Битрикс24 вернул 5xx или не ответил в отведённое время. ```json { "success": false, "error": { "code": "BITRIX_UNAVAILABLE", "message": "Bitrix24 returned 503 Service Unavailable" } } ``` **Причины:** - Технические работы или перегрузка на стороне Битрикс24. - Сетевые проблемы между Вайбкод и порталом. **Решение:** - Повторить запрос через несколько минут, реализовав повторные попытки с экспоненциальной задержкой. - Проверить статус портала по адресу `/bitrix/admin/site_checker.php` (для администратора портала). --- ### `QUEUE_TIMEOUT` (504) Очередь запросов к Битрикс24 для конкретного портала перегружена: больше 30 секунд ожидания. ```json { "success": false, "error": { "code": "QUEUE_TIMEOUT", "message": "Portal queue saturated — too many concurrent Bitrix24 calls", "userMessage": "Запросы к Битрикс24 в очереди дольше 30 секунд. Вероятно, на портале много одновременных операций.", "hint": "If this is a /search request with a wide date range, try adding \"autoWindow\": false OR narrow the date range to <14 days. See /v1/guide for optimization tips.", "retryAfter": 10 } } ``` **Решение:** - Уменьшить параллелизм, отдать клиенту повторную попытку через `retryAfter` секунд. - Для `/search`-эндпоинтов — сузить диапазон дат либо передать `autoWindow: false`. - Объединить вызовы через `POST /v1/batch`. --- ### `INTERNAL_ERROR` (500) Непредвиденная ошибка на стороне Vibe API. ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` **Решение:** - Повторить запрос. - Если ошибка воспроизводится стабильно — отправить тикет через `POST /v1/feedback` с указанием времени запроса. Заголовок `X-Request-Id` из ответа ускоряет диагностику. ## Обработка ошибок в коде ### JavaScript ```javascript async function vibeRequest(url, options = {}) { const response = await fetch(url, { ...options, headers: { 'X-Api-Key': process.env.VIBE_API_KEY, 'Content-Type': 'application/json', ...options.headers, }, }); const data = await response.json(); if (!data.success) { const { code, message, retryAfter } = data.error; switch (code) { case 'RATE_LIMITED': case 'QUEUE_TIMEOUT': { const wait = retryAfter ?? Number(response.headers.get('Retry-After')) ?? 1; await new Promise(r => setTimeout(r, wait * 1000)); return vibeRequest(url, options); } case 'BITRIX_UNAVAILABLE': await new Promise(r => setTimeout(r, 5000)); return vibeRequest(url, options); case 'MISSING_API_KEY': case 'INVALID_API_KEY': throw new Error('Проверьте API-ключ'); default: throw new Error(`${code}: ${message}`); } } return data; } ``` ### Python ```python import os import time import requests def vibe_request(url, method="GET", json_data=None): headers = { "X-Api-Key": os.environ["VIBE_API_KEY"], "Content-Type": "application/json", } response = requests.request(method, url, headers=headers, json=json_data) data = response.json() if not data.get("success"): err = data.get("error", {}) code = err.get("code") message = err.get("message") retry_after = err.get("retryAfter") or int(response.headers.get("Retry-After", 1)) if code in ("RATE_LIMITED", "QUEUE_TIMEOUT"): time.sleep(retry_after) return vibe_request(url, method, json_data) if code == "BITRIX_UNAVAILABLE": time.sleep(5) return vibe_request(url, method, json_data) raise Exception(f"{code}: {message}") return data ``` ### PHP ```php function vibeRequest(string $url, string $method = 'GET', ?array $data = null): array { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => [ 'X-Api-Key: ' . getenv('VIBE_API_KEY'), 'Content-Type: application/json', ], ]); if ($data !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); } $body = json_decode(curl_exec($ch), true); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($body === null) { throw new Exception("HTTP error: $httpCode"); } if (empty($body['success'])) { $errCode = $body['error']['code'] ?? 'UNKNOWN'; $errMsg = $body['error']['message'] ?? 'Unknown error'; $retryAfter = $body['error']['retryAfter'] ?? 1; if (in_array($errCode, ['RATE_LIMITED', 'QUEUE_TIMEOUT'], true)) { sleep((int) $retryAfter); return vibeRequest($url, $method, $data); } if ($errCode === 'BITRIX_UNAVAILABLE') { sleep(5); return vibeRequest($url, $method, $data); } throw new Exception("$errCode: $errMsg"); } return $body; } ``` ## Смотрите также - [Быстрый старт](./quickstart.md) — первый запрос за 2 минуты - [Ключи и авторизация](./keys-auth.md) — типы ключей, формат, скоупы - [Оптимизация и batch](./optimization.md) — снижение количества вызовов и обход `RATE_LIMITED` - [Batch-запросы](./batch.md) — объединение до 50 вызовов в один запрос - [CLI и cURL](./cli.md) — работа через командную строку - [MCP для AI](./mcp.md) — интеграция с AI-инструментами --- # CLI и cURL Страница для тех, кто работает с Vibe API из терминала: скрипты для оболочки, разовые проверки утилитой `curl`, серверные интеграции на PHP без SDK. Полные справочники по операциям — на профильных страницах: [Entity API](./entity-api.md), [Фильтрация](./filtering.md), [Batch API](./batch.md), [Коды ошибок](./errors.md). Базовый URL — `https://vibecode.bitrix24.tech`. Авторизация — через заголовок `X-Api-Key`. Ответы — JSON в формате `{ success, data, meta }` при успехе и `{ success: false, error }` при ошибке. ## На странице - [Окружение](#окружение) — переменные `VIBE_API_KEY` / `VIBE_URL`, сохранение в `~/.zshrc` для использования между сессиями - [Авторизация в curl](#авторизация-в-curl) — личный ключ и ключ авторизации - [Минимальный цикл проверки](#минимальный-цикл-проверки) — создание → удаление с проверкой HTTP 204 - [Полезные приёмы curl](#полезные-приёмы-curl) — `jq`, `-s` против `-sS`, `--data-binary @file`, `read -s`, `X-RateLimit-*` - [OpenAPI-спецификация](#openapi-спецификация) — `/v1/openapi.json` и сторонняя утилита `openapi-to-cli` - [PHP](#php) — шаблон `vibeRequest` без внешних зависимостей - [Обработка ошибок](#обработка-ошибок) — формат `{ success: false, error }` ## Окружение Сохраните ключ и базовый URL в переменные окружения — это убирает повторы в каждой команде и не оставляет ключ в истории команд оболочки. ```bash export VIBE_API_KEY="vibe_api_xxx..." export VIBE_URL="https://vibecode.bitrix24.tech" ``` Проверка — должен вернуться JSON с порталом и скоупами: ```bash curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/me" | head -c 200 ``` Чтобы переменные сохранились между сессиями, добавьте строки `export ...` в `~/.zshrc` (для оболочки `zsh`) или `~/.bashrc` (для `bash`) и перезапустите терминал. Для ключа авторизации (`vibe_app_...`) дополнительно понадобится токен сессии: ```bash export VIBE_APP_KEY="vibe_app_xxx..." export VIBE_SESSION_TOKEN="vibe_session_xxx..." ``` ## Авторизация в curl Личный ключ — один заголовок: ```bash curl -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals" ``` Ключ авторизации — два заголовка, `X-Api-Key` для приложения и `Authorization: Bearer` для сессии конкретного пользователя: ```bash curl -H "X-Api-Key: $VIBE_APP_KEY" \ -H "Authorization: Bearer $VIBE_SESSION_TOKEN" \ "$VIBE_URL/v1/deals" ``` Подробнее о типах ключей и получении токена сессии — [Ключи и авторизация](./keys-auth.md). ## Минимальный цикл проверки Один сценарий, чтобы убедиться, что ключ работает и API отвечает: создать сделку → удалить. Тот же набор операций есть для всех 40+ сущностей — отличаются только поля (см. [Entity API](./entity-api.md) и [справочник сущностей](./entities-index.md)). ```bash # 1. Создать сделку — вернёт объект с присвоенным id curl -X POST "$VIBE_URL/v1/deals" \ -H "X-Api-Key: $VIBE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "CLI test", "stageId": "NEW", "categoryId": 0 }' # 2. Удалить созданную сделку — успех = HTTP 204 с пустым телом curl -i -X DELETE "$VIBE_URL/v1/deals/" \ -H "X-Api-Key: $VIBE_API_KEY" ``` Признак успеха `DELETE` — код ответа, не тело ответа. Чтобы увидеть только код: ```bash curl -s -o /dev/null -w "%{http_code}\n" -X DELETE \ -H "X-Api-Key: $VIBE_API_KEY" \ "$VIBE_URL/v1/deals/" ``` Полные примеры запросов с фильтрами, сортировкой, выбором полей и автопагинацией — на странице нужной сущности, например [Сделки](./entities/deals.md). Синтаксис фильтров (MongoDB-style, префиксы, операторы как ключи) — [Фильтрация и поиск](./filtering.md). ## Полезные приёмы curl ### Читаемый JSON в терминале `curl` выдаёт ответ одной строкой. Для просмотра подключите `jq` или `python3 -m json.tool`: ```bash curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals?limit=5" | jq curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals?limit=5" | python3 -m json.tool ``` ### `-s` против `-sS` в скриптах Флаг `-s` (тихий режим) подавляет индикатор прогресса вместе с сообщениями о сетевых ошибках — например, `Could not resolve host`. В скриптах это скрывает реальные сбои. Флаг `-sS` подавляет только индикатор прогресса, а текст ошибки выводится в `stderr`: ```bash # Тихо, но при сетевой ошибке скрипт молча получит пустой ответ curl -s "$VIBE_URL/v1/deals" -H "X-Api-Key: $VIBE_API_KEY" # Тихо для нормальной работы, ошибки сети видны curl -sS "$VIBE_URL/v1/deals" -H "X-Api-Key: $VIBE_API_KEY" ``` В скриптах для оболочки используйте `-sS`: ошибки сети попадут в `stderr` и не потеряются при отладке. ### Большое тело запроса через `--data-binary @file.json` При длинном теле (batch на 50 операций, импорт OpenAPI, развёрнутый фильтр) флаг `-d` не справляется с экранированием кавычек оболочки и переносами строк. Сохраните тело в файл и передайте его через `@`: ```bash cat > body.json <<'EOF' { "calls": [ { "id": "newDeals", "entity": "deals", "action": "list", "params": { "filter": { "stageId": "NEW" }, "limit": 100 } }, { "id": "user", "entity": "users", "action": "get", "entityId": 1 } ] } EOF curl -X POST "$VIBE_URL/v1/batch" \ -H "X-Api-Key: $VIBE_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @body.json ``` `--data-binary` сохраняет переносы и кавычки как есть, в отличие от `-d`, который вырезает `\n`. Ответ группирует результаты по `id` каждого вызова — `results` содержит данные, `meta` — статистику пагинации, `summary` — итог по всему пакету: ```json { "success": true, "data": { "results": { "newDeals": [ { "id": 7720, "title": "Поставка серверов", "stageId": "NEW" } ], "user": { "id": 1, "name": "Иван Петров" } }, "totals": { "newDeals": 311 }, "meta": { "newDeals": { "total": 311, "returned": 100, "hasMore": true } }, "errors": [], "summary": { "total": 2, "succeeded": 2, "failed": 0 } } } ``` Полные правила batch (лимит 50 вызовов, стоимость в единицах rate-limit, поведение `action: "list"` с `limit > 50`) — [Batch API](./batch.md). ### Экспорт ключа без сохранения в истории оболочки Команда `export VIBE_API_KEY="vibe_api_..."` сохранится в `~/.zsh_history` или `~/.bash_history` — оттуда ключ может попасть на демонстрацию экрана или в резервную копию системы. Альтернатива — `read -s`: оболочка прочитает ключ без отображения на экране, в истории останется только команда `read`, без значения. ```bash read -s VIBE_API_KEY && export VIBE_API_KEY # курсор не двигается, вставляете ключ, Enter ``` Тот же приём подходит для `VIBE_APP_KEY` и `VIBE_SESSION_TOKEN`. ### Заголовки и код ответа ```bash # -i — заголовки + тело curl -i -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/me" # -w — только выбранные поля статистики (код, время) curl -s -o /dev/null -w "HTTP %{http_code}, %{time_total}s\n" \ -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/deals" ``` ### Лимиты запросов В заголовках ответа приходят `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` — текущий остаток лимита запросов для ключа: ```bash curl -s -D - -o /dev/null -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/me" | grep -i ratelimit ``` ### Сохранение ответа в файл ```bash curl -s -H "X-Api-Key: $VIBE_API_KEY" "$VIBE_URL/v1/openapi.json" -o openapi.json ``` ## OpenAPI-спецификация Полный машинно-читаемый каталог эндпоинтов — `/v1/openapi.json` (в формате OpenAPI 3.0): ```bash curl -s "$VIBE_URL/v1/openapi.json" -o openapi.json ``` Файл импортируется в Postman, Insomnia, Swagger UI и любые инструменты, поддерживающие OpenAPI 3.0. На основе спецификации можно генерировать клиентские библиотеки (`openapi-generator`, `oazapfts` и аналоги). ### Утилита `openapi-to-cli` > Сторонний инструмент, не часть Vibe API. Платформа не следит за его работоспособностью; за обновлениями, ошибками и совместимостью со спецификацией обращайтесь в [репозиторий автора](https://github.com/EvilFreelancer/openapi-to-cli). [`openapi-to-cli`](https://github.com/EvilFreelancer/openapi-to-cli) — CLI-утилита, которая собирает команды на основе любой OpenAPI-спецификации. Подключается к Vibe API без кодогенерации: указываете URL спецификации и заголовок авторизации. ```bash npm install -g openapi-to-cli ocli profile add vibecode \ --spec https://vibecode.bitrix24.tech/v1/openapi.json \ --base-url https://vibecode.bitrix24.tech \ --header "X-Api-Key: $VIBE_API_KEY" # Поиск эндпоинта по слову ocli vibecode search "deals" # Вызов ocli vibecode exec GET /v1/deals ocli vibecode exec POST /v1/deals \ --body '{ "title": "Новая сделка", "stageId": "NEW", "categoryId": 0 }' ``` Утилита сторонняя, поддерживается своим автором — за обновлениями и ошибками обращайтесь в её репозиторий. После изменений в Vibe API обновлённая спецификация подхватывается `ocli` при следующем запуске. ## PHP Минимальный шаблон для скриптов и серверных интеграций — без внешних зависимостей, только встроенный `curl`. Тот же шаблон подходит для всех эндпоинтов: `vibeRequest($url, $method, $data)`. ```php true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => [ 'X-Api-Key: ' . $VIBE_API_KEY, 'Content-Type: application/json', ], ]); if ($data !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE)); } $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // DELETE возвращает 204 с пустым телом if ($httpCode === 204) { return ['success' => true]; } $body = json_decode($response, true); if ($body === null) { throw new RuntimeException("HTTP $httpCode: некорректный JSON в ответе"); } if (empty($body['success'])) { $code = $body['error']['code'] ?? 'UNKNOWN'; $msg = $body['error']['message'] ?? 'Неизвестная ошибка'; throw new RuntimeException("$code: $msg (HTTP $httpCode)"); } return $body; } ``` ### Примеры использования ```php // Список $result = vibeRequest("$VIBE_URL/v1/deals?limit=20"); foreach ($result['data'] as $deal) { echo $deal['id'] . ': ' . $deal['title'] . PHP_EOL; } // Создание $result = vibeRequest("$VIBE_URL/v1/deals", 'POST', [ 'title' => 'Поставка серверов', 'stageId' => 'NEW', 'categoryId' => 0, 'amount' => 1500000, 'currency' => 'RUB', ]); $dealId = $result['data']['id']; // Поиск с фильтром $result = vibeRequest("$VIBE_URL/v1/deals/search", 'POST', [ 'filter' => [ 'stageId' => ['$ne' => 'LOST'], 'amount' => ['$gte' => 100000], ], 'sort' => ['createdAt' => 'desc'], 'limit' => 50, ]); // Удаление — внутри vibeRequest 204 превращается в ['success' => true] vibeRequest("$VIBE_URL/v1/deals/$dealId", 'DELETE'); ``` Полные форматы тел запроса и поля ответа — на страницах конкретных сущностей, например [Сделки](./entities/deals.md). ## Обработка ошибок При неуспехе тело ответа имеет вид `{ success: false, error: { code, message } }` и соответствующий HTTP-статус. Пример — запрос без ключа: ```bash curl -i "$VIBE_URL/v1/deals" ``` ``` HTTP/2 401 content-type: application/json; charset=utf-8 { "success": false, "error": { "code": "MISSING_API_KEY", "message": "API key required. Pass via X-Api-Key header." } } ``` Полный справочник кодов и рекомендуемых действий — [Коды ошибок](./errors.md). ## Связанные разделы - [Быстрый старт](./quickstart.md) — первый запрос за 2 минуты - [Ключи и авторизация](./keys-auth.md) — типы ключей, скоупы, лимиты, токены сессии - [Entity API](./entity-api.md) — CRUD, пагинация, выбор полей для всех сущностей - [Фильтрация и поиск](./filtering.md) — три синтаксиса фильтров с примерами - [Batch API](./batch.md) — объединение запросов, ускорение в 50 раз - [Оптимизация](./optimization.md) — паттерны для дашбордов и массовых операций - [Коды ошибок](./errors.md) — справочник по ошибкам - [MCP для AI](./mcp.md) — интеграция с AI-инструментами --- # Пакетные вызовы Один HTTP-запрос объединяет до 50 операций над разными сущностями. Каждый вызов идентифицируется собственным `id` и обрабатывается независимо: ошибка одного вызова не отменяет остальные. `POST /v1/batch` **Скоуп:** проверяется индивидуально по сущности (`crm`, `task`, `im`, `disk` и др.) | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` (APP-ключ) ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:---:|---------| | `calls` | array | ★ | Массив вызовов (от 1 до 50). Каждый элемент — объект, формат описан в таблице ниже. | ## Поля одного вызова | Поле | Тип | Обяз. | Описание | |------|-----|:---:|---------| | `id` | string | нет | Идентификатор вызова в ответе. Если не передан — присваивается порядковый индекс (`"0"`, `"1"`, ...). Длина до 64 символов. | | `entity` | string | ★ | Имя сущности во множественном числе: `deals`, `contacts`, `companies`, `tasks`, `users`, `files`, `folders` и другие. Полный список сущностей, доступных вашему ключу, возвращает `GET /v1/me` — см. [Ключи и авторизация](/docs/keys-auth). | | `action` | string | ★ | Операция: `list`, `get`, `create`, `update`, `delete`, `fields`, `search`. | | `entityId` | number / string | для `get` / `update` / `delete` | Идентификатор записи. | | `params` | object | нет | Параметры операции в едином entity-формате (имена полей в `camelCase`, фильтры в [синтаксисе фильтрации](/docs/filtering)). | Параметры внутри `params` совпадают с параметрами одиночного эндпоинта Entity API: - `list` и `search` — `filter`, `select`, `order`, `limit` - `get` — поле `include`, если сущность его поддерживает - `create` и `update` — поля сущности (имена в `camelCase`) - `delete` и `fields` — параметры не нужны - смарт-процессы (`entity: "items"`) — внутри `params` обязательно `entityTypeId` Идентификатор записи для `get` / `update` / `delete` передаётся в поле `entityId` на уровне вызова, **не** в `params.id`. Вызов `{ "entity": "users", "action": "get", "params": { "id": 1 } }` без `entityId` отклоняется как `MISSING_ENTITY_ID`, и вся пачка возвращает `400` с ошибкой валидации. Правильно: `{ "entity": "users", "action": "get", "entityId": 1 }`. Поле `params` у `get` служит только для `include`. ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/batch \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "calls": [ { "id": "deals", "entity": "deals", "action": "list", "params": { "filter": { "stageId": "NEW" }, "select": ["id", "title", "amount"], "limit": 50 } }, { "id": "contacts", "entity": "contacts", "action": "list", "params": { "select": ["id", "name", "lastName"], "limit": 20 } }, { "id": "user1", "entity": "users", "action": "get", "entityId": 1 } ] }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/batch \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "calls": [ { "id": "deals", "entity": "deals", "action": "list", "params": { "filter": { "stageId": "NEW" }, "select": ["id", "title", "amount"], "limit": 50 } }, { "id": "contacts", "entity": "contacts", "action": "list", "params": { "select": ["id", "name", "lastName"], "limit": 20 } }, { "id": "user1", "entity": "users", "action": "get", "entityId": 1 } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/batch', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ calls: [ { id: 'deals', entity: 'deals', action: 'list', params: { filter: { stageId: 'NEW' }, select: ['id', 'title', 'amount'], limit: 50 } }, { id: 'contacts', entity: 'contacts', action: 'list', params: { select: ['id', 'name', 'lastName'], limit: 20 } }, { id: 'user1', entity: 'users', action: 'get', entityId: 1 } ] }) }) const { data } = await res.json() console.log('Сделки:', data.results.deals) console.log('Контакты:', data.results.contacts) console.log('Сводка:', data.summary) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/batch', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json' }, body: JSON.stringify({ calls: [ { id: 'deals', entity: 'deals', action: 'list', params: { filter: { stageId: 'NEW' }, select: ['id', 'title', 'amount'], limit: 50 } }, { id: 'contacts', entity: 'contacts', action: 'list', params: { select: ['id', 'name', 'lastName'], limit: 20 } }, { id: 'user1', entity: 'users', action: 'get', entityId: 1 } ] }) }) const { data } = await res.json() console.log('Сделки:', data.results.deals) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | `true`, если запрос принят. Частичные ошибки внутри `data.errors` не переводят его в `false`. | | `data.results` | object | Результаты по `id` каждого вызова. Значение — то, что вернул бы соответствующий эндпоинт Entity API: массив записей для `list` / `search`, объект для `get` / `create`, схема полей для `fields`. | | `data.totals` | object | Общее количество записей под фильтр для `list` / `search`-вызовов. Ключи — `id` соответствующих вызовов. | | `data.errors` | object | Ошибки по `id` неудачных вызовов. Каждое значение — `{ "code": "...", "message": "..." }`. | | `data.summary.total` | number | Общее количество вызовов в запросе. | | `data.summary.succeeded` | number | Количество успешных вызовов. | | `data.summary.failed` | number | Количество вызовов с ошибкой. | | `data.meta` | object | Дополнительные сведения по `id` вызовов с `action: "list"` или `action: "search"`: `total`, `returned`, `hasMore`, `truncated`. | ## Пример ответа ```json { "success": true, "data": { "results": { "deals": [ { "id": 575, "title": "Тест валюты", "amount": 0 }, { "id": 741, "title": "Поставка оборудования", "amount": 250000 } ], "contacts": [ { "id": 1, "name": "Иван", "lastName": "Петров" } ], "user1": [ { "ID": "1", "NAME": "Летта", "ACTIVE": true } ] }, "totals": { "deals": 1798, "contacts": 305 }, "errors": {}, "summary": { "total": 3, "succeeded": 3, "failed": 0 }, "meta": { "deals": { "total": 1798, "returned": 2, "hasMore": true, "truncated": false }, "contacts": { "total": 305, "returned": 1, "hasMore": true, "truncated": false } } } } ``` ## Частичные ошибки Если часть вызовов не прошла проверку или вернула ошибку на стороне Битрикс24, успешные результаты остаются в `data.results`, неудачные — в `data.errors` под тем же `id`: ```json { "success": true, "data": { "results": { "deals": [ { "id": 575, "title": "Тест валюты" } ] }, "totals": { "deals": 1798 }, "errors": { "unknown": { "code": "UNKNOWN_ENTITY", "message": "Unknown entity \"foobar\". Check GET /v1/guide for available entities." } }, "summary": { "total": 2, "succeeded": 1, "failed": 1 }, "meta": { "deals": { "total": 1798, "returned": 1, "hasMore": true, "truncated": false } } } } ``` ## Пример ответа при ошибке Если все вызовы не прошли валидацию, возвращается `400 INVALID_REQUEST` с разбивкой по `id` в `data.errors`: ```json { "success": false, "error": { "code": "INVALID_REQUEST", "message": "All calls in the batch failed validation" }, "data": { "errors": { "x": { "code": "MISSING_ENTITY_ID", "message": "Action \"get\" requires entityId." } } } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|----------| | 400 | `INVALID_REQUEST` | Тело запроса не соответствует схеме или все вызовы провалили валидацию. | | 400 | `UNKNOWN_ENTITY` | В одном из вызовов передано неизвестное имя сущности. | | 400 | `ACTION_NOT_SUPPORTED` | Сущность не поддерживает указанное действие (например, `delete` для справочной сущности без удаления). | | 400 | `MISSING_ENTITY_ID` | Действия `get`, `update`, `delete` требуют `entityId`. | | 400 | `MISSING_DYNAMIC_PARAM` | Для смарт-процессов (`entity: "items"`) не передан `entityTypeId` внутри `params`. | | 400 | `INVALID_DYNAMIC_PARAM` | `entityTypeId` для смарт-процессов задан некорректно (не положительное целое). | | 400 | `USE_DEDICATED_ENTITY` | Для переданного `entityTypeId` существует выделенная сущность — использовать её, а не `items`. | | 400 | `ENTITY_CUSTOM_ROUTES` | Сущность работает только через специализированные маршруты (например, `task-comments` — через `/v1/tasks/:taskId/comments`). | | 400 | `INVALID_CALL` | Объект вызова не содержит обязательных полей `entity` и `action`. | | 401 | `TOKEN_MISSING` | У ключа нет настроенных OAuth-токенов или для OAuth-приложения не передан `Authorization: Bearer ...`. | | 401 | `TOKEN_REFRESH_FAILED` | Не удалось обновить OAuth-токен портала. | | 403 | `MANAGEMENT_KEY_NO_ENTITY_ACCESS` | Запрос пришёл с management-ключа — пакетные вызовы доступны только APP-ключам. | | 403 | `SCOPE_NOT_ALLOWED` | Все вызовы запросили скоупы, которых нет у ключа. Если хотя бы один вызов проходит — этот код возвращается внутри `data.errors` для конкретных вызовов, а сам запрос успешен. | | 422 | `BITRIX_ERROR` | Битрикс24 отклонил вызов. Тело ответа содержит `bitrixError.error` и `bitrixError.error_description`. | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 ответил с ошибкой 5xx. | | 503 | `QUEUE_OVERFLOW` | На портале накопилось слишком много одновременных вызовов Битрикс24 (по умолчанию более 100 в ожидании). Ответ возвращается мгновенно с HTTP-заголовком `Retry-After: N` (секунды) — клиент должен дождаться его и повторить с экспоненциальным backoff + jitter. Тело: `error.code = QUEUE_OVERFLOW`, `error.retryAfter` дублирует заголовок. | | 504 | `QUEUE_TIMEOUT` | Запрос ожидал в очереди портала более 30 секунд. Ответ содержит `userMessage` и `hint`. | | 500 | `INTERNAL_ERROR` | Внутренняя ошибка прокси. | Полный список общих ошибок API — [Коды ошибок](/docs/errors). ## Известные особенности **`search` и `list` с `limit > 50` обходят нативный пакетный вызов Битрикс24.** Эти вызовы выполняются как отдельные последовательные запросы со страничной выборкой до 5000 записей — каждый потребляет свою квоту rate-limit Битрикс24 независимо. Остальные вызовы — `list` с `limit ≤ 50`, `get`, `create`, `update`, `delete`, `fields` — объединяются в один пакетный вызов на стороне Битрикс24 и стоят одну единицу rate-limit суммарно. **Стоимость `list` в единицах rate-limit Битрикс24.** Каждые 50 записей = 1 единица. При `limit > 50` авто-пагинатор делает несколько вызовов: | `limit` | Единиц Битрикс24 | |---------|-----------------| | 1–50 | 1 (нативный batch) | | 51–2 550 | 2 | | 2 551–5 000 | 3 | **Если действие в одном вызове провалилось, остальные продолжают выполняться.** Ошибки попадают в `data.errors` под тем же `id`, успешные результаты — в `data.results`. Поле `success` остаётся `true`, проверять нужно `data.summary.failed` или присутствие нужного `id` в `data.results`. **`users.get` возвращает массив, а не объект.** Это особенность Entity API: ответ `get` для пользователей — `[ { ID, NAME, ... } ]`. Первый элемент — искомая запись. **Пакетные изменения для одной сущности.** Если нужно создать, обновить или удалить много записей одной сущности (до 500 штук), используется специализированный эндпоинт `POST /v1/{entity}/batch` с телом `{ "action": "create" | "update" | "delete", "items" | "ids": [...] }`. Он выполняет операции внутренними пакетами по 50 записей и возвращает массив результатов с пометкой `success` для каждого элемента. ## Смотрите также - [Лимиты и оптимизация](/docs/optimization) — авто-пагинация, пакетные вызовы, агрегация - [Синтаксис фильтрации](/docs/filtering) — как описывать `params.filter` - [Entity API](/docs/entity-api) — справочник сущностей и одиночных эндпоинтов - [Ключи и авторизация](/docs/keys-auth) — типы ключей, скоупы, самоописание через `GET /v1/me` - [Коды ошибок](/docs/errors) — общий справочник --- # Лимиты и оптимизация Vibe API сам объединяет вызовы и пагинирует выборки на стороне сервера. Эта статья описывает встроенные механизмы и подсказывает, какой эндпоинт выбирать под задачу. **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Авто-пагинация в `list` Параметр `limit` в `GET /v1/{entity}` принимает значения до 5000. Если `limit > 50`, Вайбкод сам разбивает выборку на внутренние страницы по 50 записей и собирает их в один ответ: ``` GET /v1/deals?limit=500&filter[stageId]=NEW ``` Возвращается до 500 записей плюс мета-поля `meta.total` и `meta.hasMore`. Если под фильтр попадает больше 5000 записей, ответ обрезается, а в `meta.truncated` приходит `true` — для остатка нужно либо сузить фильтр, либо использовать `POST /v1/{entity}/search`. ## Пакетные вызовы по нескольким сущностям `POST /v1/batch` объединяет до 50 операций над разными сущностями в один HTTP-запрос. Каждый вызов идентифицируется собственным `id`, ошибка одного не отменяет остальные. Подходит для дашбордов и страниц-сводок, где одной загрузкой нужны данные из разных мест: ```json { "calls": [ { "id": "deals", "entity": "deals", "action": "list", "params": { "filter": { "stageId": "NEW" }, "limit": 50 } }, { "id": "tasks", "entity": "tasks", "action": "list", "params": { "filter": { "responsibleId": 1 }, "limit": 20 } }, { "id": "user", "entity": "users", "action": "get", "entityId": 1 } ] } ``` Полная спецификация — [Пакетные вызовы](/docs/batch). ## Пакетные операции по одной сущности `POST /v1/{entity}/batch` массово создаёт, обновляет или удаляет до 500 записей одной сущности. Внутри Вайбкод разбивает запрос на пакеты по 50 элементов: ```bash curl -X POST https://vibecode.bitrix24.tech/v1/deals/batch \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "action": "update", "items": [ { "id": 575, "stageId": "WON" }, { "id": 741, "stageId": "WON" } ] }' ``` Действия: `create`, `update`, `delete`, `list`, `get`, `fields`. Для `delete` передаётся массив `ids`, для остальных — `items` (CUD) или `calls` (read). ## Массовое сканирование с дозагрузкой связанных данных Когда нужно прочитать тысячи записей одной сущности и подтянуть к ним связанные данные из других сущностей, поток выглядит так: 1. Выгрузить корневой список одним вызовом — Вайбкод сам пагинирует на сервере: ``` GET /v1/deals?limit=5000&select=id,title,companyId,assignedById ``` 2. Собрать `id` связанных сущностей и догрузить пакетами по 50 через `POST /v1/batch`: ```json { "calls": [ { "id": "company-15", "entity": "companies", "action": "get", "entityId": 15 }, { "id": "company-22", "entity": "companies", "action": "get", "entityId": 22 }, { "id": "user-1", "entity": "users", "action": "get", "entityId": 1 } ] } ``` Один HTTP-запрос — до 50 связанных записей; цикл повторяется для следующего пакета `id`. В таком сценарии корневая выгрузка занимает один сетевой запрос (Вайбкод сам поднимает страницы по 50), а ассоциации догружаются в темпе один HTTP-запрос на 50 элементов вместо запроса на каждый элемент. ## Поиск с разбиением по датам `POST /v1/{entity}/search` рассчитан на крупные выборки. Если в фильтре есть условие по дате с диапазоном больше 14 дней, Вайбкод автоматически делит запрос на окна по 7 дней и обрабатывает их параллельно: ```json { "filter": { "$gte": { "createdAt": "2026-01-01" }, "$lte": { "createdAt": "2026-04-30" } }, "select": ["id", "title", "stageId"], "limit": 5000 } ``` В ответе появляются мета-поля: | Поле | Описание | |------|---------| | `meta.windowCount` | Количество окон, на которые был разбит запрос. | | `meta.windowErrors` | Количество окон, по которым Битрикс24 вернул ошибку. Остальные окна возвращают свои данные. | | `meta.truncated` | `true`, если под фильтр попало больше 5000 записей и часть осталась за пределами выборки. | Разбиение отключается флагом `"autoWindow": false` в теле запроса — это уместно при таймаутах сети или нестабильной выдаче. Полный список параметров `search` — в документации каждой сущности. ## Агрегация вместо выборки записей Когда нужны только счётчики, суммы, минимумы, максимумы или средние — `POST /v1/{entity}/aggregate` возвращает результат одним вызовом, без выгрузки самих записей: ```json { "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "stageId": "WON" }, "groupBy": "assignedById" } ``` Ответ содержит `data.count`, `data.aggregates` и (при наличии `groupBy`) массив `data.groups` с разбивкой по полю группировки. Без `groupBy` ответ ограничен одним объектом сводных значений. Для функции `count` Битрикс24 возвращает результат одним вызовом независимо от размера выборки; `sum` / `avg` / `min` / `max` подгружают записи постранично до 5000 штук — при большем объёме приходит `meta.truncated: true`. ## Очередь портала У каждого портала Битрикс24 своя очередь к Vibe API: одновременно выполняются до двух запросов, остальные ждут места. Если запрос провисел в очереди дольше 30 секунд, возвращается `504 QUEUE_TIMEOUT` с подсказкой `userMessage` и `hint`. Что снижает нагрузку на очередь: - Объединять разнородные обращения через `POST /v1/batch` — один HTTP-запрос вместо нескольких. - Для массового CRUD по одной сущности — `POST /v1/{entity}/batch` (до 500 записей за запрос). - Для широких выборок — `GET /v1/{entity}?limit=...` (Вайбкод пагинирует на стороне сервера) или `POST /v1/{entity}/search` (разбивка по датам). - Когда нужны числа, а не записи — `POST /v1/{entity}/aggregate`. **Повтор при перегрузке очереди.** Под нагрузкой очередь возвращает два разных кода, и оба означают «повтори позже»: - `503 QUEUE_OVERFLOW` — очередь переполнена, запрос отклонён сразу (за миллисекунды). В заголовке `Retry-After` — рекомендованная пауза в секундах. - `504 QUEUE_TIMEOUT` — запрос ждал места дольше 30 секунд. В теле `error.retryAfter` — рекомендованная пауза. Виджеты аналитики, которые шлют пачку `/search` подряд, должны делать повтор с экспоненциальной задержкой и случайным разбросом (jitter), уважая `Retry-After`, а не повторять мгновенно в цикле — это усугубляет перегрузку. Снизьте параллелизм: выполняйте запросы последовательно или объедините их в `POST /v1/batch`. ```javascript async function callWithBackoff(url, options, maxRetries = 4) { for (let attempt = 0; ; attempt++) { const res = await fetch(url, options) if (res.status !== 503 && res.status !== 504) return res if (attempt >= maxRetries) return res // 503 — пауза в заголовке Retry-After; 504 — в теле error.retryAfter const headerWait = Number(res.headers.get('Retry-After')) let bodyWait = 0 if (res.status === 504) { bodyWait = Number((await res.clone().json())?.error?.retryAfter) || 0 } const baseSec = headerWait || bodyWait || Math.min(2 ** attempt, 30) const jitterMs = Math.floor(Math.random() * 1000) await new Promise(r => setTimeout(r, baseSec * 1000 + jitterMs)) } } ``` ## Загрузка сообщений из нескольких диалогов `POST /v1/chats/messages/bulk` возвращает сообщения не более чем из 50 диалогов в одном ответе и принимает курсоры `lastId` / `firstId` и `limit` для каждого диалога: ```json { "dialogs": [ { "dialogId": "chat253", "limit": 20 }, { "dialogId": "chat741", "lastId": 9357, "limit": 50 } ] } ``` Скоуп: `im`. Формат ответа — `{ results, errors, summary }`, аналогично `/v1/batch`. ## Сводные лимиты | Сценарий | Ограничение | |----------|-------------| | `GET /v1/{entity}` — `limit` | до 5000 записей; при `limit > 50` авто-пагинация на стороне Вайбкод | | `POST /v1/batch` — число вызовов | до 50 в одном запросе | | `POST /v1/{entity}/batch` — массовый CRUD | до 500 записей в одном запросе | | `POST /v1/{entity}/batch` — read-действия (`list` / `get` / `fields`) | до 50 вызовов в массиве `calls` | | `POST /v1/{entity}/search` — `limit` | до 5000 записей; при диапазоне дат > 14 дней — окна по 7 дней | | `POST /v1/chats/messages/bulk` — диалогов | до 50 в одном запросе | | Очередь портала | 2 одновременных запроса, ожидание до 30 секунд | ## Смотрите также - [Пакетные вызовы](/docs/batch) — полная спецификация `POST /v1/batch` - [Синтаксис фильтрации](/docs/filtering) — три синтаксиса фильтра для `list`, `search`, `aggregate` - [Entity API](/docs/entity-api) — справочник сущностей и одиночных эндпоинтов - [Коды ошибок](/docs/errors) — общий справочник - [Быстрый старт](/docs/quickstart) — первый запрос за две минуты --- # Бот-платформа Создавайте чат-ботов Битрикс24: регистрируйте бота, получайте сообщения и команды пользователей, отвечайте текстом, кнопками и вложениями, управляйте групповыми чатами и участниками. Не нужны вебхуки и публичный сервер — бот опрашивает события и отвечает обычными HTTP-запросами. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` [Какой ключ выбрать](#какой-ключ-выбрать) | [Быстрый старт](#быстрый-старт) | [Echo-бот (пример)](#полный-пример-echo-бот) | [Диагностика проблем](/docs/bots/troubleshooting) | [Коды ошибок](#коды-ошибок) | [Справочник эндпоинтов](#справочник-эндпоинтов) ## Разделы документации - [Управление ботами](/docs/bots/management) — регистрация, обновление, удаление - [События](/docs/bots/events) — опрос входящих сообщений и команд - [Сообщения](/docs/bots/messages) — отправка, редактирование, удаление, форматирование - [Чаты](/docs/bots/chats) — создание чатов, управление участниками и менеджерами - [Команды](/docs/bots/commands) — slash-команды бота - [Интерфейс](/docs/bots/ui) — реакции, индикатор набора, поле ввода - [Файлы](/docs/bots/files) — загрузка и скачивание - [Диагностика проблем](/docs/bots/troubleshooting) — что делать, если бот не получает события или возвращает ошибки ## Оформление сообщений Справочники по оформлению текста при отправке и редактировании сообщений: - [Форматирование текста (BB-коды)](/docs/bots/messages/formatting) - [Клавиатура](/docs/bots/messages/keyboard) - [Вложения (ATTACH-блоки)](/docs/bots/messages/attach) --- ## Какой ключ выбрать Бот-платформа работает с двумя типами ключей. Выбор определяется тем, от чьего имени бот будет обращаться к Битрикс24. | Сценарий | Ключ | Заголовки запроса | |---------|------|-------------------| | Бот для своего портала: собственный сервер, фоновый процесс, личный скрипт | Личный API-ключ `vibe_api_…` | `X-Api-Key: vibe_api_…` | | Бот внутри OAuth-приложения, опубликованного в каталоге Вайбкод и установленного на порталы пользователей | Ключ авторизации `vibe_app_…` | `X-Api-Key: vibe_app_…` + `Authorization: Bearer ` | **Личный ключ `vibe_api_…`.** Создаётся в личном кабинете Вайбкод и привязан к одному порталу Битрикс24. Все запросы идут от лица владельца ключа, дополнительный токен сессии не требуется. Подходит для одноразовых ботов, которые не публикуются как приложение. **Ключ авторизации `vibe_app_…`.** Привязан к OAuth-приложению из каталога. Каждый запрос отправляется от лица того пользователя, который установил приложение на свой портал и прошёл OAuth-авторизацию — поэтому обязателен заголовок `Authorization: Bearer `. Без Bearer бот-эндпоинты вернут `401 TOKEN_MISSING`. Подходит для тиражируемых ботов, которые работают на разных порталах под разными пользователями. Подробное описание типов ключей, форматов и получения `session_token` — [Ключи и авторизация](/docs/keys-auth). --- ## Быстрый старт ### 1. Зарегистрируйте бота ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "code": "my_helper_bot", "name": "Помощник", "type": "bot", "eventMode": "fetch" }' ``` Ответ: ```json { "success": true, "data": { "bot": { "id": 42, "code": "my_helper_bot", "name": "Помощник", "type": "bot", "eventMode": "fetch" } } } ``` > ID бота берите из `data.bot.id` — `botToken` платформа хранит сама и в ответ не возвращает. ### 2. Получайте события (длинный опрос) ```bash curl -H "X-Api-Key: $VIBE_KEY" \ "https://vibecode.bitrix24.tech/v1/bots/42/events" ``` Ответ содержит `nextOffset` — передайте его как `offset` в следующем запросе: ```json { "success": true, "data": { "events": [ { "eventId": 35, "type": "ONIMBOTV2MESSAGEADD", "date": "2026-04-13T10:05:00+03:00", "data": { "dialogId": "12", "bot": { "id": 42, "code": "my_helper_bot", "type": "bot" }, "message": { "id": 1501, "chatId": 87, "authorId": 1, "date": "2026-04-13T10:05:00+03:00", "text": "Привет, бот!" }, "chat": { "id": 87, "dialogId": "12", "type": "private" }, "user": { "id": 1, "name": "Иван Петров", "firstName": "Иван", "lastName": "Петров" } } } ], "nextOffset": 36, "hasMore": false, "storedOffset": 35, "persisted": true } } ``` Следующий запрос: ```bash curl -H "X-Api-Key: $VIBE_KEY" \ "https://vibecode.bitrix24.tech/v1/bots/42/events?offset=42" ``` ### 3. Отправьте ответ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/messages \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "12", "fields": { "message": "Привет! Чем могу помочь?" } }' ``` Ответ: ```json { "success": true, "data": { "id": 1502, "uuidMap": [] } } ``` --- ## Полный пример: Echo-бот ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' // ── 1. Регистрация бота ───────────────────────────────────────── const regRes = await fetch(`${BASE}/bots`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ code: 'echo_bot', name: 'Echo Bot', type: 'bot', color: 'AQUA', eventMode: 'fetch', workPosition: 'Повторяет ваши сообщения' }) }) const { data } = await regRes.json() const BOT_ID = data.bot.id console.log(`Bot registered with ID: ${BOT_ID}`) // ── 2. Регистрация slash-команд ───────────────────────────────── await fetch(`${BASE}/bots/${BOT_ID}/commands`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ command: 'ping', title: 'Ping', description: 'Проверить, жив ли бот' }) }) await fetch(`${BASE}/bots/${BOT_ID}/commands`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ command: 'help', title: 'Помощь', description: 'Показать список команд' }) }) // ── 3. Цикл опроса событий (polling) ─────────────────────────── let offset = undefined async function poll() { while (true) { try { const url = new URL(`${BASE}/bots/${BOT_ID}/events`) if (offset !== undefined) url.searchParams.set('offset', String(offset)) const res = await fetch(url, { headers: { 'X-Api-Key': VIBE_KEY } }) const { data } = await res.json() for (const event of data.events || []) { await handleEvent(event) } if (data.nextOffset !== undefined) { offset = data.nextOffset } } catch (err) { console.error('Poll error:', err.message) } await new Promise(r => setTimeout(r, 3000)) } } async function handleEvent(event) { const { data } = event // ── Обработка сообщений ──────────────────────────────────── if (event.type === 'ONIMBOTV2MESSAGEADD') { const dialogId = data.chat.dialogId const text = data.message?.text || '' const userName = data.user?.firstName || 'друг' // Пропускаем системные сообщения и свои собственные if (data.message?.isSystem) return if (data.message?.authorId === BOT_ID) return // Показываем "думает..." await fetch(`${BASE}/bots/${BOT_ID}/typing`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ dialogId, statusMessageCode: 'IMBOT_AGENT_ACTION_THINKING' }) }) // Ставим реакцию на сообщение await fetch(`${BASE}/bots/${BOT_ID}/messages/${data.message.id}/reactions`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ reaction: 'like' }) }) // Отправляем эхо-ответ с клавиатурой await fetch(`${BASE}/bots/${BOT_ID}/messages`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ dialogId, fields: { message: `${userName}, вы написали: [I]${text}[/I]`, keyboard: [ { TEXT: 'Повторить', BG_COLOR_TOKEN: 'primary', ACTION: 'SEND', ACTION_VALUE: text || 'ping', BLOCK: 'Y' }, { TEXT: 'Помощь', BG_COLOR_TOKEN: 'secondary', ACTION: 'SEND', ACTION_VALUE: '/help', DISPLAY: 'LINE' } ] } }) }) } // ── Обработка команд ─────────────────────────────────────── if (event.type === 'ONIMBOTV2COMMANDADD') { const dialogId = data.chat.dialogId const command = data.command if (command.command === 'ping') { await fetch(`${BASE}/bots/${BOT_ID}/commands/${command.id}/answer`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ messageId: data.message.id, message: '[B]Pong![/B] Бот работает нормально.' }) }) } if (command.command === 'help') { await fetch(`${BASE}/bots/${BOT_ID}/commands/${command.id}/answer`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ messageId: data.message.id, message: '[B]Echo Bot — Команды[/B]\n\n/ping — проверить, жив ли бот\n/help — показать этот список\n\nПросто напишите мне — я повторю ваше сообщение.' }) }) } } // ── Обработка реакций ────────────────────────────────────── if (event.type === 'ONIMBOTV2REACTIONCHANGE') { const dialogId = data.chat.dialogId const userName = data.user?.firstName || 'Кто-то' if (data.action === 'add') { await fetch(`${BASE}/bots/${BOT_ID}/messages`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ dialogId, fields: { message: `${userName} поставил реакцию: ${data.reaction}`, system: true } }) }) } } // ── Вход в чат ───────────────────────────────────────────── if (event.type === 'ONIMBOTV2JOINCHAT') { await fetch(`${BASE}/bots/${BOT_ID}/messages`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ dialogId: data.chat.dialogId, fields: { message: 'Привет! Я Echo Bot. Напишите мне что-нибудь, и я повторю.\n\nКоманды:\n[SEND=/ping]Ping[/SEND] | [SEND=/help]Помощь[/SEND]' } }) }) } } poll() ``` --- ## Полный пример: Standup-бот (личный опрос → отчёт в группу) Частый сценарий, где не хватает явного примера: утром бот пишет каждому сотруднику **в личку**, собирает ответы и публикует сводку в **групповой чат**. Здесь важны два разных `dialogId` (см. [Отправить сообщение](/docs/bots/messages/send)): - **личное сообщение** — `dialogId` равен числовому ID пользователя (`"42"`) - **групповой чат** — `dialogId` имеет вид `chatXXX`. ### Где взять `dialogId` группового чата - Создать чат: `POST /v1/bots/:botId/chats` (`Chat.add`) — в ответе `data.chat.dialogId` = `chatXXX`. См. [Создать чат](/docs/bots/chats/create). - Или взять из входящего события: каждое сообщение-событие из `GET /v1/bots/:botId/events` несёт `dialogId` (для группового чата это `chatXXX`). См. [События](/docs/bots/events). ### Где взять ID участников `GET /v1/bots/:botId/chats/:dialogId/users` возвращает список участников чата, либо берите сотрудников из `GET /v1/users` (скоуп `user`). Числовой ID каждого пользователя и есть его личный `dialogId`. ### Шаги ```javascript const BASE = 'https://vibecode.bitrix24.tech/v1' const headers = { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' } // 1. Утром: личный вопрос каждому участнику (dialogId = числовой userId) async function askTeam(botId, userIds) { for (const userId of userIds) { await fetch(`${BASE}/bots/${botId}/messages`, { method: 'POST', headers, body: JSON.stringify({ dialogId: String(userId), fields: { message: 'Доброе утро! Что сделал вчера, что планируешь сегодня, что мешает в работе?' }, }), }) } } // 2. В течение дня: собираем ответы через polling. // Поля события вложены в ev.data (см. «События»): dialogId, message.text, user.id. // В личном диалоге ev.data.dialogId совпадает с числовым ID отправителя. const answers = {} async function collect(botId, expectedUserIds) { const res = await fetch(`${BASE}/bots/${botId}/events`, { headers }) const { data } = await res.json() for (const ev of data.events ?? []) { if (ev.type !== 'ONIMBOTV2MESSAGEADD') continue const fromUser = String(ev.data.user.id) // Личный диалог: dialogId равен ID отправителя if (ev.data.dialogId === fromUser && expectedUserIds.includes(fromUser)) { answers[fromUser] = ev.data.message.text } } } // 3. Публикуем сводку в групповой чат (dialogId = chatXXX) async function publishReport(botId, groupDialogId, userIds) { const lines = userIds.map(id => `[b]${id}[/b]: ${answers[String(id)] ?? '— нет ответа'}`) await fetch(`${BASE}/bots/${botId}/messages`, { method: 'POST', headers, body: JSON.stringify({ dialogId: groupDialogId, // 'chat123' fields: { message: `[b]Standup за сегодня[/b]\n${lines.join('\n')}` }, }), }) } ``` **Расписание — на стороне вашего сервера.** Платформа не планирует запуски за вас: бот живёт на вашем Black Hole-сервере, поэтому утренний опрос и публикацию отчёта вызывайте по собственному cron (`crontab`, `node-cron` и т. п.). Polling событий держите запущенным постоянно — см. [Echo-бот](#полный-пример-echo-бот) выше. --- ## Windows / PowerShell и UTF-8 При отправке запросов к API ботов из Windows PowerShell кириллица в `name` бота или в теле сообщения может превратиться в знаки вопроса (`?`). Это не проблема отображения на стороне сервера — кириллические байты теряются ещё до отправки HTTP-запроса, на стороне клиента. **Причина:** по умолчанию PowerShell использует кодировку `windows-1251` (или `iso-8859-1` — зависит от локали) для строк, передаваемых в параметр `-Body` у `Invoke-WebRequest` / `Invoke-RestMethod`. Исходная строка теряет кириллицу ещё до того, как HTTP-клиент соберёт запрос. Заголовок `Content-Type: charset=utf-8` здесь не помогает — к моменту его применения исходные байты уже потеряны при перекодировании на стороне клиента. **Решение:** явно установите UTF-8 и передавайте тело массивом байтов. ```powershell # 1. Включить UTF-8 для PowerShell (делается один раз в сессии) [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 # 2. Собрать JSON и преобразовать его в массив UTF-8 байтов $body = @{ code = 'my_bot' name = 'Мой бот' color = 'AZURE' } | ConvertTo-Json -Compress $bytes = [System.Text.Encoding]::UTF8.GetBytes($body) # 3. Передать в -Body массив байтов (не строку!) и явно указать кодировку в Content-Type Invoke-WebRequest ` -Uri 'https://vibecode.bitrix24.tech/v1/bots' ` -Method POST ` -Headers @{ 'X-Api-Key' = $env:VIBE_KEY 'Content-Type' = 'application/json; charset=utf-8' } ` -Body $bytes ``` **Распространённые ошибки:** - ❌ Сохранять `.ps1` файл **с UTF-8 BOM** — старые версии PowerShell могут не разобрать сам скрипт. - ❌ Передавать **строку** в `-Body` (`-Body $body`) вместо массива байтов (`-Body $bytes`) — строка повторно перекодируется через системную кодировку. - ❌ Полагаться только на `Content-Type: application/json; charset=utf-8` без `UTF8.GetBytes` — этот заголовок не восстанавливает байты, потерянные при перекодировании на стороне клиента, а лишь объявляет серверу заявленную кодировку тела. **Node.js и Python работают по умолчанию** — `fetch` с JSON в теле запроса и библиотека `requests` сами кодируют тело в UTF-8, дополнительных шагов не требуется. Проблема специфична для PowerShell. --- ## Коды ошибок ### Ошибки бот-платформы | Код | HTTP | Описание | |-----|------|---------| | `SCOPE_DENIED` | 403 | API-ключ не имеет скоупа `imbot` | | `TOKEN_MISSING` | 401 | API-ключ не имеет настроенных токенов | | `CODE_REQUIRED` | 400 | Не передан параметр `code` при регистрации | | `NAME_REQUIRED` | 400 | Не передан параметр `name` при регистрации | | `INVALID_BOT_ID` | 400 | `botId` должен быть числом | | `BOT_NOT_FOUND` | 404 | Бот с таким ID не найден — зарегистрируйте через `POST /v1/bots` | | `BOT_ACCESS_DENIED` | 403 | Бот принадлежит другому API-ключу | | `BOT_ALREADY_EXISTS` | 409 | Бот с таким `code` уже зарегистрирован. Ответ содержит `data.botId` существующего бота (на этом пути — плоская форма, в отличие от вложенного `data.bot.id` в успешном 201) | | `REGISTRATION_FAILED` | 502 | Битрикс24 не вернул ID бота при регистрации | ### Системные ошибки | Код | HTTP | Описание | |-----|------|---------| | `AUTH_REQUIRED` | 401 | Отсутствует заголовок `X-Api-Key` | | `INVALID_API_KEY` | 401 | Неверный API-ключ | | `KEY_REVOKED` | 403 | API-ключ отозван | | `RATE_LIMIT` | 429 | Превышен лимит запросов | | `BITRIX_ERROR` | 502 | Ошибка в ответе Битрикс24 API | | `BITRIX_UNAVAILABLE` | 502 | Портал Битрикс24 недоступен | | `INTERNAL_ERROR` | 500 | Внутренняя ошибка сервера | --- ## Справочник эндпоинтов Все 36 эндпоинтов бот-платформы: | Метод | Путь | Битрикс24 метод | Описание | |-------|------|---------------|---------| | POST | [/v1/bots](/docs/bots/management/create) | imbot.v2.Bot.register | Регистрация бота | | GET | [/v1/bots](/docs/bots/management/list) | — | Список ботов | | GET | [/v1/bots/:botId](/docs/bots/management/get) | imbot.v2.Bot.get | Данные бота | | PATCH | [/v1/bots/:botId](/docs/bots/management/update) | imbot.v2.Bot.update | Обновление бота | | DELETE | [/v1/bots/:botId](/docs/bots/management/delete) | imbot.v2.Bot.unregister | Удаление бота | | POST | [/v1/bots/:botId/reauth](/docs/bots/management/reauth) | — | Повторная авторизация бота | | POST | [/v1/bots/:botId/resubscribe](/docs/bots/management/resubscribe) | imbot.v2.Bot.update | Перепривязка подписки на события | | GET | [/v1/bots/revision](/docs/bots/management/revision) | imbot.v2.Revision.get | Ревизия бот-платформы | | GET | [/v1/bots/:botId/events](/docs/bots/events/polling) | imbot.v2.Event.get | Получение событий | | POST | [/v1/bots/:botId/messages](/docs/bots/messages/send) | imbot.v2.Chat.Message.send | Отправка сообщения | | PATCH | [/v1/bots/:botId/messages/:messageId](/docs/bots/messages/update) | imbot.v2.Chat.Message.update | Обновление сообщения | | DELETE | [/v1/bots/:botId/messages/:messageId](/docs/bots/messages/delete) | imbot.v2.Chat.Message.delete | Удаление сообщения | | POST | [/v1/bots/:botId/chats/:dialogId/read](/docs/bots/messages/read) | imbot.v2.Chat.Message.read | Прочитать сообщения | | GET | [/v1/bots/:botId/messages/:messageId](/docs/bots/messages/get) | imbot.v2.Chat.Message.get | Получить сообщение | | GET | [/v1/bots/:botId/messages/:messageId/context](/docs/bots/messages/context) | imbot.v2.Chat.Message.getContext | Контекст сообщения | | POST | [/v1/bots/:botId/messages/:messageId/reactions](/docs/bots/ui/reaction-add) | imbot.v2.Chat.Message.Reaction.add | Добавить реакцию | | DELETE | [/v1/bots/:botId/messages/:messageId/reactions](/docs/bots/ui/reaction-delete) | imbot.v2.Chat.Message.Reaction.delete | Удалить реакцию | | POST | [/v1/bots/:botId/typing](/docs/bots/ui/typing) | imbot.v2.Chat.InputAction.notify | Индикатор набора | | POST | [/v1/bots/:botId/text-field](/docs/bots/ui/text-field) | imbot.v2.Chat.TextField.enabled | Управление полем ввода | | POST | [/v1/bots/:botId/chats](/docs/bots/chats/create) | imbot.v2.Chat.add | Создание чата | | GET | [/v1/bots/:botId/chats/:dialogId](/docs/bots/chats/get) | imbot.v2.Chat.get | Информация о чате | | PATCH | [/v1/bots/:botId/chats/:dialogId](/docs/bots/chats/update) | imbot.v2.Chat.update | Обновление чата | | POST | [/v1/bots/:botId/chats/:dialogId/leave](/docs/bots/chats/leave) | imbot.v2.Chat.leave | Покинуть чат | | POST | [/v1/bots/:botId/chats/:dialogId/owner](/docs/bots/chats/set-owner) | imbot.v2.Chat.setOwner | Назначить владельца | | POST | [/v1/bots/:botId/chats/:dialogId/users](/docs/bots/chats/user-add) | imbot.v2.Chat.User.add | Добавить участников | | DELETE | [/v1/bots/:botId/chats/:dialogId/users](/docs/bots/chats/user-delete) | imbot.v2.Chat.User.delete | Удалить участника | | GET | [/v1/bots/:botId/chats/:dialogId/users](/docs/bots/chats/user-list) | imbot.v2.Chat.User.list | Список участников | | POST | [/v1/bots/:botId/chats/:dialogId/managers](/docs/bots/chats/manager-add) | imbot.v2.Chat.Manager.add | Добавить менеджеров | | DELETE | [/v1/bots/:botId/chats/:dialogId/managers](/docs/bots/chats/manager-delete) | imbot.v2.Chat.Manager.delete | Удалить менеджеров | | POST | [/v1/bots/:botId/commands](/docs/bots/commands/register) | imbot.v2.Command.register | Регистрация команды | | GET | [/v1/bots/:botId/commands](/docs/bots/commands/list) | imbot.v2.Command.list | Список команд | | PATCH | [/v1/bots/:botId/commands/:commandId](/docs/bots/commands/update) | imbot.v2.Command.update | Обновление команды | | DELETE | [/v1/bots/:botId/commands/:commandId](/docs/bots/commands/delete) | imbot.v2.Command.unregister | Удаление команды | | POST | [/v1/bots/:botId/commands/:commandId/answer](/docs/bots/commands/answer) | imbot.v2.Command.answer | Ответ на команду | | POST | [/v1/bots/:botId/files](/docs/bots/files/upload) | imbot.v2.File.upload | Загрузка файла | | GET | [/v1/bots/:botId/files/:fileId](/docs/bots/files/download) | imbot.v2.File.download | Скачивание файла | --- # Подключение Битрикс24 к OpenClaw Раздел описывает интеграцию Битрикс24 с самостоятельно развёрнутым OpenClaw через npm-плагин `@ihazz/bitrix24`. Агент получает чат с пользователями портала Битрикс24 и прямой доступ к API Вайбкод для работы со сделками, задачами, контактами, календарём и другими данными портала. ## Разделы документации - [Скилл Битрикс24](/docs/openclaw/skill) — что агент получает: переменные окружения, формат вызовов API портала, базовые сценарии - [Коннектор Битрикс24](/docs/openclaw/connector) — чат с пользователями портала: провайдеры, политики доступа, поддерживаемые возможности - [Пошаговая инструкция](/docs/openclaw/scenario) — установка и проверка работы за 5 шагов ## Что входит Плагин `@ihazz/bitrix24` (MIT, текущая версия 2.3.2) — один npm-пакет, внутри которого логически выделяются два компонента: - **Скилл Битрикс24** — учит агента вызывать API Вайбкод через `curl` и стандартный `exec`-инструмент OpenClaw, чтобы работать со сделками, задачами, контактами, календарём и другими данными портала. На старте плагин экспортирует в окружение переменные `VIBE_KEY`, `VIBE_BASE_URL`, `VIBE_PLATFORM_URL` — агент использует их в каждом вызове. - **Коннектор Битрикс24** — регистрирует OpenClaw как бота на портале и пересылает сообщения между Битрикс24 Мессенджером и агентом. Поддерживает личные сообщения, групповые чаты с политиками доступа, реакции, файлы, инлайн-кнопки, индикатор набора и пассивный режим наблюдения за чатами. ## Что понадобится 1. **OpenClaw v2026.4.1** на собственной инфраструктуре. 2. **API-ключ Вайбкод** (`vibe_api_…` или `vibe_app_…`) со скоупами: - `imbot` — обязательно, для регистрации бота и обмена сообщениями. - `vibe:ai` — обязательно, чтобы LLM-провайдер агента ходил в AI Router Вайбкод. - Доменные скоупы под задачи агента: `crm` для CRM, `tasks` для задач, `calendar` для расписания, и так далее. Как создать ключ — [Ключи и авторизация](./keys-auth.md). 3. **Доступ к порталу Битрикс24** — портал берётся из ключа, отдельно указывать его в `openclaw.json` не нужно. ## Быстрый старт Установить плагин в OpenClaw: ```bash openclaw plugins install @ihazz/bitrix24@latest ``` Разрешить плагин и настроить канал в `openclaw.json`: ```json { "plugins": { "allow": ["bitrix24"] }, "channels": { "bitrix24": { "provider": "vibecode", "providerConfig": { "apiKey": "YOUR_API_KEY" } } } } ``` Перезапустить OpenClaw. Плагин зарегистрирует бота на портале через ключ, агент начнёт принимать сообщения в Битрикс24 Мессенджере. Полная пошаговая инструкция с проверкой работы — [Пошаговая инструкция](/docs/openclaw/scenario). ## Как плагин работает с API Вайбкод Плагин ходит в API сам — пользователю эти эндпоинты вызывать вручную не нужно. Краткий обзор по слоям: **Бот-платформа.** Коннектор регистрирует бота, опрашивает события чата, отправляет сообщения, реакции, файлы и индикатор набора через `/v1/bots/*`. Полный справочник — [Бот-платформа](./bots.md). **Данные портала.** Скилл запрашивает сделки, задачи, контакты, календарь и другие сущности через `/v1/`. Какие сущности доступны конкретному ключу, определяют его доменные скоупы. Полный каталог — [Справочник сущностей](./entities-index.md). **AI Router.** LLM-провайдер агента ходит в `/v1/ai/chat/completions` за моделями Вайбкод. Для OpenClaw-агента в BYO-режиме мы рекомендуем `bitrix/bitrixgpt-5.5-agent` — ту же модель, на которой работают Vibe-managed агенты. Список доступных моделей — [Модели](./ai/models.md). ## Совместимость с OpenClaw | Версия OpenClaw | Статус | |-----------------|--------| | **v2026.4.1** | Минимальная поддерживаемая. На ней проверены все возможности плагина. | | v2026.4.5 | Содержит известную проблему: скиллы плагинов не разрешаются из директории расширений, бот может не отвечать на сообщения. До исправления оставаться на v2026.4.1. | ## Смотрите также - [Ключи и авторизация](./keys-auth.md) — типы ключей и скоупы - [Бот-платформа](./bots.md) — справочник эндпоинтов - [Entity API](./entity-api.md) — формат запросов к API портала --- # Инфраструктура Создание и управление виртуальными серверами для деплоя приложений Битрикс24. Каждый сервер невидим из интернета по умолчанию (режим Black Hole) — доступ к приложению только через HTTPS-субдомен `app-{id}.vibecode.bitrix24.tech`. Управление сервером и деплой — через REST API без SSH. **Скоуп:** `vibe:infra` (добавляется автоматически в каждый API-ключ) · **Базовый URL:** `https://vibecode.bitrix24.tech/v1` · **Авторизация:** заголовок `X-Api-Key` ## Разделы документации - [Провайдеры и каталоги](/docs/infra/providers) — список провайдеров, тарифов, регионов и образов ОС (4 эндпоинта). - [Серверы](/docs/infra/servers) — создание, список, детали, удаление (4 эндпоинта). - [Жизненный цикл](/docs/infra/lifecycle) — старт, стоп, сон, пробуждение, ремонт туннеля, статус провижининга (9 эндпоинтов). - [Доступ и режимы](/docs/infra/access) — политика доступа, список пользователей/отделов, SSH-данные, режим BLACKHOLE↔OPEN (7 эндпоинтов). - [Deploy API](/docs/infra/deploy) — выполнение команд, загрузка файлов, деплой приложения, логи, порт, метрики, лок, рантаймы (8 эндпоинтов). - [Токены доступа](/docs/infra/access-tokens) — краткосрочные токены для e2e-проверки и распространяемых ссылок (3 эндпоинта). - [Что приходит в приложение](/docs/infra/app-runtime) — Gateway-инжекция `X-Vibe-Authorization: Bearer`, чтение identity через `/v1/me`, скелеты обработчика на Node/Python/Go. - [Подписки на события портала](/docs/infra/event-subscriptions) — доставка событий Битрикс24 (`ONTASKADD` и подобных) в приложение через туннель, без опроса (3 эндпоинта). ## Что важно знать сразу 1. **Порт приложения — всегда 3000.** Black Hole туннель проксирует ровно этот порт; менять его не нужно. Сервер — изолированное окружение: `:3000` внутри виртуальной машины никак не связан с портами вашей локальной машины. 2. **Deploy API — только для BLACKHOLE.** Все `/deploy`, `/exec`, `/upload`, `/logs` требуют серверов в режиме `BLACKHOLE` со статусом `CONNECTED` для агента туннеля. Для OPEN-серверов они вернут ошибку. 3. **`/deploy` и `/exec` отдают JSON по умолчанию.** Это безопасно для AI-агентов и MCP-клиентов — никаких дополнительных query-параметров не нужно. Если вам действительно нужен потоковый ответ (live-вывод шагов деплоя в UI), передайте `?stream=true` — тогда вернётся SSE (Server-Sent Events). Раньше документация утверждала обратное (default SSE, `?stream=false` для JSON) — это устарело и больше не соответствует поведению API. 4. **`accessPolicy` — это безопасность.** Смена политики с `OWNER_ONLY` на `PORTAL`/`AUTHENTICATED`/`PUBLIC` открывает приложение другим пользователям. **Никогда не меняйте `accessPolicy` без явного подтверждения пользователя.** 5. **Сервер — это чистая Ubuntu 24.04, рут-доступ включён.** Виртуальная машина создаётся из стокового образа Ubuntu без предустановленного ПО (кроме агента туннеля). Агент работает от имени пользователя `root` — в `preStart`, `install` и командах `/exec` `sudo` не нужен. Исходящий интернет доступен без ограничений: `apt-get`, `curl`, `wget`, `pip` работают напрямую. Входящий трафик заблокирован кроме туннельного соединения. 6. **Тариф Битрикс24 играет двойную роль.** Во-первых, REST API самого Битрикс24 доступен только на коммерческих тарифах портала — без этого не работают ни приложения, ни прокси `/v1/deals`, ни боты, ни любой другой вызов, который проксируется в Битрикс24. Во-вторых, поверх этого — создание серверов, деплой и пробуждение требуют активной подписки BitrixGPT + Маркетплейс на портале. AI Router работает независимо от тарифа Битрикс24 — он не проксирует в REST и доступен даже на бесплатных тарифах (BYOK бесплатно; платформенные модели тарифицируются с баланса Вайбкод). Подробности — в разделе «Тариф и доступ» ниже. 7. **Авторизация пользователя в приложении.** На каждом запросе Gateway инжектирует шесть заголовков с префиксом `X-Vibe-`: `Request-Id` всегда плюс `User-Id`, `User-Name`, `User-Role`, `Portal-Id`, `Authorization` (`Bearer vibe_session_<…>`) для аутентифицированного запроса. Браузер `Authorization`-токен не видит и не хранит — он живёт только между Gateway и app-сервером. Для быстрого идентификатора пользователя достаточно заголовка `X-Vibe-User-Id`; полный контекст (скоупы, `capabilities`, тариф, информация о приложении) — одним вызовом `GET /v1/me` со server-side кэшированием. ID пользователя в ответе `/v1/me` — `data.currentUser.bitrixUserId`, домен портала — `data.portal`. Полная таблица заголовков, BFF-паттерн и скелеты обработчика на Node/Python/Go — [Что приходит в приложение](/docs/infra/app-runtime). 8. **Создание серверов требует пользовательской сессии для ключей `vibe_app_`.** `POST /v1/infra/servers` гейтится тарифной проверкой, которой нужно знать, кто именно создаёт сервер. Для `vibe_api_` пользовательский контекст уже есть в самом ключе; для `vibe_app_` обязателен `Authorization: Bearer ` — без него ответ `401 UNAUTHENTICATED` с `error.hint`, указывающим на OAuth-флоу. Чтение и Deploy API на уже существующих серверах сессии не требуют — таблица «Авторизация эндпоинтов» ниже сводит все правила в одном месте. ## Быстрый старт Три вызова — создание сервера и запуск приложения. ### curl — личный ключ ```bash export VIBE_KEY="YOUR_API_KEY" # 1. Создать сервер (автоматически в режиме Black Hole) curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "provider": "bitrix-cloud", "name": "my-app", "plan": "bc-small", "region": "ru-central1-b", "image": "fd83esfomhq25p2ono90" }' # 2. Дождаться готовности: status=running И blackholeStatus=CONNECTED curl -H "X-Api-Key: $VIBE_KEY" \ https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID # 3. Задеплоить приложение (?stream=false — JSON вместо SSE) curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/deploy?stream=false" \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "source": { "url": "https://github.com/user/app/archive/main.tar.gz" }, "runtime": "node20", "install": "cd /opt/app && npm install --production", "start": "cd /opt/app && node server.js", "port": 3000 }' ``` Приложение доступно по адресу `https://app-{id}.vibecode.bitrix24.tech` — поле `appUrl` в ответе `/deploy`. ### curl — OAuth-приложение ```bash # То же самое, только добавляется заголовок Authorization: Bearer с токеном сессии curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "provider": "bitrix-cloud", "name": "my-app", "plan": "bc-small", "region": "ru-central1-b", "image": "fd83esfomhq25p2ono90" }' ``` ## Полный пример Реалистичный сценарий на JavaScript — создание сервера, ожидание готовности, деплой, получение URL приложения. ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body = null) { const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) if (!res.ok) throw new Error(`${method} ${path} → ${res.status}`) return res.json() } // 1. Выбрать провайдера, тариф, регион, образ const { data: plans } = await api('GET', '/infra/providers/bitrix-cloud/plans') const { data: regions } = await api('GET', '/infra/providers/bitrix-cloud/regions') const { data: images } = await api('GET', '/infra/providers/bitrix-cloud/images') const plan = plans.find(p => p.id === 'bc-small') const region = regions.find(r => r.id === 'ru-central1-b') const image = images[0] // 2. Создать сервер (всегда в Black Hole) const { data: server } = await api('POST', '/infra/servers', { provider: 'bitrix-cloud', name: 'my-crm-bot', plan: plan.id, region: region.id, image: image.id, }) console.log(`Сервер создан: ${server.id}, субдомен: ${server.subdomain}`) // 3. Ждать пока статус не станет running И blackholeStatus не станет CONNECTED let info = server while (info.status !== 'running' || info.blackholeStatus !== 'CONNECTED') { await new Promise(r => setTimeout(r, 10000)) // 10 секунд между опросами const res = await api('GET', `/infra/servers/${server.id}`) info = res.data console.log(`status=${info.status}, blackhole=${info.blackholeStatus}`) } // 4. Задеплоить приложение (обязательно ?stream=false для JSON-ответа) const deploy = await api('POST', `/infra/servers/${server.id}/deploy?stream=false`, { source: { url: 'https://github.com/user/app/archive/main.tar.gz' }, runtime: 'node20', install: 'cd /opt/app && npm install --production', preStart: 'cd /opt/app && npx prisma migrate deploy', start: 'cd /opt/app && node server.js', port: 3000, env: { NODE_ENV: 'production' }, }) console.log(`Приложение живёт: ${deploy.data.appUrl}`) // 5. (Опционально) Настроить авто-сон через 60 минут простоя await api('PATCH', `/infra/servers/${server.id}/sleep`, { sleepAfterMinutes: 60 }) ``` ## Справочник эндпоинтов Все 35 эндпоинтов. Ссылки ведут на страницы с параметрами, примерами и кодами ошибок. **Провайдеры и каталоги:** | Метод | Путь | Описание | |-------|------|----------| | GET | [`/v1/infra/providers`](/docs/infra/providers/list) | Список облачных провайдеров | | GET | [`/v1/infra/providers/:providerId/plans`](/docs/infra/providers/plans) | Тарифы провайдера | | GET | [`/v1/infra/providers/:providerId/regions`](/docs/infra/providers/regions) | Регионы провайдера | | GET | [`/v1/infra/providers/:providerId/images`](/docs/infra/providers/images) | Образы ОС | **Серверы:** | Метод | Путь | Описание | |-------|------|----------| | POST | [`/v1/infra/servers`](/docs/infra/servers/create) | Создать сервер (всегда Black Hole) | | GET | [`/v1/infra/servers`](/docs/infra/servers/list) | Список ваших серверов | | GET | [`/v1/infra/servers/:id`](/docs/infra/servers/get) | Детали сервера | | DELETE | [`/v1/infra/servers/:id`](/docs/infra/servers/delete) | Удалить сервер | **Жизненный цикл:** | Метод | Путь | Описание | |-------|------|----------| | POST | [`/v1/infra/servers/:id/start`](/docs/infra/lifecycle/start) | Запустить остановленный/спящий сервер | | POST | [`/v1/infra/servers/:id/stop`](/docs/infra/lifecycle/stop) | Остановить работающий сервер | | POST | [`/v1/infra/servers/:id/reboot`](/docs/infra/lifecycle/reboot) | Перезагрузить сервер | | POST | [`/v1/infra/servers/:id/wake`](/docs/infra/lifecycle/wake) | Разбудить спящий сервер (асинхронно или блокирующе) | | POST | [`/v1/infra/servers/:id/sleep-now`](/docs/infra/lifecycle/sleep-now) | Немедленно усыпить BLACKHOLE-сервер | | PATCH | [`/v1/infra/servers/:id/sleep`](/docs/infra/lifecycle/sleep) | Настроить авто-засыпание | | POST | [`/v1/infra/servers/:id/refresh`](/docs/infra/lifecycle/refresh) | Запросить статус и IP у провайдера | | POST | [`/v1/infra/servers/:id/repair`](/docs/infra/lifecycle/repair) | Восстановить туннель через serial console | | GET | [`/v1/infra/servers/:id/repair-status`](/docs/infra/lifecycle/repair-status) | Прогресс восстановления туннеля | **Доступ и режимы:** | Метод | Путь | Описание | |-------|------|----------| | GET | [`/v1/infra/servers/:id/ssh`](/docs/infra/access/ssh) | SSH-данные (только для OPEN) | | PATCH | [`/v1/infra/servers/:id/mode`](/docs/infra/access/mode) | Переключить BLACKHOLE↔OPEN | | PATCH | [`/v1/infra/servers/:id/access-policy`](/docs/infra/access/access-policy) | Политика доступа к приложению | | GET | [`/v1/infra/servers/:id/access`](/docs/infra/access/access-list) | Список пользователей и отделов доступа | | POST | [`/v1/infra/servers/:id/access`](/docs/infra/access/access-add) | Добавить пользователя или отдел | | DELETE | [`/v1/infra/servers/:id/access/:accessId`](/docs/infra/access/access-delete) | Удалить запись доступа | | GET | [`/v1/infra/servers/:id/b24-users`](/docs/infra/access/b24-users) | Поиск пользователей портала Битрикс24 | **Deploy API:** | Метод | Путь | Описание | |-------|------|----------| | POST | [`/v1/infra/servers/:id/exec`](/docs/infra/deploy/exec) | Выполнить команду (SSE или JSON) | | POST | [`/v1/infra/servers/:id/upload`](/docs/infra/deploy/upload) | Загрузить файл (base64 или по URL) | | GET | [`/v1/infra/servers/:id/logs`](/docs/infra/deploy/logs) | Логи сервиса (утилита `journalctl`) | | POST | [`/v1/infra/servers/:id/deploy`](/docs/infra/deploy/deploy) | Полный деплой приложения | | PATCH | [`/v1/infra/servers/:id/port`](/docs/infra/deploy/port) | Задать порт приложения | | GET | [`/v1/infra/servers/:id/metrics`](/docs/infra/deploy/metrics) | Метрики активности туннеля | | DELETE | [`/v1/infra/servers/:id/lock`](/docs/infra/deploy/lock) | Снять зависший лок операции | | GET | [`/v1/infra/runtimes`](/docs/infra/deploy/runtimes) | Список доступных рантаймов | **Токены доступа:** | Метод | Путь | Описание | |-------|------|----------| | POST | [`/v1/infra/servers/:id/access-tokens`](/docs/infra/access-tokens/create) | Выпустить токен доступа (`api-bearer` или `share-url`) | | GET | [`/v1/infra/servers/:id/access-tokens`](/docs/infra/access-tokens/list) | Список токенов сервера | | DELETE | [`/v1/infra/servers/:id/access-tokens/:tokenId`](/docs/infra/access-tokens/delete) | Отозвать токен | **Подписки на события портала:** | Метод | Путь | Описание | |-------|------|----------| | POST | [`/v1/infra/servers/:id/event-subscriptions`](/docs/infra/event-subscriptions) | Подписать сервер на событие портала (`event.bind` под OAuth-приложением) | | GET | [`/v1/infra/servers/:id/event-subscriptions`](/docs/infra/event-subscriptions) | Список подписок + недавние доставки | | DELETE | [`/v1/infra/servers/:id/event-subscriptions/:subId`](/docs/infra/event-subscriptions) | Снять подписку | ## Авторизация эндпоинтов Все инфра-эндпоинты требуют заголовок `X-Api-Key`. Для ключей `vibe_app_` (привязка к OAuth-приложению) часть POST-операций дополнительно требует `Authorization: Bearer ` — без него ответ `401 UNAUTHENTICATED` с `error.hint`. Для ключей `vibe_api_` пользовательский контекст уже есть в самом ключе, отдельная сессия не нужна. | Эндпоинт | `X-Api-Key` | `Authorization: Bearer` для `vibe_app_` | Когда требует Bearer | |----------|:-----------:|:--------------------------------------:|----------------------| | `GET /v1/infra/providers/*` | да | нет | — | | `GET /v1/infra/servers`, `GET /v1/infra/servers/:id` | да | нет | — | | `GET /v1/infra/servers/:id/logs`, `/metrics`, `/access`, `/access-tokens`, `/b24-users`, `/ssh` | да | нет | — | | `GET /v1/infra/runtimes` | да | нет | — | | `POST /v1/infra/servers` (создать сервер) | да | **да** | Тарифный гейт: платформе нужно знать, кто именно создаёт сервер. | | `POST /v1/infra/servers/:id/deploy`, `/exec`, `/upload` | да | нет | Достаточно скоупа `vibe:infra` на ключе. | | `POST /v1/infra/servers/:id/start`, `/stop`, `/reboot`, `/wake`, `/sleep-now`, `/refresh`, `/repair`, `PATCH /sleep` | да | нет | — | | `PATCH /v1/infra/servers/:id/mode`, `/access-policy`, `/port` | да | нет | — | | `POST /v1/infra/servers/:id/access`, `DELETE /v1/infra/servers/:id/access/:accessId` | да | нет | — | | `POST /v1/infra/servers/:id/access-tokens`, `DELETE .../:tokenId` | да | нет | Платформенный флаг `accessTokensEnabled` должен быть включён; иначе `503 FEATURE_DISABLED`. | | `POST/GET/DELETE /v1/infra/servers/:id/event-subscriptions` | да | нет | Сервер должен быть привязан к OAuth-приложению с `application_token`; иначе `400 NOT_OAUTH_APP`. | | `DELETE /v1/infra/servers/:id` | да | нет | — | | `DELETE /v1/infra/servers/:id/lock` | да | нет | — | Быстрая проверка до вызова: `GET /v1/me` → `data.capabilities.servers.create.available`. Для `vibe_app_` без сессии возвращается `false` с `reason: "SESSION_REQUIRED"` и подсказкой в `userMessage` — модель сразу видит, что нужно пройти OAuth-флоу, а не ловить `401` на самом `POST /v1/infra/servers`. ## Лимиты | Лимит | Значение | |-------|----------| | Серверов на API-ключ | 3 | | Операций Deploy API в минуту на сервер | 10 | | Одновременных `exec`/`deploy` на сервер | 1 | | Таймаут `exec` | 1–600 секунд (по умолчанию 300) | | Размер base64-тела (`upload` inline, `source.content`) | 500 МБ | | Размер файла через `source.url` / `upload url` | 500 МБ | | Размер multipart-архива в `deploy` | 500 МБ | | Частота запросов `/ssh` | до 10 в минуту | Rate-limit платформы — общий для всех V1-эндпоинтов, [см. раздел «Лимиты и оптимизация»](/docs/optimization). ## Статусы сервера | Статус | Описание | |--------|----------| | `provisioning` | Виртуальная машина создаётся у провайдера (1–3 минуты) | | `running` | Виртуальная машина запущена, IP назначен. Для туннеля нужен ещё `blackholeStatus: CONNECTED` | | `sleeping` | Остановлен по таймеру сна или вручную. Автоматически просыпается при обращении к HTTPS-субдомену или вызове `/deploy`/`/start`/`/wake` | | `error` | Сервер не в рабочем состоянии: виртуальная машина удалена у провайдера, агент долго не подключается, внешний `externalId` отсутствует | | `deleted` | Сервер удалён (soft-delete). Нельзя восстановить | Поле `blackholeStatus` описывает состояние туннеля агента независимо от `status`: | Значение | Описание | |----------|----------| | `NONE` | Сразу после создания сервера, до первой попытки подключения агента | | `WAITING` | Агент готовится к подключению | | `CONNECTED` | Туннель активен, Deploy API доступен | | `DISCONNECTED` | Агент был подключён, сейчас нет связи — попробуйте [`/repair`](/docs/infra/lifecycle/repair) | Поле `runtimeStatus` — устаревшее, оставлено для совместимости. Для серверов, созданных после 2026-04-25 (когда параметр `runtime` был убран из [`POST /v1/infra/servers`](/docs/infra/servers/create)), всегда возвращается `null`. Рантайм теперь ставится на этапе [`POST /:id/deploy`](/docs/infra/deploy/deploy), а сигналом готовности служит сам успех шага `runtime` в ответе деплоя. ## Тариф и доступ У инфраструктуры Вайбкод два уровня условий по доступу. **Уровень 1 — REST API Битрикс24.** Сам Битрикс24 открывает REST API только на коммерческих тарифах портала. Это не про Вайбкод: на бесплатных тарифах Битрикс24 попросту не отдаёт REST-ответы. Значит, без коммерческого тарифа Битрикс24 не работают: - Создание и публикация приложений (`POST /api/apps`) — регистрируется на портале через REST. - REST-прокси: `/v1/deals`, `/v1/contacts`, `/v1/batch`, `/v1/bots`, `/v1/tasks` и все остальные сущности. - Боты, чаты, задачи — всё, что проксирует в Битрикс24. **Уровень 2 — Вайбкод-инфраструктура.** Сверх первого условия, создание серверов, деплой и пробуждение требуют активной подписки BitrixGPT + Маркетплейс на портале: - `POST /v1/infra/servers` — создание сервера. - `POST /v1/infra/servers/:id/deploy` — деплой приложения. - `POST /v1/infra/servers/:id/wake` и автоматическое пробуждение при `preventWake=true`. - Создание агентов и managed-ботов (они провижинят серверы под капотом). **Что работает на любом тарифе Битрикс24, включая бесплатный:** - AI Router — `POST /v1/chat/completions`, `POST /v1/audio/transcriptions`, `GET /v1/models`. Не проксирует в Битрикс24, напрямую ходит к провайдерам LLM. С BYOK-ключами — бесплатно; с платформенными моделями — тарифицируется с баланса Вайбкод. - Базовые эндпоинты платформы: `GET /v1/me`, `GET /v1/feedback`, `GET /v1/guide` — для самоориентации AI-агента. **Проверка до вызова:** `GET /v1/me` → поле `capabilities.servers.create.available`. Если `false` — поле `capabilities.servers.create.userMessage` содержит переведённое объяснение для пользователя. **Принудительное обновление после апгрейда:** `GET /v1/me?refresh=tariff` — пропускает кэш (по умолчанию 1 час) и делает свежий запрос к `app.info`. **Доступ к серверам:** единственный признак — `capabilities.servers.create` в ответе `GET /v1/me` (см. выше). Если доступ закрыт, `POST /v1/infra/servers` вернёт `402` (или `403` для `REGION_NOT_SUPPORTED`) с кодом гейта доступа (см. «Коды ошибок» ниже). Доступ управляется подпиской BitrixGPT + Маркетплейс на портале. **Заголовки ответа** инфра-эндпоинтов: | Заголовок | Значение | |-----------|----------| | `X-Tariff-Checked-At` | ISO-timestamp последней сверки через `app.info` (максимум 1 час кэша) | | `X-Tariff-Is-Commercial` | `"true"` или `"false"` | Коды ошибок гейта доступа перечислены в разделе «Коды ошибок» ниже. ## Коды ошибок ### Ошибки инфраструктуры | Код | HTTP | Описание | |-----|------|----------| | `NOT_FOUND` | 404 | Сервер не найден или принадлежит другому API-ключу | | `INVALID_REQUEST` | 400 | Ошибка валидации (неверное имя, тариф, регион, образ) | | `INFRA_NOT_PERMITTED` | 403 | Инфраструктура отключена на платформе или на портале | | `SERVER_CREATION_DISABLED` | 403 | Создание серверов запрещено политикой портала | | `MAX_SERVERS_REACHED` | 403 | Превышен лимит 3 серверов на API-ключ | | `NO_CREDENTIALS` | 404 | Провайдер не сконфигурирован на платформе | | `SERVER_NOT_READY` | 409 | Сервер ещё создаётся, операция пока недоступна | | `CONFLICT` | 409 | Сервер в статусе, из которого нельзя выполнить действие (например `start` работающего) | | `PROVIDER_ERROR` | 502 | Облачный провайдер вернул ошибку | | `VM_MISSING` | 422 | У записи нет `externalId` — виртуальная машина не создана у провайдера или удалена извне. Удалите сервер через `DELETE` и создайте новый | | `PORT_RESTRICTED` | 400 | Порт 1–1023 (системные порты запрещены). Допустимы `0` (автоопределение) и `1024–65535` | | `BLACKHOLE_ONLY` | 400 | Эндпоинт работает только для BLACKHOLE-серверов (актуально для `/sleep-now`, `/sleep`, `/metrics`) | | `OPEN_MODE_NOT_ALLOWED` | 403 | Переключение в OPEN запрещено политикой портала `allowOpenMode` | | `SAME_MODE` | 400 | Сервер уже в запрошенном режиме | | `NOT_IMPLEMENTED` | 501 | Действие не поддерживается провайдером (например `/reboot` на некоторых плагинах) | | `REPAIR_BLOCKED` | 409 | Репэр заблокирован (`preventWake=true` или сервер удалён) | ### Ошибки Deploy API | Код | HTTP | Описание | |-----|------|----------| | `AGENT_NOT_CONNECTED` | 409 | Агент туннеля не в статусе `CONNECTED` | | `EXEC_BUSY` | 409 | На сервере уже выполняется другая операция. Используйте [`/lock`](/docs/infra/deploy/lock) для снятия зависшего лока | | `EXEC_TIMEOUT` | 504 | Превышен таймаут выполнения | | `EXEC_FAILED` | 500 | Ошибка выполнения команды на агенте | | `UPLOAD_PATH_DENIED` | 403 | Запрещённый путь для загрузки | | `DEPLOY_FAILED` | 500 | Ошибка в процессе деплоя (см. поле `step` в ответе) | | `VALIDATION_ERROR` | 400 | Некорректное тело запроса Deploy API | ### Ошибки гейта доступа и биллинга | Код | HTTP | Описание | |-----|------|----------| | `MARKETPLACE_REQUIRED` | 402 | На портале нет активной подписки BitrixGPT + Маркетплейс — оформите её, чтобы открыть создание серверов, деплой и пробуждение | | `KZ_PAID_ONLY` | 402 | В Казахстане подписка BitrixGPT + Маркетплейс доступна только на платном тарифе (демо-доступа нет) | | `REGION_NOT_SUPPORTED` | 403 | Подписка BitrixGPT + Маркетплейс пока недоступна в регионе портала | | `COMMERCIAL_PLAN_REQUIRED` | 402 | Бесплатный тариф Битрикс24 без активной подписки BitrixGPT + Маркетплейс | | `TRIAL_PORTAL_LIMIT` | 402 | Превышен лимит серверов на портал для демо-доступа RU/BY (1 сервер на портал) | | `PLAN_NOT_ALLOWED_ON_TRIAL` | 402 | Запрошенный план недоступен на демо-доступе RU/BY (разрешён только `bc-micro`) | | `ACCOUNT_FROZEN` | 402 | Баланс Вайбкод заморожен. Нужно пополнить | | `BILLING_EXHAUSTED` | 402 | Баланс Вайбкод исчерпан. Пробуждение и деплой заблокированы | | `SERVER_WAKE_BLOCKED` | 403 | Пробуждение заблокировано (не из-за биллинга: административный блок, безопасность) | ### Системные ошибки | Код | HTTP | Описание | |-----|------|----------| | `MISSING_API_KEY` | 401 | Не передан заголовок `X-Api-Key` | | `INVALID_API_KEY` | 401 | Неверный или просроченный API-ключ | | `SCOPE_DENIED` | 403 | У ключа нет скоупа `vibe:infra` | | `RATE_LIMIT_EXCEEDED` | 429 | Превышен rate-limit | | `INTERNAL_ERROR` | 500 | Внутренняя ошибка сервера | Полный справочник общих ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Обзор API](/docs/overview) — общая архитектура платформы. - [Лимиты и оптимизация](/docs/optimization) — ограничения частоты, авто-пагинация, batch-запросы. - [Личный кабинет API (`/v1/me`)](/docs/me) — проверка тарифа и возможностей. - [Что приходит в приложение](/docs/infra/app-runtime) — Gateway-инжекция `X-Vibe-Authorization`, BFF-паттерн, скелеты обработчика. --- # Телефония Управление телефонией Битрикс24: регистрация внешних звонков в CRM, исходящие автоматические звонки и обратный звонок, прикрепление транскрипций, статистика звонков, управление линиями приложения. **Скоуп:** `telephony` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` [Быстрый старт](#быстрый-старт) | [Полный пример](#полный-пример) | [Справочник эндпоинтов](#справочник-эндпоинтов) | [Коды ошибок](#коды-ошибок) ## Разделы документации - [Звонки в CRM](/docs/telephony/crm) — регистрация внешних звонков, завершение, карточка оператору, транскрипции - [Исходящие звонки](/docs/telephony/outbound) — обратный звонок и автоматические звонки с синтезом речи или аудиофайлом - [Линии](/docs/telephony/lines) — внешние линии приложения и список арендованных у Voximplant - [Аналитика и справочники](/docs/telephony/analytics) — статистика звонков и справочник голосов для синтеза речи --- ## Быстрый старт ### 1. Зарегистрируйте звонок ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/register \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userId": 1, "phoneNumber": "+79161234567", "type": 2, "crmCreate": true }' ``` Ответ (HTTP 201): ```json { "success": true, "data": { "CALL_ID": "externalCall.00b1e735843c558431be668e3687a58b.1777974304", "CRM_CREATED_LEAD": 1001069, "CRM_CREATED_ENTITIES": [{"ENTITY_TYPE": "LEAD", "ENTITY_ID": 1001069}], "CRM_ENTITY_TYPE": "LEAD", "CRM_ENTITY_ID": 1001069 } } ``` ### 2. Завершите звонок ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/externalCall.00b1e735843c558431be668e3687a58b.1777974304/finish \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"userId": 1, "duration": 120, "statusCode": "200"}' ``` ### 3. Прикрепите транскрипцию ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/externalCall.00b1e735843c558431be668e3687a58b.1777974304/transcription \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "messages": [ {"side": "User", "startTime": 0, "stopTime": 3, "message": "Здравствуйте, чем могу помочь?"}, {"side": "Client", "startTime": 4, "stopTime": 8, "message": "У меня вопрос по заказу"} ] }' ``` Ответ: ```json { "success": true, "data": { "TRANSCRIPT_ID": 3 } } ``` --- ## Полный пример JavaScript-скрипт обработки входящего звонка: регистрация в CRM с автосозданием лида → отображение карточки оператору → завершение → прикрепление транскрипции → проверка статистики. ```javascript const KEY = process.env.VIBE_API_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body) { const opts = { method, headers: { 'X-Api-Key': KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) if (res.status === 204) return null return res.json() } // 1. Регистрируем внешний звонок и создаём лид, если номера ещё нет в CRM const reg = await api('POST', '/calls/register', { userId: 1, phoneNumber: '+79161234567', type: 2, crmCreate: true }) const callId = reg.data.CALL_ID console.log('Звонок зарегистрирован:', callId) console.log('Создан лид:', reg.data.CRM_CREATED_LEAD) // 2. Показываем карточку звонка оператору await api('POST', `/calls/${callId}/show`, { userId: 1 }) // 3. Завершаем звонок (длительность 245 секунд, успех) const fin = await api('POST', `/calls/${callId}/finish`, { userId: 1, duration: 245, statusCode: '200' }) console.log('CRM-активность:', fin.data.CRM_ACTIVITY_ID) // 4. Прикрепляем транскрипцию await api('POST', `/calls/${callId}/transcription`, { messages: [ { side: 'User', startTime: 0, stopTime: 4, message: 'Здравствуйте, компания Вайб!' }, { side: 'Client', startTime: 5, stopTime: 12, message: 'Здравствуйте, я хотел бы уточнить детали заказа 4521' }, { side: 'User', startTime: 13, stopTime: 25, message: 'Конечно, заказ отправлен, трек-номер RU123456789' } ] }) // 5. Смотрим статистику за сегодня const today = new Date().toISOString().slice(0, 10) + 'T00:00:00' const stats = await api('GET', `/calls/statistics?filter[>CALL_START_DATE]=${today}`) console.log(`Звонков сегодня: ${stats.total}`) ``` --- ## Справочник эндпоинтов | Метод | Путь | Bitrix24 метод | Описание | |-------|------|----------------|---------| | POST | [/v1/calls/register](/docs/telephony/crm/register) | telephony.externalcall.register | Зарегистрировать внешний звонок в CRM | | POST | [/v1/calls/:callId/finish](/docs/telephony/crm/finish) | telephony.externalcall.finish | Завершить звонок | | POST | [/v1/calls/:callId/show](/docs/telephony/crm/show) | telephony.externalcall.show | Показать карточку звонка оператору | | POST | [/v1/calls/:callId/hide](/docs/telephony/crm/hide) | telephony.externalcall.hide | Скрыть карточку звонка | | POST | [/v1/calls/:callId/transcription](/docs/telephony/crm/transcription) | telephony.call.attachTranscription | Прикрепить транскрипцию | | POST | [/v1/calls/callback](/docs/telephony/outbound/callback) | voximplant.callback.start | Обратный звонок (оператор → клиент) | | POST | [/v1/calls/auto-call](/docs/telephony/outbound/auto-call) | voximplant.infocall.startwithtext | Автозвонок с синтезом речи | | POST | [/v1/calls/auto-call-audio](/docs/telephony/outbound/auto-call-audio) | voximplant.infocall.startwithsound | Автозвонок с воспроизведением аудиофайла | | GET | [/v1/telephony-lines](/docs/telephony/lines/list) | telephony.externalLine.get | Список линий приложения | | POST | [/v1/telephony-lines](/docs/telephony/lines/create) | telephony.externalLine.add | Добавить линию приложения | | PATCH | [/v1/telephony-lines/:number](/docs/telephony/lines/update) | telephony.externalLine.update | Обновить линию | | DELETE | [/v1/telephony-lines/:number](/docs/telephony/lines/delete) | telephony.externalLine.delete | Удалить линию | | GET | [/v1/voximplant-lines](/docs/telephony/lines/voximplant) | voximplant.line.get | Список линий Voximplant (арендованные и SIP) | | GET | [/v1/calls/statistics](/docs/telephony/analytics/statistics) | voximplant.statistic.get | Статистика звонков | | GET | [/v1/calls/voices](/docs/telephony/analytics/voices) | voximplant.tts.voices.get | Справочник голосов синтеза речи | --- ## Коды ошибок ### Ошибки телефонии | Код | HTTP | Описание | |-----|------|---------| | `MISSING_PARAMS` | 400 | Не передан обязательный параметр (точное сообщение зависит от эндпоинта) | | `INVALID_MESSAGE_SHAPE` | 400 | Только для `transcription`: некорректная структура одного из элементов массива `messages` | | `BITRIX_ERROR` | 422 | Битрикс24 вернул ошибку (сообщение из B24 в поле `error.message`) | | `BITRIX_UNAVAILABLE` | 502 | Битрикс24 недоступен | ### Системные ошибки | Код | HTTP | Описание | |-----|------|---------| | `MISSING_API_KEY` | 401 | Не передан заголовок `X-Api-Key` | | `INVALID_API_KEY` | 401 | Неверный API-ключ | | `KEY_INACTIVE` | 401 | API-ключ неактивен или отозван | | `TOKEN_MISSING` | 401 | Ключ не имеет настроенных токенов Битрикс24 | | `SCOPE_DENIED` | 403 | Ключу не хватает скоупа `telephony` | | `RATE_LIMITED` | 429 | Превышен лимит запросов | Полный список общих ошибок API — [Ошибки](/docs/errors). --- ## Смотрите также - [Лиды](/docs/entities/leads) — автоматически создаются при `crmCreate: true` в register - [Контакты](/docs/entities/contacts) — связываются со звонками по номеру телефона - [Сделки](/docs/entities/deals) — звонки попадают в таймлайн связанной сделки --- # CRM Автоматизация Запускайте CRM-триггеры и бизнес-процессы через API. Автоматизируйте воронку продаж, переводите сделки по стадиям, запускайте цепочки согласований программно. **Скоуп:** `crm` (триггеры), `bizproc` (бизнес-процессы) | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Разделы документации - [Триггеры](/docs/automation/triggers) — активация CRM-триггеров для сущностей (2 эндпоинта). - [Бизнес-процессы](/docs/automation/workflows) — запуск, мониторинг и управление бизнес-процессами (5 эндпоинтов). ## Быстрый старт ### Активировать CRM-триггер ```bash curl -X POST https://vibecode.bitrix24.tech/v1/triggers/fire \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityType": "deal", "entityId": 100, "triggerId": "payment_received" }' ``` Ответ: ```json { "success": true, "data": true } ``` Полная документация параметров и кодов ошибок: [`POST /v1/triggers/fire`](/docs/automation/triggers/fire) ### Запустить бизнес-процесс ```bash curl -X POST https://vibecode.bitrix24.tech/v1/workflows/start \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateId": 15, "entityType": "deal", "entityId": 100, "parameters": { "approver": 1, "comment": "Согласование скидки 15%" } }' ``` Ответ: ```json { "success": true, "data": { "workflowId": "67a1b2c3d4e5f6" } } ``` Полная документация параметров и кодов ошибок: [`POST /v1/workflows/start`](/docs/automation/workflows/start) ## Полный пример Сценарий: сделка перешла в стадию «Оплачено» — активируем CRM-триггер, затем запускаем бизнес-процесс подготовки документов, отправляем событие для продолжения приостановленного процесса, завершаем ненужный экземпляр. ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body = null) { const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) return res.json() } const dealId = 100 // 1. Сделка оплачена — активируем CRM-триггер await api('POST', '/triggers/fire', { entityType: 'deal', entityId: dealId, triggerId: 'payment_received' }) console.log('Триггер "Оплата получена" активирован') // 2. Запускаем бизнес-процесс подготовки документов const { data: wf } = await api('POST', '/workflows/start', { templateId: 22, entityType: 'deal', entityId: dealId, parameters: { docType: 'act', sendToClient: true } }) console.log('Бизнес-процесс запущен:', wf.workflowId) // 3. Просматриваем запущенные экземпляры по шаблону const { data: instances, meta } = await api('GET', '/workflows?templateId=22') console.log(`Активных процессов по шаблону 22: ${meta.total}`) for (const instance of instances) { console.log(` ${instance.ID}: started=${instance.STARTED}`) } // 4. Отправляем событие в приостановленный процесс // eventToken приходит на handler зарегистрированной активити из B24-callback // (см. /docs/entities/bizproc-activities), здесь — иллюстративное значение await api('POST', '/workflows/event', { eventToken: '55c1dc1c3f0d75.67', returnValues: { approved: true }, logMessage: 'Автоматическое подтверждение — сумма в пределах лимита' }) console.log('Событие отправлено, процесс продолжен') // 5. Завершаем ненужный экземпляр await fetch(`${BASE}/workflows/${wf.workflowId}`, { method: 'DELETE', headers: { 'X-Api-Key': VIBE_KEY } }) console.log('Процесс завершён') ``` ## Справочник эндпоинтов | Метод | Путь | Bitrix24 метод | Скоуп | Описание | |-------|------|---------------|-------|---------| | POST | [`/v1/triggers/fire`](/docs/automation/triggers/fire) | crm.automation.trigger | crm | Активировать CRM-триггер | | GET | [`/v1/triggers`](/docs/automation/triggers/list) | crm.automation.trigger.list | crm | Список триггеров портала | | POST | [`/v1/workflows/start`](/docs/automation/workflows/start) | bizproc.workflow.start | bizproc | Запустить бизнес-процесс | | GET | [`/v1/workflows`](/docs/automation/workflows/list) | bizproc.workflow.instances | bizproc | Список запущенных процессов | | DELETE | [`/v1/workflows/:id`](/docs/automation/workflows/terminate) | bizproc.workflow.terminate / kill | bizproc | Завершить бизнес-процесс | | POST | [`/v1/workflows/event`](/docs/automation/workflows/event) | bizproc.event.send | bizproc | Отправить событие в процесс | | POST | [`/v1/workflows/activity-log`](/docs/automation/workflows/activity-log) | bizproc.activity.log | bizproc | Записать в журнал процесса | ## Коды ошибок ### Ошибки автоматизации | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_ENTITY_TYPE` | Неизвестный тип сущности в `entityType`. Поддерживаются: `deal`, `lead`, `contact`, `company`, `quote`, `invoice` | | 400 | `MISSING_PARAMS` | Не переданы обязательные параметры (указаны в поле `message` ответа) | | 400 | `INVALID_PARAMS` | Некорректное значение параметра (возвращается Битрикс24) | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов Битрикс24 | | 403 | `SCOPE_DENIED` | API-ключ не имеет нужного скоупа: `crm` для триггеров, `bizproc` для бизнес-процессов | | 403 | `BITRIX_ACCESS_DENIED` | Портал Битрикс24 отклонил операцию — недостаточно прав на стороне портала | | 404 | `ENTITY_NOT_FOUND` | Сущность или шаблон с указанным ID не найден | | 422 | `BITRIX_ERROR` | Ошибка Битрикс24 REST API (подробности в поле `message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов. Подождите 1–2 секунды и повторите | | 500 | `INTERNAL_ERROR` | Внутренняя ошибка сервера | | 502 | `BITRIX_UNAVAILABLE` | Портал Битрикс24 недоступен | | 504 | `QUEUE_TIMEOUT` | Запрос к Битрикс24 ожидал в очереди дольше 30 секунд | Полный справочник общих ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Сделки](/docs/entities/deals) — основная сущность для автоматизации воронки продаж - [Лиды](/docs/entities/leads) — запуск триггеров и бизнес-процессов для лидов - [Шаблоны бизнес-процессов](/docs/entities/bizproc-templates) — список шаблонов для параметра `templateId` - [Действия бизнес-процессов](/docs/entities/bizproc-activities) — регистрация пользовательских действий - [Роботы](/docs/entities/bizproc-robots) — регистрация пользовательских роботов - [Ошибки](/docs/errors) — полный справочник кодов ошибок --- # Рабочий день Учёт рабочего времени сотрудника: открытие и закрытие дня, пауза, текущий статус, настройки портала и график работы. **Скоуп:** `timeman` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` [Какой ключ выбрать](#какой-ключ-выбрать) | [Быстрый старт](#быстрый-старт) | [Полный пример](#полный-пример-автоматический-учёт-рабочего-дня) | [Справочник эндпоинтов](#справочник-эндпоинтов) | [Коды ошибок](#коды-ошибок) ## Какой ключ выбрать Раздел работает с двумя типами ключей. Выбор определяет, от чьего имени фиксируется рабочий день. | Сценарий | Ключ | Заголовки запроса | |---------|------|-------------------| | Личный учёт времени, скрипт на собственном сервере | Личный API-ключ `vibe_api_…` | `X-Api-Key: vibe_api_…` | | OAuth-приложение из каталога Вайбкод — учёт времени для каждого пользователя, установившего приложение | Ключ авторизации `vibe_app_…` | `X-Api-Key: vibe_app_…` + `Authorization: Bearer ` | Действия фиксируются от лица владельца ключа (для личного) или пользователя сессии (для OAuth). Подробное описание форматов и получение `session_token` — [Ключи и авторизация](/docs/keys-auth). --- ## Быстрый старт ### 1. Узнайте текущий статус ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/workday/status ``` ```json { "success": true, "data": { "status": "CLOSED", "timeStart": "2026-05-04T09:00:00+03:00", "timeFinish": "2026-05-04T18:00:00+03:00", "duration": "08:00:00", "timeLeaks": "00:30:00", "active": true, "ipOpen": "203.0.113.10", "ipClose": "203.0.113.10", "latOpen": 0, "lonOpen": 0, "latClose": 0, "lonClose": 0, "tzOffset": 10800 } } ``` ### 2. Откройте рабочий день ```bash curl -X POST https://vibecode.bitrix24.tech/v1/workday/open \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{}' ``` ### 3. Закройте день с отчётом ```bash curl -X POST https://vibecode.bitrix24.tech/v1/workday/close \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "report": "Закрыл 5 сделок, обработал 12 лидов" }' ``` --- ## Полный пример: автоматический учёт рабочего дня Сценарий: скрипт открывает день в 9:00, отслеживает обеденный перерыв и закрывает день в 18:00 с автоматическим отчётом. ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body = null) { const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) return res.json() } // 1. Узнаём текущий статус — чтобы не открывать уже открытый день const { data: current } = await api('GET', '/workday/status') console.log('Текущий статус:', current.status) // 2. Открываем рабочий день, если он закрыт if (current.status === 'CLOSED' || !current.status) { const { data: opened } = await api('POST', '/workday/open', {}) console.log('День открыт в', opened.timeStart) } else { console.log('День уже открыт с', current.timeStart) } // 3. Получаем настройки учёта на портале const { data: settings } = await api('GET', '/workday/settings') console.log('Допустимое начало дня до:', settings.ufTmMaxStart) console.log('Минимальная длительность дня:', settings.ufTmMinDuration) // 4. Уход на обед — ставим паузу const { data: paused } = await api('POST', '/workday/pause', {}) console.log('День на паузе с', paused.timeFinish) // ...перерыв... // 5. Возвращаемся с обеда — продолжаем день const { data: resumed } = await api('POST', '/workday/open', {}) console.log('День продолжен, статус:', resumed.status) // 6. Конец рабочего дня — закрываем с отчётом const { data: closed } = await api('POST', '/workday/close', { report: 'Автоматическое закрытие' }) console.log('День закрыт, отработано:', closed.duration) console.log('Длительность перерыва:', closed.timeLeaks) ``` --- ## Справочник эндпоинтов | Метод | Путь | Bitrix24 метод | Описание | |-------|------|---------------|---------| | POST | [/v1/workday/open](/docs/workday/open) | timeman.open | Открыть или продолжить рабочий день | | POST | [/v1/workday/close](/docs/workday/close) | timeman.close | Закрыть рабочий день | | POST | [/v1/workday/pause](/docs/workday/pause) | timeman.pause | Приостановить рабочий день | | GET | [/v1/workday/status](/docs/workday/status) | timeman.status | Текущий статус рабочего дня | | GET | [/v1/workday/settings](/docs/workday/settings) | timeman.settings | Настройки учёта на портале | | GET | [/v1/workday/schedule](/docs/workday/schedule) | timeman.schedule.get | Сведения о графике работы по `id` | Интерактивный переключатель методов с примерами и таблицами полей — [Эндпоинты](/docs/workday/endpoints). --- ## Коды ошибок | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Битрикс24 вернул `INVALID_PARAMS` — нарушена валидация полей запроса | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `KEY_EXPIRED` | Срок действия API-ключа истёк | | 401 | `TOKEN_MISSING` | Ключу не настроены OAuth-токены для портала | | 402 | `ACCOUNT_FROZEN` | Баланс портала заморожен — пополните баланс | | 403 | `SCOPE_DENIED` | У ключа нет скоупа `timeman` | | 422 | `BITRIX_ERROR` | Битрикс24 отклонил запрос — текст в `message` (например, попытка закрыть уже закрытый день) | | 429 | `RATE_LIMITED` | Превышен лимит запросов к Битрикс24 | | 502 | `BITRIX_UNAVAILABLE` | Портал Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). --- ## Смотрите также - [Ключи и авторизация](/docs/keys-auth) — типы ключей, скоупы, формат `session_token`. - [Лимиты и оптимизация](/docs/optimization) — общие ограничения API. - [Ошибки](/docs/errors) — справочник кодов и стратегии обработки. --- # MCP для AI Вайбкод публикует два MCP-сервера для AI-агентов — подходят для Claude Desktop, Claude Code, Cursor, Codex CLI, Windsurf, Gemini CLI и любого другого клиента с поддержкой Model Context Protocol. - `mcp-vibe-api` — инструменты для работы с Битрикс24 через Vibe API. - `mcp-docs` — справочник по REST-методам Битрикс24. [Установка mcp-vibe-api](#mcp-vibe-api) | [Инструменты (53)](#инструменты-53) | [HTTP-транспорт](#http-транспорт) | [mcp-docs](#mcp-docs) | [Безопасность](#безопасность) ## Что можно делать через MCP Подборка диалогов с AI-агентом и инструментов, которые агент реально вызывает. Помогает оценить возможности `mcp-vibe-api` и подобрать набор скоупов для ключа. ### Аналитика по сделкам > **Пользователь:** Покажи сумму сделок в работе по каждому ответственному за последний месяц. Агент по очереди вызывает: 1. `aggregate_entities` для сущности `deals` с фильтром по `closeDate`, агрегатом `sum` по полю `amount` и группировкой по `assignedById`. 2. `list_entities` для сущности `users` — чтобы заменить идентификаторы на имена сотрудников. Скоуп ключа: `crm`, `user`. ### Создание и публикация бота > **Пользователь:** Зарегистрируй бота с именем «Помощник» и пришли тестовое сообщение в чат с моим коллегой. Агент по очереди вызывает: 1. `manage_bot` с действием `register` — создаёт бота на портале. 2. `manage_bot` с действием `get_events` — получает идентификатор диалога с коллегой из входящего события. 3. `manage_bot_messages` с действием `send` — отправляет приветственное сообщение в нужный диалог. Скоуп ключа: `imbot`. ### Развёртывание приложения на сервере > **Пользователь:** Подними новый сервер в BitrixCloud и выкатишь туда архив с приложением. Агент по очереди вызывает: 1. `manage_server` с действиями `list_providers`, `list_plans`, `list_regions`, `list_images` — собирает каталог. 2. `manage_server` с действием `create` — создаёт сервер в выбранной конфигурации. 3. `manage_server` с действием `get` — ждёт, пока статус станет `RUNNING` и `CONNECTED`. 4. `manage_server_deploy` с действием `deploy` — запускает конвейер развёртывания (загрузка архива, установка, systemd, проверка работоспособности). 5. `manage_server_deploy` с действием `logs` — читает журналы при ошибках. Скоуп ключа: `vibe:infra`. ### Подключение собственного провайдера AI > **Пользователь:** Добавь мой ключ OpenAI и сделай тестовый запрос к gpt-4o. Агент по очереди вызывает: 1. `manage_ai_credentials` с действием `list_providers` — выясняет идентификатор провайдера OpenAI. 2. `manage_ai_credentials` с действием `create` — сохраняет ключ; провайдер проверяется до записи и возвращает `422 CREDENTIAL_INVALID`, если ключ не работает. 3. `ai_chat` с действием `chat` и параметром `model: "openai/gpt-4o"` — отправляет тестовый запрос через AI Router. Скоуп ключа: `vibe:ai`. ### Оставить запрос в поддержку через AI > **Пользователь:** Эндпоинт `/v1/deals/aggregate` иногда возвращает пустой ответ — заведи тикет с подробностями. Агент по очереди вызывает: 1. `get_me` — забирает идентификатор портала и текущий тариф для поля `context`. 2. `manage_feedback` с действием `create` — отправляет тикет с категорией `BUG`, заголовком, описанием воспроизведения и сериализованным `context` (эндпоинт, тело запроса, код ответа). Скоуп ключа: создание тикетов доступно любому ключу. ## mcp-vibe-api Сервер, который даёт AI-агенту доступ к Битрикс24 через Vibe API. Дальше — установка, параметры запуска, инструменты, Resources, Prompts и HTTP-транспорт. ### Установка Пакет [`@bitrix24/mcp-vibecode-api`](https://www.npmjs.com/package/@bitrix24/mcp-vibecode-api). После установки доступна команда `mcp-vibe-api`. Нужен Node.js версии 18 или выше — подойдёт любая актуальная LTS-сборка (18, 20, 22). ```bash npm install -g @bitrix24/mcp-vibecode-api ``` ### Регистрация в клиенте через CLI Если клиент умеет управлять MCP-серверами через консоль, конфиг-файл редактировать не нужно — достаточно одной команды. Claude Code: ```bash claude mcp add vibecode -- mcp-vibe-api --key vibe_api_your_key_here ``` Команда добавит сервер в локальный конфиг текущего пользователя. Чтобы поделиться настройкой со всем проектом, добавьте флаг `-s project` — конфиг попадёт в `.mcp.json` репозитория. Управлять списком: `claude mcp list`, `claude mcp remove vibecode`. Codex CLI: ```bash codex mcp add vibecode -- mcp-vibe-api --key vibe_api_your_key_here ``` Запись попадёт в `~/.codex/config.toml`. Передать API-ключ через переменную окружения вместо аргумента: `codex mcp add vibecode --env VIBE_API_KEY=vibe_api_your_key_here -- mcp-vibe-api`. Для проектного scope создайте `.codex/config.toml` в корне репозитория и пропишите блок `[mcp_servers.vibecode]` напрямую. Gemini CLI: ```bash gemini mcp add vibecode mcp-vibe-api --key vibe_api_your_key_here ``` Запись попадёт в `~/.gemini/settings.json`. Передать ключ через переменную окружения: `gemini mcp add -e VIBE_API_KEY=vibe_api_your_key_here vibecode mcp-vibe-api`. Для проектного scope используйте `.gemini/settings.json` в корне репозитория. ### Регистрация через конфиг-файл Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json` на macOS, `%APPDATA%\Claude\claude_desktop_config.json` на Windows): ```json { "mcpServers": { "vibecode": { "command": "mcp-vibe-api", "args": ["--key", "vibe_api_your_key_here"] } } } ``` Cursor (`.cursor/mcp.json` в корне проекта): ```json { "mcpServers": { "vibecode": { "command": "mcp-vibe-api", "args": ["--key", "vibe_api_your_key_here"] } } } ``` Codex CLI (`~/.codex/config.toml`): ```toml [mcp_servers.vibecode] command = "mcp-vibe-api" args = ["--key", "vibe_api_your_key_here"] ``` ### Запуск без глобальной установки Если глобально установить пакет нельзя, замените `mcp-vibe-api` на `npx -y @bitrix24/mcp-vibecode-api` в любом конфиге выше. Пример для Claude Desktop: ```json { "mcpServers": { "vibecode": { "command": "npx", "args": ["-y", "@bitrix24/mcp-vibecode-api", "--key", "vibe_api_your_key_here"] } } } ``` ### Параметры запуска Ключ и базовый URL передаются флагами командной строки или через переменные окружения. При коллизии флаг побеждает. | Флаг | Переменная окружения | По умолчанию | Описание | |------|----------------------|--------------|----------| | `--key ` | `VIBE_API_KEY` | — | API-ключ Вайбкод (`vibe_api_...` или `vibe_app_...`) | | `--api-url ` | `VIBE_API_URL` | `https://vibecode.bitrix24.tech` | Базовый URL Vibe API | | `--http` | — | выключен | Включить HTTP-транспорт вместо stdio | | `--http-token ` | `VIBE_MCP_HTTP_TOKEN` | — | Bearer-токен для HTTP-транспорта (обязателен с `--http`) | | `--host ` | — | `127.0.0.1` | Адрес для HTTP-транспорта | | `--port ` | — | `3001` | TCP-порт для HTTP-транспорта | | `--allowed-origins ` | — | пусто | Список разрешённых браузерных `Origin`, через запятую | | `--max-body-kb ` | — | `256` | Лимит тела запроса в килобайтах | | `--rate-limit ` | — | `300` | Лимит запросов в минуту на IP | | `-h`, `--help` | — | — | Показать справку | | `-v`, `--version` | — | — | Показать версию пакета | Установка ключа через переменную окружения, чтобы не хранить его в конфигах: ```bash export VIBE_API_KEY="vibe_api_your_key_here" mcp-vibe-api ``` ### Доступ по типу ключа `mcp-vibe-api` работает с двумя типами ключей Вайбкод и при старте запрашивает `/v1/me`, чтобы определить тип. Дальше клиенту отдаются только те инструменты, которые ключ может использовать. | Тип ключа | Какие инструменты доступны | |-----------|----------------------------| | `vibe_api_...` или `vibe_app_...` (ключ портала) | Данные Битрикс24, AI, сборка приложений, служебные | | `vibe_live_...` (управляющий ключ) | Платформенное управление, служебные | В описании каждой группы инструментов ниже указан тип ключа, который к ней подходит. ### Инструменты (53) Все инструменты возвращают JSON. Для специализированных эндпоинтов есть типизированные обёртки — используйте их вместо `call_api`, когда они доступны: подсказки по параметрам и валидация выше. Инструменты сгруппированы в пять кластеров по типу задачи. #### Данные Битрикс24 (27) — ключ портала Чтение и запись данных портала: CRM-сущности, чаты и боты, расширения для CRM, телефония, файлы, бизнес-процессы, рабочее время. Подходит большинству задач AI-агента. ##### Сущности CRM и других модулей (10) Покрывают единый CRUD-интерфейс над 40+ сущностями Битрикс24 — от сделок и контактов до задач, файлов, документов и записей смарт-процессов. | Инструмент | Описание | |------------|----------| | `discover` | Список сущностей и их полей из OpenAPI-схемы | | `get_fields` | Поля сущности с учётом пользовательских полей `UF_*` | | `list_entities` | Список записей с фильтрацией, сортировкой, автопагинацией при `limit > 50` | | `get_entity` | Запись по ID | | `create_entity` | Создание записи | | `update_entity` | Частичное обновление записи | | `delete_entity` | Удаление записи | | `search_entities` | Поиск с операторами `$gt`, `$gte`, `$lt`, `$lte`, `$ne`, `$contains`, `$in` | | `batch_entities` | Массовое создание, обновление и удаление до 500 записей за вызов | | `aggregate_entities` | Агрегация: `count`, `sum`, `avg`, `min`, `max` с группировкой через `groupBy` | Поддерживаемые сущности: `deals`, `contacts`, `companies`, `leads`, `quotes`, `activities`, `products`, `product-sections`, `statuses`, `currencies`, `deal-categories`, `requisites`, `timelines`, `invoices`, `items`, `smart-processes`, `tasks`, `calendar-events`, `files`, `folders`, `storages`, `users`, `departments`, `workgroups`, `chats`, `list-elements`, `catalog-products`, `catalog-sections`, `catalog-prices`, `orders`, `order-statuses`, `basket-items`, `payments`, `sites`, `pages`, `doc-templates`, `documents`, `bookings`, `bizproc-templates`, `openline-configs`, `telephony-lines` и другие. ##### Чаты (1) | Инструмент | Действия | |------------|----------| | `manage_chat` | `list_recent`, `find`, `get`, `send_message`, `read_messages`, `create`, `add_users`, `bulk_messages` | Скоуп: `im`. Управляет чатами и сообщениями на стороне пользователя; для чатов, принадлежащих боту, нужен `manage_bot_chat`. ##### Боты (3) Управление ботами на платформе Битрикс24 — регистрация, чаты, обмен сообщениями. Скоуп ключа: `imbot`. | Инструмент | Действия | |------------|----------| | `manage_bot` | `register`, `unregister`, `update`, `list`, `get`, `get_events` | | `manage_bot_chat` | `create`, `get`, `update`, `leave`, `add_user`, `remove_user`, `set_owner` | | `manage_bot_messages` | `send`, `edit`, `delete`, `add_reaction`, `remove_reaction`, `read`, `get_history`, `send_typing` | ##### CRM-расширения и работа с порталом (12) | Инструмент | Действия | |------------|----------| | `manage_workday` | `open`, `close`, `pause`, `status`, `settings`, `schedule` — учёт рабочего времени. Скоуп: `timeman` | | `manage_workflow` | `start`, `list`, `terminate`, `send_event` — бизнес-процессы. Скоуп: `bizproc` | | `send_notification` | Push-уведомление пользователю Битрикс24. Скоуп: `im` | | `manage_call` | `register`, `finish`, `auto_call`, `callback`, `statistics`, `voices` — телефония и автообзвон с TTS. Скоуп: `telephony` | | `manage_trigger` | `fire`, `list` — CRM-триггеры автоматизации. Скоуп: `bizproc` | | `manage_timeline_log` | `create`, `list`, `get`, `delete`, `add_note`, `get_note`, `delete_note`, `pin`, `unpin`, `bind`, `unbind`, `get_bindings` — записи в таймлайне CRM-сущностей. Скоуп: `crm` | | `manage_warehouse` | `list`, `get`, `create`, `delete`, `get_stock` — склады и остатки. Скоуп: `catalog` | | `manage_post` | `list`, `create`, `update`, `delete`, `share`, `add_comment` — посты в живой ленте. Скоуп: `log` | | `manage_userfield` | `list`, `get`, `types`, `create`, `update`, `delete` — пользовательские поля в фиксированных CRM-сущностях и смарт-процессах. Скоуп: `crm` | | `manage_task_time` | `list`, `get`, `add`, `update`, `delete` — учёт времени по задачам. Скоуп: `task` | | `crm_extras` | `stage_history`, `find_duplicates` — история стадий и поиск дубликатов. Скоуп: `crm` | | `manage_file` | `upload`, `download` — загрузка и скачивание файлов в Битрикс24.Диске. Скоуп: `disk` | ##### Универсальный вызов Vibe API (1) | Инструмент | Описание | |------------|----------| | `call_api` | Произвольный HTTP-вызов к Vibe API: `method`, `path`, `body`, `query`. Запасной канал для эндпоинтов без типизированной обёртки | Пример вызова: `call_api({ method: "GET", path: "/v1/calls/statistics" })`. #### AI (2) — ключ портала Подключение AI-моделей через AI Router и управление BYOK-учётными данными. Скоуп: `vibe:ai`. | Инструмент | Действия | |------------|----------| | `ai_chat` | `list_models`, `chat` — OpenAI-совместимые chat completions через `/v1/chat/completions`; модель по умолчанию — бесплатная `bitrix/bitrixgpt-5.5` | | `manage_ai_credentials` | `list`, `create`, `update`, `delete`, `test`, `usage`, `list_providers` — управление BYOK-учётными данными для подключения сторонних AI-провайдеров. Создание и обновление проверяют ключ перед сохранением и возвращают `422 CREDENTIAL_INVALID` при ошибке | #### Сборка приложений (14) — ключ портала Создание приложений Битрикс24, развёртывание серверной части на облачных VM, настройка плейсментов в интерфейсе портала. ##### Инфраструктура (3) Облачные серверы для приложений и Black Hole-туннели. Скоуп: `vibe:infra`. | Инструмент | Действия | |------------|----------| | `manage_server` | Каталог: `list_providers`, `list_plans`, `list_regions`, `list_images`. Жизненный цикл: `create`, `list`, `get`, `delete`, `get_ssh`. Состояние: `start`, `stop`, `reboot`, `wake`, `sleep_now`, `refresh`. Операции: `metrics`, `set_port`, `set_sleep`, `set_mode`, `repair`, `repair_status` | | `manage_server_deploy` | `deploy`, `exec`, `upload`, `logs`, `clear_lock` — конвейер развёртывания с шагами `stop → clean → download → runtime → install → env → pre_start → systemd → start → healthcheck` | | `manage_server_access` | `list_access`, `add_access`, `remove_access`, `b24_users_search` — списки доступа Black Hole с автодополнением пользователей Битрикс24 | ##### Приложения (5) | Инструмент | Описание | |------------|----------| | `list_apps` | Список приложений, опциональный фильтр по статусу | | `get_app` | Приложение по ID | | `create_app` | Создание приложения | | `update_app` | Обновление приложения | | `delete_app` | Удаление приложения | ##### Публикация и развёртывание приложений (5) | Инструмент | Описание | |------------|----------| | `publish_app` | Публикация приложения для всего портала | | `unpublish_app` | Возврат приложения в черновик | | `list_deployments` | Список развёртываний приложения | | `deploy_app` | Развёртывание приложения на портал или в каталог приложений | | `undeploy_app` | Удаление конкретного развёртывания | ##### Плейсменты (1) | Инструмент | Действия | |------------|----------| | `manage_placements` | `list_bound`, `list_available`, `bind`, `unbind` — встройка приложения в интерфейс Битрикс24. Для IM-плейсментов (`IM_SIDEBAR`, `IM_NAVIGATION`, `IM_TEXTAREA`) обязателен параметр `options.iconName` — проверяется на стороне клиента до отправки запроса | Скоуп: `placement`. Действие `list_bound` (под капотом — `GET /v1/placements`) возвращает список placement-кодов, привязанных в Вайбкоде, и — при наличии токена сессии (`Authorization: Bearer`) — дополнительное поле `handlers`. Это массив с фактическим URL-обработчиком из Битрикс24 для каждого код-а: `{ placement, handler, title?, options?, langAll? }`. Тип: `Array<{...}> | undefined` — поле отсутствует, если запрос пришёл без `Bearer`, у приложения нет привязанных плейсментов или ответ Битрикс24 не удалось получить (тогда базовый список `placements` всё равно вернётся — graceful-degrade). Поле `handlers` строится как пересечение нашего `App.placements` с ответом Битрикс24-метода `placement.get`. Коды, которые есть в нашей базе, но отсутствуют у Битрикс24, в `handlers` не попадают — это сигнал расхождения (drift), полезный для диагностики: пользователь видит привязку в Вайбкоде, но в портале её фактически нет (например, кто-то снял её через интерфейс Битрикс24). Базовый список `data.placements` при этом остаётся прежним — несовместимых изменений в форме ответа нет. Пример (наличие `handlers`): ```json { "success": true, "data": { "placements": ["CRM_DEAL_DETAIL_TAB", "LEFT_MENU"], "appId": "5b5c7e6f-…", "appTitle": "My App", "handlers": [ { "placement": "CRM_DEAL_DETAIL_TAB", "handler": "https://myapp.example.com/deal-tab", "title": "My tab", "options": {}, "langAll": { "ru": { "TITLE": "Моя вкладка" } } } ] } } ``` В примере выше `LEFT_MENU` есть в `placements`, но отсутствует в `handlers` — на портале он не привязан, нужна повторная регистрация через `bind`. Пример без `handlers` (вызов без `Bearer` или нет привязок): ```json { "success": true, "data": { "placements": [], "appId": "5b5c7e6f-…", "appTitle": "My App" } } ``` #### Платформенное управление (8) — управляющий ключ Эта группа доступна только управляющим ключам Вайбкод (формат `vibe_live_...`). | Инструмент | Описание | |------------|----------| | `list_portals` | Список порталов, доступных по управляющему ключу | | `list_keys` | Список API-ключей портала | | `get_key` | Ключ по ID | | `create_key` | Создание ключа со скоупами, IP-вайтлистом и сроком действия | | `update_key` | Изменение ключа | | `delete_key` | Удаление ключа | | `rotate_key` | Ротация секрета ключа | | `manage_feedback` | `create`, `list`, `get`, `update`, `comment` — обращения через `/v1/feedback`. Управляющий ключ работает со всеми порталами; для ключа портала это создание и чтение собственных тикетов, а с дополнительным скоупом `vibe:feedback` — также обновление и комментирование | #### Служебные (2) — любой ключ Доступны и ключу портала, и управляющему. | Инструмент | Описание | |------------|----------| | `get_me` | Снимок текущего ключа: владелец, портал, тариф, состояние пробного периода, capabilities. Параметр `sections` сужает ответ; `refresh: 'tariff'` принудительно перепроверяет тариф через Битрикс24 | | `check_for_updates` | Проверка наличия обновлений `mcp-vibe-api` в реестре npm. Возвращает текущую и последнюю версии, команду обновления | ### Resources URI вида `vibe://...` отдают справочные материалы для AI-агента. | URI | Описание | |-----|----------| | `vibe://api-reference` | Полный справочник Vibe API в формате Markdown | | `vibe://entity/{plural}` | Справочник по конкретной сущности — например `vibe://entity/deals`, `vibe://entity/tasks` | | `vibe://tariff-gate` | Карта 402-ошибок тарифного шлюза, пробного периода и баланса с подсказками `userMessage` / `alternatives` / `hint` | | `vibe://error-codes` | Каталог кодов ошибок Vibe API и форма их ответа | ### Prompts Готовые мульти-шаговые подсказки для AI-агента. Активируются клиентом по имени. | Имя | Описание | |-----|----------| | `create-bitrix24-app` | Сценарий создания, публикации и развёртывания приложения для Битрикс24 | | `deploy-app-step-by-step` | Развёртывание приложения на сервере: пробуждение, загрузка, выполнение команд, проверка работоспособности | | `diagnose-server-issue` | Диагностика проблем сервера: статус, метрики, журналы, варианты восстановления | | `upgrade-from-trial` | Объяснение блокировок тарифного шлюза и пути перехода на коммерческий тариф | ### HTTP-транспорт Помимо stdio (используется по умолчанию) `mcp-vibe-api` поддерживает HTTP-транспорт. Подходит для серверных интеграций, где stdio неудобен. ```bash mcp-vibe-api \ --key vibe_api_your_key_here \ --http \ --http-token "$(openssl rand -hex 32)" \ --allowed-origins https://your-client.example.com ``` Клиент отправляет `POST http://127.0.0.1:3001/mcp` с заголовками: ``` Authorization: Bearer Content-Type: application/json ``` | Код ответа | Причина | |------------|---------| | `401` | Отсутствует или некорректный Bearer-токен | | `403` | Не совпал заголовок `Host`, `Origin` не в списке разрешённых, либо `OPTIONS` без разрешённого `Origin` | | `404` | Путь отличается от `/mcp` | | `405` | Метод запроса отличается от `POST` или `OPTIONS` | | `413` | Тело запроса превышает `--max-body-kb` | | `415` | `Content-Type` отличается от `application/json` | | `429` | Превышен лимит запросов в минуту, ответ содержит `Retry-After: 60` | Сервер откажется стартовать, если `--http` указан без токена. Сами токены не пишутся в журналы — на старте указывается только их источник (флаг или переменная окружения). ## mcp-docs Справочник по REST API Битрикс24: методы, скоупы, плейсменты, типы и категории приложений. Работает офлайн без API-ключа — все данные встроены в пакет. ### Установка Пакет [`@bitrix24/mcp-docs`](https://www.npmjs.com/package/@bitrix24/mcp-docs). После установки доступна команда `mcp-docs`. API-ключ не нужен — справочник встроен в пакет и работает без сети. ```bash npm install -g @bitrix24/mcp-docs ``` ### Регистрация в клиенте Через CLI: ```bash claude mcp add bitrix24-docs -- mcp-docs codex mcp add bitrix24-docs -- mcp-docs gemini mcp add bitrix24-docs mcp-docs ``` Через конфиг-файл: ```json { "mcpServers": { "bitrix24-docs": { "command": "mcp-docs" } } } ``` ### Инструменты (8) | Инструмент | Описание | |------------|----------| | `search_docs` | Полнотекстовый поиск по справочнику | | `get_rest_methods` | Список REST-методов с фильтром по скоупу или поисковому запросу | | `get_method_detail` | Подробное описание метода: параметры, ответ, примеры | | `get_scopes` | Список скоупов с описаниями | | `get_placements` | Список UI-плейсментов с фильтром по модулю | | `get_placement_detail` | Подробное описание плейсмента | | `get_app_types` | Типы приложений Битрикс24 | | `get_categories` | Категории приложений Битрикс24 | Дополнительно сервер публикует ресурс с гайдом по REST API и промпт `bitrix24-rest-intro` — введение в REST и в синтаксис Вайбкод-прокси. ## Прямое использование Vibe API без MCP Если MCP-клиент недоступен, дайте AI-модели API-ключ и ссылку на полный справочник: ``` Вот мой API-ключ Вайбкод: vibe_api_your_key_here Полная документация: https://vibecode.bitrix24.tech/llms-full.txt Опишите вашу задачу... ``` `mcp-vibe-api` подключается к любому клиенту с поддержкой Model Context Protocol — Claude Desktop, Claude Code, Cursor, Codex CLI, Windsurf, Gemini CLI и другим. Прямой ключ без MCP подойдёт даже клиентам без поддержки протокола, например ChatGPT. ## Безопасность - Передавайте API-ключ через переменную окружения `VIBE_API_KEY` или флаг `--key` — не вписывайте ключ в скрипты, репозитории и публичные конфиги. - Создавайте отдельный ключ для каждого AI-агента и оставляйте только нужные скоупы — ключи `vibe_api_...` поддерживают список скоупов и срок действия. - Для серверных сценариев настраивайте IP-вайтлист и фиксированный срок жизни ключа. - В HTTP-транспорте используйте Bearer-токен из `--http-token` или `VIBE_MCP_HTTP_TOKEN` и оставляйте `--host 127.0.0.1`, если внешний доступ не нужен. - Если ключ скомпрометирован — отзовите его в [разделе ключей](https://vibecode.bitrix24.tech/keys) и создайте новый. ## Смотрите также - [Управление ключами](/docs/keys-auth) — типы ключей Вайбкод и их скоупы - [Эндпоинты Vibe API](/docs/entity-api) — единый CRUD над сущностями Битрикс24 - [AI Router](/docs/ai) — модели и BYOK-провайдеры - [Обратная связь](/docs/feedback) — отправка сообщений о проблемах через `/v1/feedback` --- # Таймлайн CRM 12 REST-эндпоинтов для журналирования действий в таймлайне CRM-сущностей: создание лог-записей, заметки к ним, закрепление, привязка к нескольким сущностям одновременно. Удобно для AI-агентов, фоновых интеграций и автоматизации, которым нужно оставлять структурированный след в карточке сделки или контакта. **Скоуп:** `crm` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` [Быстрый старт](#быстрый-старт) | [AI-агент логирует свои действия (полный пример)](#полный-пример-ai-агент-логирует-свои-действия) | [Коды ошибок](#коды-ошибок) | [Справочник эндпоинтов](#справочник-эндпоинтов) ## Разделы документации - [Записи журнала](/docs/timeline-logs/logs) — создание, просмотр, удаление лог-записей - [Заметки](/docs/timeline-logs/notes) — заметка-комментарий к лог-записи - [Закрепления](/docs/timeline-logs/pins) — закрепить или открепить запись в верхней части таймлайна - [Привязки](/docs/timeline-logs/bindings) — связать одну запись с несколькими сущностями CRM ## Когда использовать - Записать действие AI-агента: проанализировал клиента, подготовил коммерческое предложение, отправил уведомление. - Зафиксировать событие из внешней системы: оплата прошла, заказ собран, документ подписан. - Создать аудиторский след интеграции: какие данные обработала, на основании чего приняла решение. - Закрепить ключевое событие сделки в верхней части таймлайна, чтобы менеджер сразу видел контекст. Для текстовых комментариев пользователя (не системных событий) используйте [`/v1/timelines`](/docs/entities/timelines) — это отдельный API над `crm.timeline.comment.*`. ## Быстрый старт ### 1. Создайте запись в таймлайне сделки ```bash curl -X POST https://vibecode.bitrix24.tech/v1/timeline-logs \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityTypeId": 2, "entityId": 100, "title": "AI-агент обработал заявку", "text": "Проанализированы данные клиента. Рекомендация: предложить тариф Enterprise." }' ``` Ответ: ```json { "success": true, "data": { "id": 5012, "created": "2026-04-27T10:00:00+03:00", "authorId": 1, "title": "AI-агент обработал заявку", "text": "Проанализированы данные клиента. Рекомендация: предложить тариф Enterprise.", "iconCode": "" } } ``` ### 2. Закрепите запись в верхней части таймлайна ```bash curl -X POST https://vibecode.bitrix24.tech/v1/timeline-logs/5012/pin \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityTypeId": 2, "entityId": 100 }' ``` ### 3. Прикрепите внутреннюю заметку ```bash curl -X POST https://vibecode.bitrix24.tech/v1/timeline-logs/5012/note \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityTypeId": 2, "entityId": 100, "text": "Клиент обычно отвечает в течение 2 дней." }' ``` ## Полный пример: AI-агент логирует свои действия Сценарий: AI-агент анализирует сделку, оставляет лог-запись с результатом, привязывает её к контакту и компании, прикрепляет заметку для менеджера, закрепляет в таймлайне. ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body = null) { const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) return res.json() } const dealId = 100 const contactId = 50 const companyId = 10 // 1. Записать факт начала работы const start = await api('POST', '/timeline-logs', { entityTypeId: 2, entityId: dealId, title: 'AI-агент начал обработку', text: 'Анализ данных клиента, проверка кредитного лимита, подготовка предложения.', }) const startId = start.data.id // 2. Связать запись с контактом и компанией — менеджеры обоих увидят // то же событие в своих таймлайнах await api('POST', `/timeline-logs/${startId}/bind`, { entityTypeId: 3, entityId: contactId }) await api('POST', `/timeline-logs/${startId}/bind`, { entityTypeId: 4, entityId: companyId }) // ... AI-агент выполняет работу ... // 3. Записать результат отдельной лог-записью const result = await api('POST', '/timeline-logs', { entityTypeId: 2, entityId: dealId, title: 'AI-агент завершил обработку', text: [ '[b]Результаты анализа:[/b]', '- Кредитный лимит: OK (500 000 руб.)', '- Рекомендованный тариф: Enterprise', '- Скидка: 10% (постоянный клиент)', '- КП сформировано и отправлено на email', ].join('\n'), }) const resultId = result.data.id // 4. Закрепить итоговую запись в верхней части таймлайна await api('POST', `/timeline-logs/${resultId}/pin`, { entityTypeId: 2, entityId: dealId }) // 5. Оставить внутреннюю заметку для менеджера await api('POST', `/timeline-logs/${resultId}/note`, { entityTypeId: 2, entityId: dealId, text: 'Клиент обычно отвечает в течение 2 дней. Напомнить менеджеру, если нет ответа.', }) console.log('AI-агент завершил работу, все действия залогированы') ``` ## Какой ключ использовать CRUD-операции работают с любым типом ключа — личным (`vibe_api_*`) или OAuth-приложением (`vibe_app_*`). Однако **`DELETE /v1/timeline-logs/:id` накладывает ограничение**: Битрикс24 разрешает удалить лог-запись только тому же приложению, которое её создало. - **OAuth-приложение** (`vibe_app_*` + `Authorization: Bearer ...`) — стабильное `client_id`, удалить свои записи можно. Если планируете удалять созданные записи через API, используйте этот тип ключа. - **Личный ключ** (`vibe_api_*`) — Вайбкод ротирует токены между вызовами, для Битрикс24 каждый вызов выглядит как отдельное приложение. `DELETE` всегда возвращает `403 CROSS_APP_DELETE_FORBIDDEN`, в том числе на свежесозданные записи. Если приложение, создавшее запись, недоступно — удалить её нельзя в принципе. Битрикс24 не предоставляет UI-кнопку удаления log-записи в карточке сущности. Учитывайте это при проектировании сценариев аудита. Подробнее — [Удалить запись](/docs/timeline-logs/logs/delete). ## Типы родительских сущностей Параметр `entityTypeId` (числовой код CRM-сущности) указывает, в чьём таймлайне создаётся запись: | `entityTypeId` | Сущность | Где найти ID | |:---:|----------|--------------| | 1 | Лид | [`GET /v1/leads`](/docs/entities/leads/list) | | 2 | Сделка | [`GET /v1/deals`](/docs/entities/deals/list) | | 3 | Контакт | [`GET /v1/contacts`](/docs/entities/contacts) | | 4 | Компания | [`GET /v1/companies`](/docs/entities/companies) | | 7 | Предложение | [`GET /v1/quotes`](/docs/entities/quotes) | | 14 | Заказ | [`GET /v1/orders`](/docs/entities/orders) | | 31 | Счёт | [`GET /v1/invoices`](/docs/entities/invoices) | | ≥ 128 | Смарт-процесс | [`GET /v1/items/:entityTypeId`](/docs/entities/items/list); список процессов — [`GET /v1/smart-processes`](/docs/entities/smart-processes/list) | В привязках (`bind`/`unbind`) можно использовать как числовой `entityTypeId`, так и строковый `entityType` напрямую (`"deal"`, `"contact"`, `"dynamic_174"` и т. п.) — см. [Привязать запись](/docs/timeline-logs/bindings/bind). ## Коды ошибок ### Ошибки таймлайна | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Не переданы или некорректны обязательные параметры (`entityTypeId`, `entityId`, `title`, `text`, `itemType` и т. д. — конкретное поле в `message`) | | 400 | `INVALID_ENTITY_TYPE_ID` | В `bindings.bind`/`unbind` передан `entityTypeId` без отображения на `ENTITY_TYPE` (`< 128` и не из таблицы выше) | | 403 | `CROSS_APP_DELETE_FORBIDDEN` | Попытка удалить лог-запись через ключ, отличный от того, которым она создана | | 404 | `ENTITY_NOT_FOUND` | Лог-запись с указанным `id` не существует — Битрикс24 вернул ошибку `NOT_FOUND` | | 404 | `NOT_FOUND` | Только `GET /v1/timeline-logs/:id`: Битрикс24 вернул успешный ответ, но объект записи пуст | | 404 | `NOTE_NOT_FOUND` | У указанного элемента таймлайна нет привязанной заметки | ### Системные ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `AUTH_REQUIRED` | Отсутствует `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов (для `vibe_app_*` нужен `Authorization: Bearer ...`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов. Подождите 1–2 секунды и повторите. Несколько вызовов можно объединить в [`POST /v1/batch`](/docs/batch) | | 502 | `ERROR_LOOP_DETECTED` | Срабатывает circuit breaker: подряд много одинаковых ошибок от B24. Подождите ~60 секунд | | 502 | `BITRIX_UNAVAILABLE` | Портал Битрикс24 недоступен | | 504 | `QUEUE_TIMEOUT` | Запрос к B24 не успел выполниться в очереди портала. Сузьте фильтр или повторите позже | | 500 | `INTERNAL_ERROR` | Внутренняя ошибка сервера | Полный список общих кодов API — [Ошибки](/docs/errors). ## Справочник эндпоинтов Все 12 эндпоинтов: | Метод | Путь | Bitrix24 метод | Описание | |-------|------|---------------|---------| | POST | [/v1/timeline-logs](/docs/timeline-logs/logs/create) | `crm.timeline.logmessage.add` | Создать лог-запись | | GET | [/v1/timeline-logs](/docs/timeline-logs/logs/list) | `crm.timeline.logmessage.list` | Список лог-записей | | GET | [/v1/timeline-logs/:id](/docs/timeline-logs/logs/get) | `crm.timeline.logmessage.get` | Получить одну запись | | DELETE | [/v1/timeline-logs/:id](/docs/timeline-logs/logs/delete) | `crm.timeline.logmessage.delete` | Удалить запись | | POST | [/v1/timeline-logs/:id/note](/docs/timeline-logs/notes/save) | `crm.timeline.note.save` | Сохранить или обновить заметку | | GET | [/v1/timeline-logs/:id/note](/docs/timeline-logs/notes/get) | `crm.timeline.note.get` | Получить заметку | | DELETE | [/v1/timeline-logs/:id/note](/docs/timeline-logs/notes/delete) | `crm.timeline.note.delete` | Удалить заметку | | POST | [/v1/timeline-logs/:id/pin](/docs/timeline-logs/pins/pin) | `crm.timeline.item.pin` | Закрепить запись | | POST | [/v1/timeline-logs/:id/unpin](/docs/timeline-logs/pins/unpin) | `crm.timeline.item.unpin` | Открепить запись | | POST | [/v1/timeline-logs/:id/bind](/docs/timeline-logs/bindings/bind) | `crm.timeline.bindings.bind` | Привязать к ещё одной сущности | | POST | [/v1/timeline-logs/:id/unbind](/docs/timeline-logs/bindings/unbind) | `crm.timeline.bindings.unbind` | Отвязать от сущности | | GET | [/v1/timeline-logs/:id/bindings](/docs/timeline-logs/bindings/list) | `crm.timeline.bindings.list` | Список всех привязок записи | ## Смотрите также - [Комментарии таймлайна](/docs/entities/timelines) — текстовые комментарии пользователя (отдельный API на `crm.timeline.comment.*`) - [Сделки](/docs/entities/deals), [Лиды](/docs/entities/leads), [Контакты](/docs/entities/contacts), [Компании](/docs/entities/companies) — типичные родительские сущности - [Смарт-процессы](/docs/entities/smart-processes) — для записей в таймлайне пользовательских CRM-типов - [Batch](/docs/batch) — массовые операции - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Пользовательские поля Управление пользовательскими полями CRM-сущностей и смарт-процессов Битрикс24: создание, обновление, удаление текстовых полей, списков, дат, чисел, привязок к сотрудникам и сущностям CRM. Изменения применяются к полям сущности на всём портале — учитывайте это при работе на боевых данных. **Скоуп:** `crm`, `userfieldconfig` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` [Быстрый старт](#быстрый-старт) | [Полный пример](#полный-пример) | [Справочник эндпоинтов](#справочник-эндпоинтов) | [Коды ошибок](#коды-ошибок) ## Разделы документации - [Поля CRM-сущностей](/docs/userfields/crm) — управление полями сделок, лидов, контактов, компаний, предложений и реквизитов - [Поля смарт-процессов](/docs/userfields/smart-processes) — управление полями элементов смарт-процессов по `entityTypeId` --- ## Быстрый старт ### 1. Посмотрите существующие поля сделки ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ "https://vibecode.bitrix24.tech/v1/userfields/deals" ``` Ответ: ```json { "success": true, "data": [ { "id": 7115, "entityId": "CRM_DEAL", "fieldName": "UF_CRM_PROJECT_CODE", "userTypeId": "string", "mandatory": "N", "sort": "100", "editFormLabel": { "ru": "Код проекта" } } ], "meta": { "total": 44 } } ``` ### 2. Создайте новое поле ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/userfields/deals" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userTypeId": "string", "fieldName": "PROJECT_CODE", "label": "Код проекта" }' ``` При успешном создании возвращается HTTP `201 Created` с числовым `id` нового поля. --- ## Полный пример Сценарий: добавить поле-список «Источник лида», получить его полное описание, сделать видимым в фильтре, удалить. ```javascript const KEY = process.env.VIBECODE_API_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body) { const opts = { method, headers: { 'X-Api-Key': KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) return res.status === 204 ? null : res.json() } // 1. Узнать, сколько пользовательских полей уже создано const before = await api('GET', '/userfields/deals') console.log(`Полей до создания: ${before.meta.total}`) // 2. Создать поле-список «Источник лида» const created = await api('POST', '/userfields/deals', { userTypeId: 'enumeration', fieldName: 'LEAD_SOURCE', label: 'Источник лида', mandatory: 'Y', list: [ { VALUE: 'Сайт', SORT: 10 }, { VALUE: 'Соцсети', SORT: 20 }, { VALUE: 'Реклама', SORT: 30 } ] }) const newId = created.data.id console.log('Создано поле с id:', newId) // 3. Получить полное описание созданного поля const detail = await api('GET', `/userfields/deals/${newId}`) console.log('Варианты списка:', detail.data.list.map(v => v.VALUE).join(', ')) // 4. Сделать поле видимым в фильтре карточки await api('PATCH', `/userfields/deals/${newId}`, { showFilter: 'Y' }) // 5. Удалить поле — ответ HTTP 204 с пустым телом await api('DELETE', `/userfields/deals/${newId}`) console.log('Поле удалено') ``` --- ## Справочник эндпоинтов ### Поля CRM-сущностей | Метод | Путь | Bitrix24 метод | Описание | |-------|------|----------------|---------| | GET | [/v1/userfields/:entity](/docs/userfields/crm/list) | crm.:entity.userfield.list | Список полей сущности | | GET | [/v1/userfields/:entity/types](/docs/userfields/crm/types) | crm.userfield.types | Каталог типов полей | | GET | [/v1/userfields/:entity/:id](/docs/userfields/crm/get) | crm.:entity.userfield.get | Одно поле по идентификатору | | POST | [/v1/userfields/:entity](/docs/userfields/crm/create) | crm.:entity.userfield.add | Создать поле | | PATCH | [/v1/userfields/:entity/:id](/docs/userfields/crm/update) | crm.:entity.userfield.update | Обновить поле | | DELETE | [/v1/userfields/:entity/:id](/docs/userfields/crm/delete) | crm.:entity.userfield.delete | Удалить поле | `:entity` — одно из значений: `deals`, `leads`, `contacts`, `companies`, `quotes`, `requisites`. ### Поля смарт-процессов | Метод | Путь | Bitrix24 метод | Описание | |-------|------|----------------|---------| | GET | [/v1/items/:entityTypeId/userfields](/docs/userfields/smart-processes/list) | userfieldconfig.list | Список полей смарт-процесса | | GET | [/v1/items/:entityTypeId/userfields/types](/docs/userfields/smart-processes/types) | crm.userfield.types | Каталог типов полей | | GET | [/v1/items/:entityTypeId/userfields/:id](/docs/userfields/smart-processes/get) | userfieldconfig.get | Одно поле по идентификатору | | POST | [/v1/items/:entityTypeId/userfields](/docs/userfields/smart-processes/create) | userfieldconfig.add | Создать поле | | PATCH | [/v1/items/:entityTypeId/userfields/:id](/docs/userfields/smart-processes/update) | userfieldconfig.update | Обновить поле | | DELETE | [/v1/items/:entityTypeId/userfields/:id](/docs/userfields/smart-processes/delete) | userfieldconfig.delete | Удалить поле | `entityTypeId` — идентификатор типа смарт-процесса из ответа [`GET /v1/smart-processes`](/docs/entities/smart-processes). --- ## Коды ошибок ### Ошибки пользовательских полей | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_ENTITY` | Сущность не из списка поддерживаемых (`deals`, `leads`, `contacts`, `companies`, `quotes`, `requisites`) | | 400 | `INVALID_ENTITY_TYPE_ID` | `entityTypeId` смарт-процесса не является положительным целым числом | | 400 | `MISSING_FIELD` | Не передан обязательный параметр `userTypeId` при создании | | 400 | `INVALID_REQUEST` | Тело запроса не является объектом | | 403 | `BITRIX_ACCESS_DENIED` | OAuth-приложению Битрикс24 не хватает прав на `userfieldconfig.*` для смарт-процессов | | 404 | `ENTITY_NOT_FOUND` | Поле с указанным `id` не существует | | 404 | `SMART_PROCESS_NOT_FOUND` | Смарт-процесс с указанным `entityTypeId` не найден на портале | | 422 | `BITRIX_ERROR` | Битрикс24 отклонил запрос — некорректное значение, недопустимое имя поля, неизвестный `userTypeId` | ### Системные ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Отсутствует заголовок `X-Api-Key` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 502 | `BITRIX_UNAVAILABLE` | Портал Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). --- ## Смотрите также - [Поля CRM-сущностей](/docs/userfields/crm) - [Поля смарт-процессов](/docs/userfields/smart-processes) - [Смарт-процессы](/docs/entities/smart-processes) - [Сделки](/docs/entities/deals) - [Реквизиты](/docs/entities/requisites) - [Ошибки](/docs/errors) --- # Каталог и склад Управляйте каталогом товаров, ценами и складскими остатками через Entity API. Разделы каталога, ценовые предложения, склады — всё через стандартные CRUD-операции. ## Обзор Catalog API расширяет базовые entity-обёртки для торгового каталога Битрикс24: - **Разделы каталога** (`/v1/catalog-sections/*`) — категории и подкатегории товаров - **Цены** (`/v1/catalog-prices/*`) — ценовые предложения (прайс-листы) - **Склады** (`/v1/warehouses/*`) — управление складами и остатками **Требуемые скоупы:** `catalog`, `crm` **Базовый URL:** `https://vibecode.bitrix24.tech/v1` **Авторизация:** заголовок `X-Api-Key` с вашим API-ключом. ## Быстрый старт ### Создайте раздел каталога ```bash curl -X POST https://vibecode.bitrix24.tech/v1/catalog-sections \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "iblockId": 14, "name": "Электроника", "iblockSectionId": null } }' ``` Ответ: ```json { "success": true, "data": { "section": { "id": 42 } } } ``` ## Разделы каталога Entity: `catalog-sections` — разделы (категории) торгового каталога. ### POST /v1/catalog-sections Создаёт новый раздел каталога. **Параметры тела запроса (в `fields`):** | Параметр | Тип | Обязательный | Описание | |----------|-----|:---:|---------| | `iblockId` | number | да | ID инфоблока каталога | | `name` | string | да | Название раздела | | `iblockSectionId` | number | нет | ID родительского раздела (`null` — корневой) | | `xmlId` | string | нет | Внешний ID для синхронизации | | `description` | string | нет | Описание раздела | | `sort` | number | нет | Порядок сортировки | **JavaScript:** ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-sections', { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ fields: { iblockId: 14, name: 'Смартфоны', iblockSectionId: 42, // дочерний раздел "Электроники" sort: 100 } }) }) const { data } = await res.json() console.log('Section ID:', data.section.id) ``` ### GET /v1/catalog-sections Возвращает список разделов каталога с фильтрацией. ```bash curl -H "X-Api-Key: $VIBE_KEY" \ "https://vibecode.bitrix24.tech/v1/catalog-sections?filter[iblockId]=14" ``` ### GET /v1/catalog-sections/:id Получает раздел по ID. ```bash curl -H "X-Api-Key: $VIBE_KEY" \ https://vibecode.bitrix24.tech/v1/catalog-sections/42 ``` ### PATCH /v1/catalog-sections/:id Обновляет раздел каталога. ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/catalog-sections/42 \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "name": "Электроника и гаджеты", "sort": 50 } }' ``` ### DELETE /v1/catalog-sections/:id Удаляет раздел каталога. ```bash curl -X DELETE -H "X-Api-Key: $VIBE_KEY" \ https://vibecode.bitrix24.tech/v1/catalog-sections/42 ``` ## Цены Entity: `catalog-prices` — ценовые предложения для товаров. ### POST /v1/catalog-prices Создаёт новое ценовое предложение для товара. **Параметры тела запроса (в `fields`):** | Параметр | Тип | Обязательный | Описание | |----------|-----|:---:|---------| | `catalogGroupId` | number | да | ID типа цены | | `productId` | number | да | ID товара | | `price` | number | да | Цена | | `currency` | string | да | Валюта (`RUB`, `USD`, `EUR`) | | `quantityFrom` | number | нет | Количество «от» для оптовой цены | | `quantityTo` | number | нет | Количество «до» | ```bash curl -X POST https://vibecode.bitrix24.tech/v1/catalog-prices \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "catalogGroupId": 1, "productId": 200, "price": 49990, "currency": "RUB" } }' ``` **JavaScript — оптовые цены:** ```javascript // Розничная цена await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices', { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ fields: { catalogGroupId: 1, // розничная productId: 200, price: 49990, currency: 'RUB' } }) }) // Оптовая цена (от 10 штук) await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices', { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ fields: { catalogGroupId: 2, // оптовая productId: 200, price: 39990, currency: 'RUB', quantityFrom: 10 } }) }) ``` ### GET /v1/catalog-prices Список цен с фильтрацией по товару. ```bash curl -H "X-Api-Key: $VIBE_KEY" \ "https://vibecode.bitrix24.tech/v1/catalog-prices?filter[productId]=200" ``` ### GET /v1/catalog-prices/:id Получает цену по ID. ```bash curl -H "X-Api-Key: $VIBE_KEY" \ https://vibecode.bitrix24.tech/v1/catalog-prices/15 ``` ### PATCH /v1/catalog-prices/:id Обновляет цену. ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/catalog-prices/15 \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "price": 44990 } }' ``` ### DELETE /v1/catalog-prices/:id Удаляет ценовое предложение. ```bash curl -X DELETE -H "X-Api-Key: $VIBE_KEY" \ https://vibecode.bitrix24.tech/v1/catalog-prices/15 ``` ## Склады Склады и складские остатки вынесены в отдельный раздел — **[Склады](/docs/entities/warehouses)** — с отдельной страницей на каждую операцию и проверенными примерами. ## Полный пример: Синхронизация каталога из 1С ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body = null) { const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) return res.json() } // Данные из 1С const categories = [ { name: 'Электроника', xmlId: '1c_cat_001', children: [ { name: 'Смартфоны', xmlId: '1c_cat_002' }, { name: 'Ноутбуки', xmlId: '1c_cat_003' } ]}, { name: 'Аксессуары', xmlId: '1c_cat_010' } ] const IBLOCK_ID = 14 // 1. Создаём корневые разделы for (const cat of categories) { const { data } = await api('POST', '/catalog-sections', { fields: { iblockId: IBLOCK_ID, name: cat.name, xmlId: cat.xmlId } }) const parentId = data.section.id console.log(`Раздел "${cat.name}" создан, ID: ${parentId}`) // 2. Создаём дочерние разделы if (cat.children) { for (const child of cat.children) { const { data: childData } = await api('POST', '/catalog-sections', { fields: { iblockId: IBLOCK_ID, name: child.name, xmlId: child.xmlId, iblockSectionId: parentId } }) console.log(` Подраздел "${child.name}" создан, ID: ${childData.section.id}`) } } } // 3. Устанавливаем цены на товары const products = [ { id: 200, retail: 49990, wholesale: 39990 }, { id: 201, retail: 79990, wholesale: 64990 } ] for (const product of products) { // Розничная цена await api('POST', '/catalog-prices', { fields: { catalogGroupId: 1, productId: product.id, price: product.retail, currency: 'RUB' } }) // Оптовая цена await api('POST', '/catalog-prices', { fields: { catalogGroupId: 2, productId: product.id, price: product.wholesale, currency: 'RUB', quantityFrom: 10 } }) console.log(`Цены для товара ${product.id}: розн. ${product.retail}, опт. ${product.wholesale}`) } console.log('Синхронизация завершена') ``` ## Справочник эндпоинтов | Метод | Путь | Bitrix24 метод | Описание | |-------|------|---------------|---------| | POST | /v1/catalog-sections | catalog.section.add | Создать раздел | | GET | /v1/catalog-sections | catalog.section.list | Список разделов | | GET | /v1/catalog-sections/:id | catalog.section.get | Получить раздел | | PATCH | /v1/catalog-sections/:id | catalog.section.update | Обновить раздел | | DELETE | /v1/catalog-sections/:id | catalog.section.delete | Удалить раздел | | POST | /v1/catalog-prices | catalog.price.add | Создать цену | | GET | /v1/catalog-prices | catalog.price.list | Список цен | | GET | /v1/catalog-prices/:id | catalog.price.get | Получить цену | | PATCH | /v1/catalog-prices/:id | catalog.price.update | Обновить цену | | DELETE | /v1/catalog-prices/:id | catalog.price.delete | Удалить цену | ## Коды ошибок | Код | HTTP | Описание | |-----|------|---------| | `SCOPE_DENIED` | 403 | API-ключ не имеет скоупа `catalog` | | `TOKEN_MISSING` | 401 | Ключ не имеет настроенных токенов | | `SECTION_NOT_FOUND` | 404 | Раздел каталога не найден | | `PRODUCT_NOT_FOUND` | 404 | Товар не найден | | `BITRIX_UNAVAILABLE` | 502 | Битрикс24 недоступен | | `BITRIX_ERROR` | 422 | Ошибка Bitrix24 REST API | --- # Лента новостей Публикация постов в Ленте новостей Битрикс24 через API: посты с адресацией отделам и сотрудникам, открытие доступа дополнительным получателям и комментарии. **Скоуп:** `log` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` [Быстрый старт](#быстрый-старт) | [Полный пример](#полный-пример) | [Справочник эндпоинтов](#справочник-эндпоинтов) | [Коды ошибок](#коды-ошибок) ## Разделы документации - [Посты](/docs/feed/posts) — создание, список, обновление, удаление постов и добавление получателей - [Комментарии](/docs/feed/comments) — добавление и удаление комментариев к постам ## Быстрый старт ### 1. Опубликуйте пост ```bash curl -X POST https://vibecode.bitrix24.tech/v1/posts \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Обновление платформы", "text": "[b]Вышла новая версия[/b] — поддержка пакетных запросов.", "recipients": ["UA"] }' ``` Ответ — идентификатор созданного поста и получатели, которым он открыт: ```json { "success": true, "data": { "id": 512, "recipients": ["UA"] } } ``` ### 2. Прокомментируйте пост ```bash curl -X POST https://vibecode.bitrix24.tech/v1/posts/512/comments \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Отличная новость!" }' ``` Ответ — идентификатор комментария: ```json { "success": true, "data": 1024 } ``` ### 3. Откройте пост дополнительным получателям ```bash curl -X POST https://vibecode.bitrix24.tech/v1/posts/512/share \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "recipients": ["DR3", "U5"] }' ``` ```json { "success": true, "data": true } ``` ## Полный пример Автоматический отчёт в ленту: публикация поста, комментарий от интеграции и открытие доступа руководству. Сценарий использует только скоуп `log`. ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body = null) { const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) return res.status === 204 ? null : res.json() } // 1. Публикуем ежедневный отчёт, адресуя отделу с подотделами const created = await api('POST', '/posts', { title: 'Ежедневный отчёт', text: [ '[b]Итоги дня[/b]', '', 'Закрытых задач: 48', 'Новых обращений: 12' ].join('\n'), recipients: ['DR1'] }) const postId = created.data.id console.log('Пост опубликован, ID:', postId) // 2. Добавляем комментарий от интеграции const comment = await api('POST', `/posts/${postId}/comments`, { text: 'Отчёт сформирован автоматически интеграцией Вайбкод.' }) console.log('Комментарий добавлен, ID:', comment.data) // 3. Открываем отчёт руководству await api('POST', `/posts/${postId}/share`, { recipients: ['U1'] }) // 4. Проверяем, что пост в ленте const list = await api('GET', '/posts?limit=5') console.log('Всего постов:', list.meta.total) ``` ## Справочник эндпоинтов | Метод | Путь | Bitrix24 метод | Описание | |-------|------|---------------|---------| | POST | [/v1/posts](/docs/feed/posts/create) | log.blogpost.add | Создать пост | | GET | [/v1/posts](/docs/feed/posts/list) | log.blogpost.get | Список постов | | PATCH | [/v1/posts/:id](/docs/feed/posts/update) | log.blogpost.update | Обновить пост | | DELETE | [/v1/posts/:id](/docs/feed/posts/delete) | log.blogpost.delete | Удалить пост | | POST | [/v1/posts/:id/share](/docs/feed/posts/share) | log.blogpost.share | Добавить получателей | | POST | [/v1/posts/:id/comments](/docs/feed/comments/add) | log.blogcomment.add | Добавить комментарий | | DELETE | [/v1/posts/:id/comments/:commentId](/docs/feed/comments/delete) | log.blogcomment.delete | Удалить комментарий | ## Коды ошибок ### Ошибки ленты | Код | HTTP | Описание | |-----|------|---------| | `SCOPE_DENIED` | 403 | У API-ключа нет скоупа `log` | | `TOKEN_MISSING` | 401 | У API-ключа не настроены токены доступа | | `MISSING_PARAMS` | 400 | Не переданы обязательные параметры (`text` для поста или комментария, `recipients` для добавления получателей) | | `INVALID_LIMIT` | 400 | `limit` вне диапазона 1..50 | | `INVALID_OFFSET` | 400 | `offset` отрицательный | | `INVALID_POST_ID` | 400 | `id` поста не является положительным целым | | `POST_NOT_FOUND` | 404 | Пост не найден или недоступен с этим ключом | | `POST_NOT_FOUND_OR_INVALID_RECIPIENTS` | 404 | Добавление получателей отклонено: пост не существует или среди получателей есть неверный | | `INVALID_RECIPIENTS` | 400 | Неверный формат получателей | | `BITRIX_ACCESS_DENIED` | 403 | Недостаточно прав на пост | | `COMMENT_NOT_FOUND` | 404 | Комментарий не найден | | `INVALID_COMMENT_ID` | 400 | `commentId` неверный | | `COMMENT_ACCESS_DENIED` | 403 | Недостаточно прав на комментарий | | `DUPLICATE_COMMENT` | 409 | Повторный комментарий с тем же содержимым | ### Системные ошибки | Код | HTTP | Описание | |-----|------|---------| | `MISSING_API_KEY` | 401 | Отсутствует заголовок `X-Api-Key` | | `INVALID_API_KEY` | 401 | Неверный API-ключ | | `RATE_LIMITED` | 429 | Превышен лимит запросов | | `BITRIX_ERROR` | 422 | Битрикс24 вернул ошибку | | `BITRIX_UNAVAILABLE` | 502 | Портал Битрикс24 недоступен | | `INTERNAL_ERROR` | 500 | Внутренняя ошибка сервера | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Посты](/docs/feed/posts) - [Комментарии](/docs/feed/comments) - [Ключи и авторизация](/docs/keys-auth) - [Ошибки](/docs/errors) --- # Чаты и сообщения Работайте с мессенджером Битрикс24 от имени авторизованного пользователя: находите чаты CRM-сущностей, читайте и отправляйте сообщения, управляйте участниками, загружайте файлы и получайте события через опрос. **Скоуп:** `im` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` [Быстрый старт](#быстрый-старт) | [Полный пример](#полный-пример) | [Справочник эндпоинтов](#справочник-эндпоинтов) | [Коды ошибок](#коды-ошибок) ## Разделы документации - [Поиск чатов](/docs/chats/discovery) — список последних диалогов, поиск чата CRM-сущности, текстовый поиск, информация о диалоге - [Сообщения](/docs/chats/messages) — чтение, отправка, редактирование, удаление, отметка прочитанными, массовая загрузка - [Управление чатами](/docs/chats/management) — создание групповых чатов, переименование, передача владения, выход - [Участники](/docs/chats/members) — список участников, добавление, удаление - [Файлы](/docs/chats/files) — загрузка файлов в чат, метаданные файла, папка чата на Диске - [События](/docs/chats/events) — подписка, опрос событий мессенджера, отписка ## Оформление сообщений Справочники по оформлению текста при отправке и редактировании сообщений: - [Форматирование текста (BB-коды)](/docs/chats/messages/formatting) - [Клавиатура](/docs/chats/messages/keyboard) - [Вложения](/docs/chats/messages/attach) ## Идентификаторы чатов В запросах встречаются два вида идентификаторов: - `dialogId` — идентификатор диалога: число (ID пользователя) для личной переписки, строка вида `chatN` (например `chat123`) для групповых чатов. - `chatId` — числовой ID чата без префикса `chat`. Нужен для управления чатом, участниками и файлами. Вместо своего идентификатора можно передать литерал `me` — он заменяется на ID текущего пользователя, которому принадлежит ключ. Так можно отправить сообщение самому себе, не запрашивая свой ID отдельным вызовом. Литерал пишется строчными буквами и работает везде, где принимается `dialogId`: информация о диалоге, чтение и отправка сообщений, список участников. Пример — отправить себе уведомление: ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/chats/me/messages" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"message": "Квартальный отчёт готов"}' ``` ## Быстрый старт Найдите чат CRM-сделки, прочитайте сообщения и отправьте ответ. ### 1. Найдите чат сделки ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ "https://vibecode.bitrix24.tech/v1/chats/find?entityType=CRM&entityId=DEAL|123" ``` Ответ: ```json { "success": true, "data": { "id": 2741 } } ``` `data.id` — числовой `chatId`. Для построения `dialogId` при обращении к эндпоинтам сообщений добавьте префикс `chat`: `chat2741`. ### 2. Прочитайте сообщения ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ "https://vibecode.bitrix24.tech/v1/chats/chat2741/messages?limit=5" ``` Ответ: ```json { "success": true, "data": { "chatId": 253, "messages": [ { "id": 9357, "chatId": 253, "authorId": 1, "date": "2026-04-26T18:10:54+03:00", "text": "Коллеги, КП утверждено. Можно выставлять счёт.", "unread": false } ], "users": [ { "id": 1, "name": "Иван Петров", "firstName": "Иван", "lastName": "Петров" } ], "files": [] } } ``` ### 3. Отправьте ответ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/chats/chat2741/messages" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"message": "Счёт выставлен. Номер: СЧ-2026-0458"}' ``` Ответ: ```json { "success": true, "data": 36889 } ``` `data` — ID отправленного сообщения. ## Полный пример Непрерывный сценарий: создать групповой чат, отправить приветствие, отметить переписку прочитанной, переименовать чат и выйти из него. ```javascript const VIBE_KEY = process.env.VIBE_KEY const BASE = 'https://vibecode.bitrix24.tech/v1' async function api(method, path, body = null) { const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } } if (body) { opts.headers['Content-Type'] = 'application/json' opts.body = JSON.stringify(body) } const res = await fetch(`${BASE}${path}`, opts) return res.json() } // 1. Создаём групповой чат const created = await api('POST', '/chats', { title: 'Рабочая группа', users: [1, 5, 12], }) const chatId = created.data // числовой chatId const dialogId = `chat${chatId}` // dialogId для эндпоинтов сообщений console.log('Чат создан, ID:', chatId) // 2. Отправляем приветствие const sent = await api('POST', `/chats/${dialogId}/messages`, { message: 'Добро пожаловать в рабочую группу!', }) console.log('Сообщение отправлено, ID:', sent.data) // 3. Отмечаем переписку прочитанной const read = await api('POST', `/chats/${dialogId}/read`, {}) console.log('Непрочитанных осталось:', read.data.counter) // 4. Переименовываем чат — управление идёт по числовому chatId, без префикса chat await api('PATCH', `/chats/${chatId}`, { title: 'Проект: Поставка оборудования', }) // 5. Выходим из чата await api('POST', `/chats/${chatId}/leave`, {}) console.log('Готово') ``` > Если вы владелец чата, сначала передайте владение через `POST /v1/chats/:chatId/owner`, затем покидайте чат — иначе выход зафиксируется, но владельцем останетесь вы. ## Справочник эндпоинтов Все 23 эндпоинта раздела: | Метод | Путь | Bitrix24 метод | Описание | |-------|------|---------------|---------| | GET | [/v1/chats/recent](/docs/chats/discovery/recent) | im.recent.list | Последние диалоги | | GET | [/v1/chats/find](/docs/chats/discovery/find) | im.chat.get | Найти чат CRM-сущности | | GET | [/v1/chats/search](/docs/chats/discovery/search) | im.search.chat.list | Поиск чатов по тексту | | GET | [/v1/chats/:dialogId](/docs/chats/discovery/get) | im.dialog.get | Информация о диалоге | | GET | [/v1/chats/:dialogId/messages](/docs/chats/messages/list) | im.dialog.messages.get | Чтение сообщений | | POST | [/v1/chats/:dialogId/messages](/docs/chats/messages/send) | im.message.add | Отправка сообщения | | PATCH | [/v1/chats/:dialogId/messages/:messageId](/docs/chats/messages/update) | im.message.update | Редактирование сообщения | | DELETE | [/v1/chats/:dialogId/messages/:messageId](/docs/chats/messages/delete) | im.message.delete | Удаление сообщения | | POST | [/v1/chats/:dialogId/read](/docs/chats/messages/read) | im.dialog.read | Отметить прочитанным | | POST | [/v1/chats/messages/bulk](/docs/chats/messages/bulk) | batch (im.dialog.messages.get) | Массовая загрузка из нескольких диалогов | | POST | [/v1/chats](/docs/chats/management/create) | im.chat.add | Создать групповой чат | | PATCH | [/v1/chats/:chatId](/docs/chats/management/rename) | im.chat.updateTitle | Переименовать чат | | POST | [/v1/chats/:chatId/owner](/docs/chats/management/owner) | im.chat.setOwner | Передать владение | | POST | [/v1/chats/:chatId/leave](/docs/chats/management/leave) | im.chat.leave | Покинуть чат | | GET | [/v1/chats/:dialogId/users](/docs/chats/members/list) | im.dialog.users.list | Список участников | | POST | [/v1/chats/:chatId/users](/docs/chats/members/add) | im.chat.user.add | Добавить участников | | DELETE | [/v1/chats/:chatId/users](/docs/chats/members/remove) | im.chat.user.delete | Удалить участника | | POST | [/v1/chats/:chatId/files](/docs/chats/files/upload) | im.disk.folder.get + disk.folder.uploadfile + im.disk.file.commit | Загрузить файл в чат | | GET | [/v1/chats/files/:fileId](/docs/chats/files/file-get) | disk.file.get | Метаданные файла | | GET | [/v1/chats/:chatId/folder](/docs/chats/files/folder) | im.disk.folder.get | Папка чата на Диске | | POST | [/v1/chats/events/subscribe](/docs/chats/events/subscribe) | im.v2.Event.subscribe | Подписаться на события | | POST | [/v1/chats/events/unsubscribe](/docs/chats/events/unsubscribe) | im.v2.Event.unsubscribe | Отписаться от событий | | GET | [/v1/chats/events](/docs/chats/events/poll) | im.v2.Event.get | Получить события | ## Коды ошибок Коды, специфичные для работы с чатами: | Код | HTTP | Описание | |-----|------|---------| | `SCOPE_DENIED` | 403 | API-ключ не имеет скоупа `im` | | `TOKEN_MISSING` | 401 | У API-ключа не настроены токены Битрикс24 | | `MISSING_PARAMS` | 400 | Не переданы обязательные параметры (`entityType`/`entityId` при поиске, `filename`/`content` при загрузке файла) | | `INVALID_REQUEST` | 400 | Некорректное тело запроса (например, пустой массив `dialogs` в массовой загрузке) | | `BATCH_LIMIT_EXCEEDED` | 400 | Превышен лимит 50 диалогов в массовой загрузке | | `INVALID_CHAT_ID` | 400 | `chatId` не является положительным целым числом | | `TITLE_EMPTY` | 400 | Пустое название при переименовании чата | | `INVALID_OFFSET` | 400 | Некорректный `offset` при опросе событий | | `INVALID_LIMIT` | 400 | `limit` вне допустимого диапазона | | `CHAT_NOT_FOUND_OR_NO_ACCESS` | 404 | Чат не существует или нет прав на операцию | | `DIALOG_NOT_FOUND_OR_NO_ACCESS` | 404 | Диалог не существует или нет доступа | | `ENTITY_NOT_FOUND` | 404 | Запрошенный объект не найден | | `FILE_NOT_FOUND` | 404 | Файл с указанным `fileId` не найден | | `FOLDER_NOT_FOUND` | 404 | Папка чата на Диске не найдена | | `UPLOAD_FAILED` | 500 | Не удалось загрузить файл на Диск | | `ME_ALIAS_RESOLUTION_FAILED` | 502 | Не удалось определить текущего пользователя для алиаса `me` | | `BITRIX_ERROR` | 422 | Битрикс24 вернул ошибку (текст в поле `message`) | | `BITRIX_UNAVAILABLE` | 502 | Портал Битрикс24 недоступен или вернул ошибку сервера | Общие коды авторизации, ключей и лимитов — на странице [Ошибки](/docs/errors). ## Смотрите также - [Бот-платформа](/docs/bots) - [Ключи и авторизация](/docs/keys-auth) - [Лимиты и оптимизация](/docs/optimization) - [Справочник ошибок](/docs/errors) --- # Менеджмент-ключи Менеджмент-ключи (`vibe_live_`) не привязаны к одному порталу и предназначены для автоматизации администрирования: управления API-ключами, просмотра порталов и работы с обратной связью. ## Отличие от ключей портала | Возможность | API-ключ (`vibe_api_`) | Ключ авторизации (`vibe_app_`) | Менеджмент-ключ (`vibe_live_`) | |-------------|------------------------|--------------------------------|--------------------------------| | Привязка к порталу | Да (один портал) | Да (один портал) | Нет (все порталы пользователя) | | Доступ к сущностям Битрикс24 (deals, tasks и др.) | Да | Да | Нет | | Управление API-ключами | Нет | Нет | Да | | Просмотр списка порталов | Нет | Нет | Да | | Работа с обратной связью | Только свои тикеты | Только свои тикеты | Все тикеты платформы | | Справочник API (`/v1/guide`) | Отфильтрован по скоупам | Отфильтрован по скоупам | Полный (все сущности) | ## Скоупы менеджмент-ключа Каждый менеджмент-ключ создаётся с одним или несколькими скоупами. Без нужного скоупа конкретный эндпоинт возвращает `403 MANAGEMENT_SCOPE_REQUIRED` — даже если эндпоинт в принципе доступен менеджмент-ключам. | Скоуп | Открывает | |-------|-----------| | `vibe:mgmt:keys` | `/v1/keys` (список, создание, изменение, удаление, перевыпуск) | | `vibe:mgmt:portals` | `/v1/portals` | | `vibe:mgmt:feedback` | `/v1/feedback` (список тикетов, чтение, обновление, комментарии) | Эндпоинты `/v1/me`, `/v1/guide` и `/v1/openapi.json` доступны любому менеджмент-ключу без отдельного скоупа. При создании ключа выбирайте только нужные скоупы — если ключ предназначен только для управления API-ключами, скоуп `vibe:mgmt:feedback` ему не нужен. ## Доступные эндпоинты При обращении к эндпоинтам сущностей Битрикс24 возвращается `403 MANAGEMENT_KEY_NO_ENTITY_ACCESS`. ### `GET /v1/me` — самоописание ключа Возвращает тип ключа, список порталов с ролями и количеством ключей, перечень доступных эндпоинтов и быстрый старт. ```bash curl -H "X-Api-Key: vibe_live_abc123..." \ https://vibecode.bitrix24.tech/v1/me ``` Ответ: ```json { "success": true, "data": { "type": "management", "keyPrefix": "vibe_live_abc123", "keySuffix": "f9d2", "expiresAt": null, "scopes": [], "capabilities": [ "GET https://vibecode.bitrix24.tech/v1/me — this endpoint (management key self-description)", "GET https://vibecode.bitrix24.tech/v1/guide — full API reference (portal-agnostic)", "GET https://vibecode.bitrix24.tech/v1/keys — list APP keys for a portal (requires portalId query param)", "POST https://vibecode.bitrix24.tech/v1/keys — create APP key (requires portalId in body)", "GET https://vibecode.bitrix24.tech/v1/portals — list your portals", "GET https://vibecode.bitrix24.tech/v1/feedback — list ALL platform feedback (management key sees everything)", "GET https://vibecode.bitrix24.tech/v1/feedback/:id — feedback details including comment thread", "PATCH https://vibecode.bitrix24.tech/v1/feedback/:id — update status/resolution (legacy, prefer /comments)", "POST https://vibecode.bitrix24.tech/v1/feedback/:id/comments — post a team comment, changes status" ], "portals": [ { "id": "portal-uuid", "domain": "mycompany.bitrix24.ru", "status": "ACTIVE", "role": "ADMIN", "appKeyCount": 3 } ], "totalAppKeys": 3, "quickstart": { "step1": "GET https://vibecode.bitrix24.tech/v1/portals — list available portals", "step2": "GET https://vibecode.bitrix24.tech/v1/keys?portalId= — list APP keys for a portal", "step3": "POST https://vibecode.bitrix24.tech/v1/keys { portalId, name, scopes } — create an APP key", "step4": "Use the APP key for entity API calls (deals, tasks, etc.)" }, "docs": "https://vibecode.bitrix24.tech/docs/management-keys" } } ``` В ответе также присутствует объект `feedback` со справочником эндпоинтов, статусов и фильтров для работы с тикетами обратной связи — он используется AI-моделями для автоматической обработки тикетов. ### `GET /v1/guide` — справочник API Возвращает полный справочник API со всеми сущностями (без фильтрации по скоупам). Используется для подбора нужных эндпоинтов перед созданием API-ключей. ```bash curl -H "X-Api-Key: vibe_live_abc123..." \ https://vibecode.bitrix24.tech/v1/guide ``` ### `GET /v1/openapi.json` — OpenAPI-спецификация Возвращает машинно-читаемую OpenAPI 3.1 спецификацию платформы Вайбкод. ```bash curl -H "X-Api-Key: vibe_live_abc123..." \ https://vibecode.bitrix24.tech/v1/openapi.json ``` ### `GET /v1/portals` — список порталов Возвращает порталы, к которым пользователь имеет доступ, с ролью на каждом портале. ```bash curl -H "X-Api-Key: vibe_live_abc123..." \ https://vibecode.bitrix24.tech/v1/portals ``` ### `GET /v1/keys` — список API-ключей портала Параметр `portalId` обязателен. ```bash curl -H "X-Api-Key: vibe_live_abc123..." \ "https://vibecode.bitrix24.tech/v1/keys?portalId=portal-uuid" ``` ### `POST /v1/keys` — создание API-ключа Создаёт новый API-ключ (`vibe_api_`) для указанного портала. В теле передаётся `portalId`, имя и список скоупов. Полный ключ возвращается в поле `rawKey` один раз — сохраните его сразу. ```bash curl -X POST \ -H "X-Api-Key: vibe_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"portalId": "portal-uuid", "name": "My Key", "scopes": ["crm", "task"]}' \ https://vibecode.bitrix24.tech/v1/keys ``` Дополнительные коды ошибок: | Код | HTTP | Когда возвращается | |-----|------|---------------------| | `MISSING_PORTAL_ID` | 400 | В теле запроса не указан `portalId` | | `NOT_PORTAL_MEMBER` | 403 | Владелец ключа не состоит в указанном портале | | `PORTAL_NOT_LINKED` | 400 | Портал не подключён к Битрикс24 Network — создать ключ невозможно | | `BITRIX_UNAVAILABLE` | 502 | Битрикс24 не ответил на регистрацию входящего вебхука | ### `GET /v1/keys/:id` — данные одного ключа Возвращает данные ключа без секрета (только префикс, имя, скоупы, статус). ```bash curl -H "X-Api-Key: vibe_live_abc123..." \ https://vibecode.bitrix24.tech/v1/keys/key-uuid ``` ### `PATCH /v1/keys/:id` — обновление ключа Можно изменить любое из полей ниже (все необязательны, передавайте только то, что меняете): | Поле | Тип | Описание | |------|-----|----------| | `name` | string | Имя ключа в личном кабинете | | `scopes` | string[] | Список скоупов — см. [Скоупы](./scopes.md) | | `status` | `"ACTIVE"` \| `"REVOKED"` | Активация или отзыв ключа | | `ipWhitelist` | string[] | Список разрешённых IP-адресов | | `rateLimit` | number \| null | Индивидуальный лимит запросов в секунду | | `expiresAt` | ISO-8601 \| null | Срок действия ключа (`null` — бессрочный) | ```bash curl -X PATCH \ -H "X-Api-Key: vibe_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"status": "REVOKED"}' \ https://vibecode.bitrix24.tech/v1/keys/key-uuid ``` ### `DELETE /v1/keys/:id` — удаление ключа Удаляет ключ. Если на ключе есть активные серверы, возвращается `409 KEY_HAS_ACTIVE_SERVERS` — серверы нужно удалить первыми. ```bash curl -X DELETE \ -H "X-Api-Key: vibe_live_abc123..." \ https://vibecode.bitrix24.tech/v1/keys/key-uuid ``` ### `POST /v1/keys/:id/rotate` — перевыпуск ключа Создаёт новый ключ с теми же настройками и оставляет старому переходный период 24 часа. После перевыпуска старый ключ автоматически становится недействительным. ```bash curl -X POST \ -H "X-Api-Key: vibe_live_abc123..." \ https://vibecode.bitrix24.tech/v1/keys/key-uuid/rotate ``` ### `GET /v1/feedback` — список тикетов обратной связи Возвращает все тикеты обратной связи на платформе. Поддерживает фильтры по статусу, категории, порталу и постраничную выборку. ```bash curl -H "X-Api-Key: vibe_live_abc123..." \ "https://vibecode.bitrix24.tech/v1/feedback?status=NEW&page=1&limit=50" ``` ### `GET /v1/feedback/:id` — карточка тикета Возвращает тикет со всем тредом комментариев. ### `PATCH /v1/feedback/:id` — обновление тикета Меняет статус и резолюцию тикета. ### `POST /v1/feedback/:id/comments` — комментарий к тикету Добавляет команду в тред и одновременно меняет статус. Используется AI-моделями для ответа пользователю. #### Статусы тикетов | Статус | Когда применяется | |--------|-------------------| | `NEW` | Пользователь только что отправил тикет, никто его ещё не смотрел | | `REVIEWING` | Команда взяла тикет в работу, пользователь пока не получает обновлений | | `AWAITING_USER` | Команда задала пользователю уточняющий вопрос — ждём ответа (пользователь получает письмо) | | `NEEDS_REVIEW` | Пользователь ответил на уточнение — команда читает новый комментарий и решает следующий шаг | | `RESOLVED` | Исправление опубликовано в продуктовой среде, пользователь получил уведомление | | `ARCHIVED` | Закрыт без правки кода (дубликат, вне темы, не воспроизводится) | #### Категории тикетов `BUG`, `SUGGESTION`, `DOCS`, `CHAT`, `BOTS`, `OTHER`. #### Фильтры списка `?status=NEW&category=BUG&portalId=&page=1&limit=50`. Параметр `limit` ограничен значением 100. ## Быстрый старт 1. Создайте менеджмент-ключ в личном кабинете (раздел «Менеджмент-ключи») 2. Получите список порталов: `GET /v1/portals` 3. Посмотрите существующие ключи на нужном портале: `GET /v1/keys?portalId=` 4. Создайте API-ключ с нужными скоупами: `POST /v1/keys { portalId, name, scopes }` 5. Используйте полученный API-ключ (`vibe_api_…`) для работы с данными Битрикс24 ## Ограничения - Менеджмент-ключи не могут обращаться к эндпоинтам сущностей Битрикс24 (`/v1/deals`, `/v1/tasks` и другим) - Для работы с данными используйте API-ключ (`vibe_api_`) или ключ авторизации (`vibe_app_`) - При попытке обратиться к неподдерживаемому эндпоинту возвращается `403 MANAGEMENT_KEY_NO_ENTITY_ACCESS` ## Смотрите также - [Ключи и авторизация](./keys-auth.md) — создание ключа, типы, передача, лимиты, IP, жизненный цикл, безопасность - [Скоупы](./scopes.md) — справочник скоупов и как их выбрать - [Быстрый старт](./quickstart.md) — первый запрос за 2 минуты - [Оптимизация и batch](./optimization.md) — ускорение в 50 раз через `POST /v1/batch` - [Коды ошибок](./errors.md) — справочник ошибок API --- # Partner Connect Подключение внешних сервисов к Битрикс24: ваше приложение запрашивает у пользователя разрешение на доступ к его порталу и получает API-ключ Вайбкод для дальнейших вызовов. Поток построен по схеме Authorization Code — той же, что у OAuth-провайдеров Google или GitHub. **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `client_id` + `client_secret` партнёра | **Скоупы ключа:** запрашиваются на странице согласия ## Содержание - [Когда применять](#когда-применять) - [Как это работает](#как-это-работает) - [Справочник эндпоинтов](#справочник-эндпоинтов) - [Полный сценарий](#полный-сценарий) — Express-обработчик от и до - [`GET /v1/connect/authorize`](#get-v1-connect-authorize) — старт потока, редирект на согласие - [`POST /v1/connect/token`](#post-v1-connect-token) — обмен кода на API-ключ - [Использование API-ключа](#использование-api-ключа) - [Доступные скоупы](#доступные-скоупы) - [Время жизни и отзыв ключа](#время-жизни-и-отзыв-ключа) - [Безопасность](#безопасность) - [Регистрация партнёра](#регистрация-партнёра) - [Смотрите также](#смотрите-также) ## Когда применять Сценарий — внешний SaaS-продукт, который интегрируется с порталами Битрикс24 ваших клиентов: CRM-аналитика, синхронизация с 1С, чат-ассистент, конструктор лендингов. Кнопка «Подключить Битрикс24» на вашем сайте запускает поток: пользователь выбирает портал и подтверждает скоупы, ваш сервер получает постоянный API-ключ и работает с порталом от имени пользователя. Если вы пишете приложение, которое ставится **внутри** портала Битрикс24 и работает только с ним, — используйте обычный API-ключ, см. [Авторизация и ключи](/docs/keys-auth). ## Как это работает ``` Ваше приложение → [1. Redirect] → Вайбкод Consent Page → [2. Согласие] ↑ ↓ └──── [4. API-ключ] ←── [3. Code → redirect_uri] ──────────┘ ``` 1. **Redirect** — отправляете пользователя на `/v1/connect/authorize` с `client_id`, `redirect_uri`, `state` и списком скоупов. 2. **Согласие** — пользователь видит страницу Вайбкод, выбирает портал и подтверждает или отклоняет запрошенные скоупы. 3. **Код** — после одобрения пользователь возвращается на `redirect_uri` с параметрами `code` и `state`. При отказе — `redirect_uri?error=access_denied&state=...`. 4. **Обмен** — сервер партнёра отправляет `POST /v1/connect/token` и получает API-ключ. ## Справочник эндпоинтов | Метод | Путь | Описание | |-------|------|----------| | GET | [`/v1/connect/authorize`](#get-v1-connect-authorize) | Старт потока: редирект на страницу согласия | | POST | [`/v1/connect/token`](#post-v1-connect-token) | Обмен одноразового кода на постоянный API-ключ | ## Полный сценарий Пример Express-обработчика, который проводит пользователя через оба эндпоинта от и до. Перед запуском поместите `client_id` и `client_secret`, выданные командой Битрикс24 Вайбкод, в переменные окружения, а `redirect_uri` зарегистрируйте у партнёра. ```javascript import express from 'express' import crypto from 'node:crypto' const app = express() const sessions = new Map() // в продакшене — Redis или БД const CLIENT_ID = process.env.PARTNER_CLIENT_ID const CLIENT_SECRET = process.env.PARTNER_CLIENT_SECRET const REDIRECT_URI = 'https://yourapp.com/callback' // 1. Кнопка «Подключить Битрикс24» ведёт сюда app.get('/connect', (req, res) => { const state = crypto.randomBytes(16).toString('hex') sessions.set(state, { userId: req.user.id, createdAt: Date.now() }) const params = new URLSearchParams({ client_id: CLIENT_ID, redirect_uri: REDIRECT_URI, scopes: 'crm,task', state, }) res.redirect(`https://vibecode.bitrix24.tech/v1/connect/authorize?${params}`) }) // 2. Вайбкод возвращает пользователя сюда после согласия или отказа app.get('/callback', async (req, res) => { const { code, state, error } = req.query const session = sessions.get(state) if (!session) return res.status(400).send('Неизвестный state') sessions.delete(state) if (error === 'access_denied') { return res.redirect('/dashboard?connect=denied') } // 3. Обмениваем код на API-ключ — серверный запрос с client_secret const tokenRes = await fetch('https://vibecode.bitrix24.tech/v1/connect/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ client_id: CLIENT_ID, client_secret: CLIENT_SECRET, code, redirect_uri: REDIRECT_URI, }), }) const data = await tokenRes.json() if (!data.success) { return res.status(400).send(`Ошибка обмена: ${data.error.code}`) } // 4. Сохраняем привязку: пользователь нашего сервиса ↔ портал Битрикс24 await db.connections.upsert({ userId: session.userId, portalDomain: data.portal.domain, portalName: data.portal.name, apiKey: encrypt(data.api_key), // секрет, шифруем перед хранением scopes: data.scopes, }) res.redirect('/dashboard?connect=ok') }) // 5. Дальше используем сохранённый ключ для вызовов от имени пользователя async function listDeals(userId) { const connection = await db.connections.findByUserId(userId) const apiKey = decrypt(connection.apiKey) const res = await fetch('https://vibecode.bitrix24.tech/v1/deals?limit=10', { headers: { 'X-Api-Key': apiKey }, }) return res.json() } ``` Ключевые моменты сценария: - `state` генерируется на сервере и проверяется при возврате — без этой проверки злоумышленник может подсунуть пользователю чужой код. - `client_secret` хранится только на сервере и в браузер не попадает. - API-ключ шифруется перед записью в БД и расшифровывается только в момент вызова. - При `error=access_denied` пользователь видит понятное сообщение, а не страницу с ошибкой обмена. ## GET /v1/connect/authorize Перенаправляет пользователя на страницу согласия Битрикс24 Вайбкод. **Query-параметры:** | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|----------| | `client_id` | string | да | Идентификатор партнёра, выданный командой Битрикс24 Вайбкод | | `redirect_uri` | string | да | URL обратного вызова. Должен совпадать с одним из зарегистрированных у партнёра | | `state` | string | да | Произвольная строка, которая вернётся вместе с кодом. Защита от CSRF | | `scopes` | string | нет | Список скоупов через запятую: `crm,task,im`. Если не передать — применяются скоупы по умолчанию из настроек партнёра | **Пример URL:** ``` https://vibecode.bitrix24.tech/v1/connect/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=https://yourapp.com/callback&scopes=crm,task&state=abc123random ``` **Успешный редирект** после одобрения: ``` https://yourapp.com/callback?code=AUTH_CODE_HERE&state=abc123random ``` **Редирект при отказе** пользователя на странице согласия: ``` https://yourapp.com/callback?error=access_denied&state=abc123random ``` ### Ошибки | HTTP | Код | Описание | |------|-----|----------| | 400 | `INVALID_REQUEST` | Не передан один из `client_id`, `redirect_uri`, `state` | | 400 | `INVALID_CLIENT` | `client_id` не зарегистрирован или партнёр отключён | | 400 | `INVALID_REDIRECT_URI` | `redirect_uri` не совпадает ни с одним из зарегистрированных у партнёра | | 400 | `INVALID_SCOPE` | Один или несколько скоупов не входят в список разрешённых для Битрикс24 | Полный справочник общих ошибок API — [Ошибки](/docs/errors). ## POST /v1/connect/token Обменивает одноразовый код авторизации на постоянный API-ключ. Принимает `application/json` и `application/x-www-form-urlencoded`. **Поля запроса (body):** | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|----------| | `client_id` | string | да | Идентификатор партнёра | | `client_secret` | string | да | Секрет партнёра. Передавать только с серверной стороны | | `code` | string | да | Код из параметра `code` редиректа | | `redirect_uri` | string | да | Тот же `redirect_uri`, что был передан в `/v1/connect/authorize` | ### Примеры #### curl ```bash curl -X POST https://vibecode.bitrix24.tech/v1/connect/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=YOUR_CLIENT_SECRET \ -d code=RECEIVED_CODE \ -d redirect_uri=https://yourapp.com/callback ``` #### JavaScript ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/connect/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ client_id: 'YOUR_CLIENT_ID', client_secret: 'YOUR_CLIENT_SECRET', code: receivedCode, redirect_uri: 'https://yourapp.com/callback', }), }) const data = await res.json() // data.api_key — постоянный API-ключ Вайбкод // data.portal — выбранный пользователем портал // data.scopes — подтверждённые скоупы // data.user — пользователь, выдавший доступ ``` ### Поля ответа | Поле | Тип | Описание | |------|-----|----------| | `success` | boolean | `true` при успешном обмене | | `api_key` | string | API-ключ Вайбкод в формате `vibe_app_...`. Передавать в заголовке `X-Api-Key` при последующих вызовах | | `portal.domain` | string | Домен портала Битрикс24, например `example.bitrix24.ru` | | `portal.name` | string | Название портала | | `scopes` | string[] | Список скоупов, которые пользователь подтвердил. Может быть короче запрошенного, если пользователь снял часть | | `user.name` | string | Имя пользователя, выдавшего доступ | | `user.email` | string | Электронная почта пользователя | ### Пример ответа ```json { "success": true, "api_key": "vibe_app_...", "portal": { "domain": "example.bitrix24.ru", "name": "Моя компания" }, "scopes": ["crm", "task"], "user": { "name": "Иван Иванов", "email": "ivan@example.com" } } ``` ### Пример ответа при ошибке 400 — отсутствует обязательный параметр: ```json { "success": false, "error": { "code": "INVALID_REQUEST", "message": "Missing required parameters" } } ``` ### Ошибки | HTTP | Код | Описание | |------|-----|----------| | 400 | `INVALID_REQUEST` | Не передан один из `client_id`, `client_secret`, `code`, `redirect_uri` | | 400 | `INVALID_CODE` | Код не существует, истёк (5 минут), уже был использован, либо `redirect_uri` отличается от того, что был передан в `/v1/connect/authorize` | | 401 | `INVALID_CLIENT` | `client_id` неизвестен или `client_secret` не совпадает | | 403 | `PARTNER_DISABLED` | Учётная запись партнёра приостановлена | Полный справочник общих ошибок API — [Ошибки](/docs/errors). ## Использование API-ключа Полученный ключ имеет тип `APP` и работает как стандартный API-ключ Вайбкод. Передавайте его в заголовке `X-Api-Key`: ```bash curl -H "X-Api-Key: vibe_app_..." \ https://vibecode.bitrix24.tech/v1/deals ``` Один и тот же ключ можно использовать с любым эндпоинтом Вайбкод API в пределах подтверждённых скоупов: список сделок, batch-запросы, поиск, агрегация и т. д. Партнёрский ключ работает с одним заголовком `X-Api-Key` и **не требует** `Authorization: Bearer `. Это отличает его от ключей OAuth-приложений из каталога Вайбкод с тем же префиксом `vibe_app_...` — там сессия пользователя обязательна. ## Доступные скоупы При вызове `/v1/connect/authorize` передавайте те же скоупы, что и при создании стандартного API-ключа в портале Битрикс24. На странице согласия пользователь видит список и может снять отдельные пункты — итоговый набор приходит в поле `scopes` ответа `/v1/connect/token`. Полный список поддерживаемых значений (32 скоупа: `crm`, `task`, `tasks`, `im`, `imbot`, `imopenlines`, `call`, `telephony`, `bizproc`, `calendar`, `timeman`, `catalog`, `sale`, `lists`, `disk`, `entity`, `user`, `user_basic`, `user_brief`, `user.userfield`, `department`, `landing`, `documentgenerator`, `sign.b2e`, `sonet_group`, `log`, `vote`, `ai_admin`, `biconnector`, `booking`, `delivery`, `pay_system`, `main`, `placement`, `userfieldtype`) описан в разделе [Авторизация и ключи](/docs/keys-auth). ## Время жизни и отзыв ключа - **Код авторизации (`code`)** действует **5 минут** и одноразовый. После обмена через `/v1/connect/token` повторный вызов с тем же кодом вернёт `INVALID_CODE`. - **Стейт согласия** (внутреннее состояние страницы согласия) живёт 10 минут — если пользователь не подтвердит за это время, ссылку придётся выдавать заново. - **API-ключ** не имеет срока истечения. Действует, пока: - пользователь не отзовёт доступ в портале (на странице управления выданными правами в личном кабинете), - либо команда Битрикс24 Вайбкод не приостановит партнёрское приложение. При отзыве ключа все запросы с ним возвращают `401 KEY_INACTIVE`. Если ключ удалён или неизвестен — `401 INVALID_API_KEY`. Партнёр должен корректно обработать оба кода и предложить пользователю повторно авторизоваться. ## Безопасность - **State-параметр** — генерируйте криптостойкую случайную строку на каждый запрос и сверяйте при возврате на `redirect_uri`. Защищает от CSRF. - **`client_secret` — только на сервере.** Никогда не передавайте секрет в браузер, мобильное приложение или клиентский код. Обмен кода на ключ выполняется только серверным запросом. - **Хранение ключа.** API-ключ — секрет, который даёт доступ к данным пользователя. Храните в зашифрованном виде, ограничивайте доступ к строке подключения, не логируйте. - **Привязка `redirect_uri`.** Значение в `/v1/connect/authorize` и `/v1/connect/token` должно совпадать символ в символ — несоответствие приведёт к `INVALID_CODE`. ## Регистрация партнёра Самостоятельная регистрация пока не предусмотрена — `client_id` и `client_secret` выдаёт команда Битрикс24 Вайбкод после ревью заявки. Чтобы оставить заявку, напишите на `lev@bitrix.ru`. В заявке укажите: - название и краткое описание приложения, - сценарий использования, - список запрашиваемых скоупов, - один или несколько `redirect_uri`, которые будете использовать. ## Смотрите также - [Авторизация и ключи](/docs/keys-auth) — общие правила работы с API-ключами Вайбкод, типы ключей (включая OAuth-приложения), список скоупов - [Управляющие ключи](/docs/management-keys) — программное создание ключей для собственного портала - [Ошибки API](/docs/errors) — общий справочник кодов ошибок --- # Справочник сущностей Полный перечень сущностей и специализированных API с доступными операциями. Для каждой сущности указан путь, набор операций и требуемый скоуп. Описание общего формата запросов и ответов — в разделе [Обзор API](/docs/entity-api). ## Сущности по разделам ### CRM | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Сделки](/docs/entities/deals) | `/v1/deals` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` `products` | `crm` | | [Контакты](/docs/entities/contacts) | `/v1/contacts` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Компании](/docs/entities/companies) | `/v1/companies` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Лиды](/docs/entities/leads) | `/v1/leads` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` `products` | `crm` | | [Предложения](/docs/entities/quotes) | `/v1/quotes` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` `products` | `crm` | | [Счета](/docs/entities/invoices) | `/v1/invoices` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` `products` | `crm` | | [Направления сделок](/docs/entities/deal-categories) | `/v1/deal-categories` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Дела](/docs/entities/activities) | `/v1/activities` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Товары CRM](/docs/entities/products) | `/v1/products` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Разделы товаров](/docs/entities/product-sections) | `/v1/product-sections` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Статусы и стадии](/docs/entities/statuses) | `/v1/statuses` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Валюты](/docs/entities/currencies) | `/v1/currencies` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | [Реквизиты](/docs/entities/requisites) | `/v1/requisites` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | Пресеты реквизитов | `/v1/requisite-presets` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | Банковские реквизиты | `/v1/bank-details` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | | Адреса (composite key) | `/v1/addresses`, `/v1/addresses/:typeId/:entityTypeId/:entityId` | `list` `get` `create` `update` `delete` `fields` | `crm` | | Поля пресета (вложенные) | `/v1/requisite-presets/:presetId/fields` | `list` `get` `create` `update` `delete` `available` `schema` | `crm` | | Связи реквизитов | `/v1/requisite-links`, `/v1/requisite-links/:entityTypeId/:entityId` | `list` `get` `register` `unregister` `fields` | `crm` | | [Таймлайн](/docs/entities/timelines) | `/v1/timelines` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `crm` | ### Смарт-процессы | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Смарт-процессы](/docs/entities/smart-processes) | `/v1/smart-processes` | `list` `get` `create` `update` `delete` `fields` `search` | `crm` | | [Элементы смарт-процессов](/docs/entities/items) | `/v1/items/:entityTypeId` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` `products` | `crm` | ### Задачи | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Задачи](/docs/entities/tasks) | `/v1/tasks` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `tasks` | | [Комментарии к задачам](/docs/entities/task-comments) | `/v1/tasks/:taskId/comments` | `list` `get` `create` `update` `delete` | `task` | | [Учёт времени задач](/docs/entities/tasks/time) | `/v1/tasks/:taskId/time` | `list` `get` `create` `update` `delete` | `task` | ### Календарь | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [События календаря](/docs/entities/calendar-events) | `/v1/calendar-events` | `list` `get` `create` `update` `delete` `fields` | `calendar` | ### Диск | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Файлы](/docs/entities/files) | `/v1/files` | `list` `get` `update` `delete` `fields` `search` `aggregate` | `disk` | | [Папки](/docs/entities/folders) | `/v1/folders` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `disk` | | [Хранилища](/docs/entities/storages) | `/v1/storages` | `list` `get` `fields` `search` `aggregate` | `disk` | ### Пользователи и соцсеть | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Сотрудники](/docs/entities/users) | `/v1/users` | `list` `get` `create` `invite` `update` `delete` `fields` `search` `aggregate` | `user` | | [Отделы](/docs/entities/departments) | `/v1/departments` | `list` `get` `create` `update` `delete` `fields` `search` | `department` | | [Рабочие группы](/docs/entities/workgroups) | `/v1/workgroups` | `list` `get` `create` `update` `delete` `search` `fields` | `sonet_group` | ### Торговый каталог | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Каталоги](/docs/entities/catalogs) | `/v1/catalogs` | `list` `get` `search` `fields` | `catalog` | | [Товары каталога](/docs/entities/catalog-products) | `/v1/catalog-products` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `catalog` | | [Разделы каталога](/docs/entities/catalog-sections) | `/v1/catalog-sections` | `list` `get` `create` `update` `delete` `search` `aggregate` | `catalog` | | [Цены каталога](/docs/entities/catalog-prices) | `/v1/catalog-prices` | `list` `get` `create` `update` `delete` `search` `fields` | `catalog` | | [Склады](/docs/entities/warehouses) | `/v1/warehouses` | `list` `get` `create` `update` `delete` `stock` | `catalog` | ### Интернет-магазин | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Заказы](/docs/entities/orders) | `/v1/orders` | `list` `get` `create` `update` `delete` `fields` `search` `aggregate` | `sale` | | [Оплаты](/docs/entities/payments) | `/v1/payments` | `list` `get` `create` `update` `delete` `search` `aggregate` | `sale` | | [Позиции корзины](/docs/entities/basket-items) | `/v1/basket-items` | `list` `get` `create` `update` `delete` `search` `aggregate` | `sale` | | [Статусы заказов](/docs/entities/order-statuses) | `/v1/order-statuses` | `list` `get` `create` `update` `delete` `search` `aggregate` | `sale` | ### Сайты | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Сайты](/docs/entities/sites) | `/v1/sites` | `list` `get` `create` `update` `delete` `search` `aggregate` | `landing` | | [Страницы](/docs/entities/pages) | `/v1/pages` | `list` `get` `create` `update` `delete` `search` | `landing` | ### Генератор документов | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Шаблоны документов](/docs/entities/doc-templates) | `/v1/doc-templates` | `list` `get` `create` `update` `delete` `fields` `search` | `documentgenerator` | | [Документы](/docs/entities/documents) | `/v1/documents` | `list` `get` `create` `update` `delete` `fields` `search` | `documentgenerator` | ### Бронирование | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Бронирования](/docs/entities/bookings) | `/v1/bookings` | `list` `get` `create` `update` `delete` `search` | `booking` | ### Бизнес-процессы | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Шаблоны бизнес-процессов](/docs/entities/bizproc-templates) | `/v1/bizproc-templates` | `list` `create` `update` `delete` `search` `aggregate` | `bizproc` | | [Действия бизнес-процессов](/docs/entities/bizproc-activities) | `/v1/bizproc-activities` | `list` `create` `update` `delete` `search` `aggregate` | `bizproc` | | [Роботы](/docs/entities/bizproc-robots) | `/v1/bizproc-robots` | `list` `create` `update` `delete` `search` `aggregate` | `bizproc` | ### Открытые линии | Сущность | Путь | Операции | Скоуп | |----------|------|----------|-------| | [Конфигурации открытых линий](/docs/entities/openline-configs) | `/v1/openline-configs` | `list` `get` `create` `update` `delete` `search` `fields` `aggregate` | `imopenlines` | ## Специализированные API Эти API имеют собственные эндпоинты, выходящие за рамки стандартного CRUD: | API | Путь | Скоуп | Описание | |-----|------|-------|----------| | Боты | `/v1/bots` | `imbot` | Платформа ботов (imbot.v2): регистрация, сообщения, чаты, команды, файлы | | Чаты | `/v1/chats` | `im` | IM Chat API: чаты CRM-сущностей, сообщения, групповые чаты | | Бизнес-процессы | `/v1/workflows` | `bizproc` | Запуск, список, завершение процессов, события | | Уведомления | `/v1/notifications` | `im` | Push-уведомления пользователям Битрикс24 | | [Телефония](/docs/telephony) | `/v1/calls`, `/v1/telephony-lines`, `/v1/voximplant-lines` | `telephony` | Регистрация внешних звонков в CRM, исходящие звонки, линии, статистика | | Триггеры | `/v1/triggers` | `crm` | Триггеры CRM-автоматизации: запуск триггера по сделке/лиду | | Лог таймлайна | `/v1/timeline-logs` | `crm` | Таймлайн CRM: действия, заметки, закрепление, привязка к сущностям | | Посты | `/v1/posts` | `log` | Живая лента: объявления, комментарии | | Пользовательские поля | `/v1/userfields` | `crm` | Пользовательские поля CRM: сделки, лиды, контакты, компании, предложения | | История стадий | `/v1/stage-history` | `crm` | История переходов по стадиям CRM | | Дубликаты | `/v1/duplicates` | `crm` | Поиск дубликатов по телефону/email | | Рабочий день | `/v1/workday` | `timeman` | Учёт рабочего времени: открытие/закрытие дня, статус, настройки | | Пакетные запросы | `/v1/batch` | `*` | До 50 вызовов сущностей в одном запросе (1 единица рейт-лимита) | ## Общие возможности Все эндпоинты сущностей поддерживают: - **[Фильтрация](/docs/filtering):** `?filter[stageId]=NEW` или `?filter[$gte][amount]=1000` (MongoDB-операторы) - **Сортировка:** `?sort=-createdAt` (префикс `-` для сортировки по убыванию) - **Пагинация:** `?limit=50&offset=100` (автопагинация при limit > 50) - **Выбор полей:** `?select=id,title,amount` - **Трансформация полей:** camelCase-имена автоматически конвертируются в имена полей Битрикс24 - **Метаданные полей:** `GET /v1/{entity}/fields` возвращает описание полей, включая пользовательские UF-поля с подписями. Для полей-перечислений возвращается массив `items` с доступными значениями - **Поиск:** `POST /v1/{entity}/search` — расширенный поиск с автоматическим разбиением по датам для больших наборов данных - **Агрегация:** `POST /v1/{entity}/aggregate` — подсчёт, сумма, среднее, минимум, максимум по полям - **Товарные позиции:** для CRM-сущностей с товарами (сделки, лиды, предложения, счета, элементы смарт-процессов) доступны маршруты `GET/POST/PUT/PATCH/DELETE /v1/{entity}/{id}/products` - **[Связанные данные (include)](/docs/includes):** `?include=company,contact` загружает связанные сущности в одном запросе --- # Связанные данные (include) Загрузка связанных сущностей вместе с основными записями в одном запросе. Вместо отдельных вызовов для получения контакта, компании или ответственного — передайте параметр `include`, и Вайбкод вернёт всё в поле `_included`. > Параметр `include` опциональный и работает в трёх местах: > - `GET /v1/{entity}/{id}?include=...` — получение одной записи > - `GET /v1/{entity}?include=...` — получение списка > - `POST /v1/{entity}/search` — поиск (`include` в теле запроса как массив строк) ## Как использовать Перечислите имена связей через запятую: ### curl ```bash curl "https://vibecode.bitrix24.tech/v1/deals/741?include=contact,company" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### JavaScript ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741?include=contact,company', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data } = await res.json() // data._included.contacts — массив контактов сделки // data._included.company — компания (объект или null) ``` Связанные данные появятся в поле `_included` каждой записи: ```json { "success": true, "data": { "id": 741, "title": "Поставка оборудования", "contactId": 71, "companyId": 15, "_included": { "contacts": [ { "id": 71, "name": "Иван", "lastName": "Петров", "phone": [{ "VALUE": "+79161234567" }], "isPrimary": true, "sort": 10 } ], "company": { "id": 15, "title": "ООО Ромашка", "industry": "IT" } } } } ``` ## Два типа связей ### Один-к-одному Сущность содержит поле-ссылку на связанный объект (например, `companyId` у контакта). Результат — один объект или `null`. ``` GET /v1/leads/50?include=contact ``` ```json { "data": { "id": 50, "title": "Заявка с сайта", "contactId": 71, "_included": { "contact": { "id": 71, "name": "Иван", "lastName": "Петров" } } } } ``` Если поле-ссылка пустое или равно 0, возвращается `null`: ```json { "_included": { "contact": null } } ``` ### Много-ко-многим Связь через промежуточную таблицу. Результат — массив объектов с дополнительными полями связи. ``` GET /v1/deals/741?include=contact ``` ```json { "_included": { "contacts": [ { "id": 71, "name": "Иван", "lastName": "Петров", "isPrimary": true, "sort": 10, "roleId": 0 }, { "id": 85, "name": "Мария", "lastName": "Сидорова", "isPrimary": false, "sort": 20, "roleId": 0 } ] } } ``` Обратите внимание: имя связи в запросе — `contact` (ед. число), а в ответе — `contacts` (мн. число). Вайбкод автоматически плюрализует имя для массивов. Дополнительные поля связи (`isPrimary`, `sort`, `roleId`) добавляются к каждому объекту — их значения приходят из промежуточной таблицы, а не из самой сущности. ## Использование в списках и поиске ### curl — список ```bash curl "https://vibecode.bitrix24.tech/v1/deals?limit=10&include=company" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### JavaScript — список ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals?limit=10&include=company', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data, meta } = await res.json() for (const deal of data) { console.log(deal.title, '—', deal._included.company?.title ?? 'без компании') } // meta.includeSkipped === true, если записей > 200 ``` Ответ: ```json { "success": true, "data": [ { "id": 741, "title": "Поставка оборудования", "companyId": 15, "_included": { "company": { "id": 15, "title": "ООО Ромашка" } } }, { "id": 742, "title": "Техподдержка", "companyId": 15, "_included": { "company": { "id": 15, "title": "ООО Ромашка" } } } ], "total": 150, "meta": { "hasMore": true } } ``` Вайбкод дедуплицирует запросы: если несколько записей ссылаются на одну компанию, она загружается один раз. ### curl — поиск В поиске `include` передаётся в теле запроса как массив. ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deals/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "stageId": "NEW", "amount": { "$gte": 100000 } }, "include": ["contact", "company"], "limit": 50 }' ``` ### JavaScript — поиск ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { stageId: 'NEW', amount: { $gte: 100000 } }, include: ['contact', 'company'], limit: 50, }), }) const { data } = await res.json() ``` ## Несколько связей в одном запросе Можно запросить до 3 связей одновременно: ``` GET /v1/quotes/18?include=deal,contact,company ``` ```json { "_included": { "deal": { "id": 741, "title": "Поставка оборудования" }, "contact": { "id": 71, "name": "Иван", "lastName": "Петров" }, "company": { "id": 15, "title": "ООО Ромашка" } } } ``` ## Лимиты | Параметр | Значение | |----------|---------| | Максимум связей в запросе | 3 | | Максимум записей для include | 200 | Если в списке или поиске больше 200 записей, include **пропускается** и в `meta` добавляется флаг: ```json { "data": [ ... ], "meta": { "hasMore": true, "includeSkipped": true } } ``` Чтобы получить связанные данные для больших выборок — уменьшите `limit` до 200 или меньше. ## Доступные связи по сущностям Узнать доступные include для конкретной сущности можно через эндпоинт полей: ```bash curl "https://vibecode.bitrix24.tech/v1/deals/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` В ответе будет поле `include` со списком доступных связей: ```json { "success": true, "data": { "fields": { ... }, "include": ["contact", "company"] } } ``` Доступные связи зависят от сущности. Какие именно include поддерживает конкретная сущность — указано в документации каждого метода и в ответе `GET /v1/{entity}/fields` (поле `include`). ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INCLUDE_LIMIT_EXCEEDED` | Запрошено более 3 связей | | 400 | `INVALID_INCLUDE` | Связь не найдена. Ответ содержит список доступных связей | Если у сущности вообще нет связей (например, `departments`), любой `include` вернёт `INVALID_INCLUDE` с пустым списком `Available:`. Пример ошибки: ```json { "success": false, "error": { "code": "INVALID_INCLUDE", "message": "Unknown include 'manager'. Available: contact, company, quote" } } ``` ## Связанные разделы - [Entity API](./entity-api.md) — CRUD-операции, пагинация, агрегация - [Фильтрация](./filtering.md) — три синтаксиса фильтров - [Batch API](./batch.md) — объединение вызовов - [Все сущности](./entities-index.md) — полный список сущностей - [Коды ошибок](./errors.md) — справочник ошибок платформы --- # AI Router Единый OpenAI-совместимый API для работы с языковыми моделями от разных провайдеров. Бесплатные модели Битрикс24 доступны сразу — для платных и для своих ключей провайдеров (BYOK) подключите учётные данные. **Это API, а не чат на портале.** Диалогового окна для общения с моделью на портале Вайбкод нет — искать его не нужно. Запрос (промпт) вводится в вашем AI-инструменте, агенте или коде (Cursor, IDE-агент, библиотека `openai`, собственное приложение), который обращается к этому API по адресу ниже. Бесплатные модели Битрикс24 работают так же, как платные и BYOK, — через тот же API. **Скоуп:** `vibe:ai` (добавляется автоматически ко всем API-ключам) | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** заголовок `X-Api-Key` или `Authorization: Bearer YOUR_API_KEY` ## Совместимость с OpenAI SDK Все ответы возвращаются в сыром OpenAI-формате. Подключите любой OpenAI-совместимый инструмент (Cursor, IDE-агенты, библиотека `openai`) через стандартные настройки: ``` Base URL: https://vibecode.bitrix24.tech/v1 API Key: ваш ключ vibe_api_... или vibe_app_... ``` SDK по умолчанию передаёт ключ в заголовке `Authorization: Bearer` — Вайбкод принимает оба варианта (`X-Api-Key` и `Authorization: Bearer`). Параметры запроса (`model`, `messages`, `temperature`, `tools`, `stream`, `response_format`) и поля ответа (`id`, `choices`, `usage`) соответствуют контракту `POST /v1/chat/completions` из OpenAI API. ## Разделы документации - [Чат-комплишены](/docs/ai/chat) — генерация ответов модели в синхронном или потоковом режиме (`Server-Sent Events`) - [Модели](/docs/ai/models) — список доступных моделей и детали отдельной модели - [Распознавание речи](/docs/ai/audio) — преобразование аудио в текст через Whisper Large v3 Turbo - [Свои ключи (BYOK)](/docs/ai/credentials) — подключение собственных ключей провайдеров - [Список провайдеров](/docs/ai/providers) — справочник провайдеров для подключения BYOK - [Статистика использования](/docs/ai/usage) — расход токенов и стоимость по API-ключу - [Совместимость с OpenAI SDK](#совместимость-с-openai-sdk) — настройка Cursor, IDE-агентов и любых OpenAI-совместимых клиентов - [Жизненный цикл моделей](/docs/ai/chat/completions#жизненный-цикл-моделей) — поведение `ACTIVE` / `DEPRECATED` / `DISABLED` и связанные заголовки - [Миграция со старых маршрутов](#миграция-со-старых-маршрутов) — для проектов, где остались вызовы `/v1/ai/chat/completions` и аналогичных --- ## Быстрый старт ### 1. Сгенерируйте ответ бесплатной моделью ```bash curl -X POST https://vibecode.bitrix24.tech/v1/chat/completions \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "bitrix/bitrixgpt-5.5", "messages": [{"role": "user", "content": "Что такое CRM?"}] }' ``` Ответ: ```json { "id": "chatcmpl-a1a73c6eb3f180fd", "object": "chat.completion", "created": 1777289339, "model": "bitrix/bitrixgpt-5.5", "choices": [ { "index": 0, "finish_reason": "stop", "message": { "role": "assistant", "content": "CRM — это система управления взаимоотношениями с клиентами." } } ], "usage": { "prompt_tokens": 12, "completion_tokens": 18, "total_tokens": 30 } } ``` ### 2. Посмотрите доступные модели ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/models ``` Возвращает только те модели, для которых у портала настроены учётные данные провайдера. Модели Битрикс24 (`bitrix/*`) доступны всем без отдельных BYOK-ключей; большинство из них — бесплатные. ### 3. Проверьте расход токенов ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ "https://vibecode.bitrix24.tech/v1/ai/usage?days=7" ``` --- ## Типовые сценарии использования - **Классификация лидов:** запросите лиды через [`GET /v1/leads`](/docs/entities/leads/list), пропустите через [чат-комплишен](/docs/ai/chat/completions) с `response_format: json_object`, обновите CRM-поля через [`PATCH /v1/leads/:id`](/docs/entities/leads/update). - **Генерация контента:** прочитайте товары через [`GET /v1/products`](/docs/entity-api), сгенерируйте описания, обновите карточки в каталоге. - **Извлечение данных:** возьмите комментарии из [`GET /v1/timeline-logs`](/docs/timeline-logs), извлеките телефон / email / название компании, запишите в CRM. - **Чат-бот:** зарегистрируйте бота через [`POST /v1/bots`](/docs/bots/management/create), получайте события через [`GET /v1/bots/:botId/events`](/docs/bots/events), генерируйте ответ AI, отправляйте через [`POST /v1/bots/:botId/messages`](/docs/bots/messages). - **Отчёты:** соберите данные через [`POST /v1/batch`](/docs/batch), сгенерируйте сводку, отправьте уведомление. --- ## Полный пример: распознавание звонка → классификация → запись в таймлайн Сценарий: получить аудиозапись звонка, расшифровать через Whisper, классифицировать качество лида через `JSON`-ответ модели, записать результат в таймлайн сделки. ### Шаг 1. Распознавание речи ```bash curl -X POST https://vibecode.bitrix24.tech/v1/audio/transcriptions \ -H "X-Api-Key: YOUR_API_KEY" \ -F "file=@call-recording.mp3" \ -F "language=ru" \ -F "response_format=json" ``` Ответ: ```json { "text": "Здравствуйте, ООО Вектор. Хотим CRM на 50 пользователей, бюджет до 500 тысяч в месяц." } ``` ### Шаг 2. Классификация лида с гарантированным `JSON` ```bash curl -X POST https://vibecode.bitrix24.tech/v1/chat/completions \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "bitrix/bitrixgpt-5.5", "messages": [ { "role": "system", "content": "Классифицируй лид по тексту звонка. Верни JSON: {\"quality\": \"high|medium|low\", \"score\": 0-100, \"reason\": \"...\"}." }, { "role": "user", "content": "ООО Вектор. CRM на 50 пользователей, бюджет до 500 тысяч в месяц." } ], "response_format": {"type": "json_object"} }' ``` Ответ: ```json { "id": "chatcmpl-acdb112cf9cdf9f9", "object": "chat.completion", "model": "bitrix/bitrixgpt-5.5", "choices": [ { "index": 0, "finish_reason": "stop", "message": { "role": "assistant", "content": "{\"quality\":\"high\",\"score\":88,\"reason\":\"Юрлицо, конкретный объём (50 пользователей) и бюджет 500 тысяч в месяц.\"}" } } ], "usage": {"prompt_tokens": 92, "completion_tokens": 36, "total_tokens": 128} } ``` ### Шаг 3. Запись результата в таймлайн сделки Парсим `choices[0].message.content` как `JSON` и отправляем в таймлайн: ```bash curl -X POST https://vibecode.bitrix24.tech/v1/timeline-logs \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityType": "deal", "entityId": 1234, "title": "Классификация AI: high (88/100)", "text": "Юрлицо, конкретный объём (50 пользователей) и бюджет 500 тысяч в месяц." }' ``` Все три эндпоинта живут в одном API-ключе и одной авторизации — отдельных интеграций не требуется. --- ## Справочник эндпоинтов | Метод | Путь | Описание | |-------|------|----------| | POST | [`/v1/chat/completions`](/docs/ai/chat/completions) | Генерация ответа модели — синхронно или потоком | | GET | [`/v1/models`](/docs/ai/models/list) | Список доступных моделей | | GET | [`/v1/models/:modelId`](/docs/ai/models/get) | Детали конкретной модели | | POST | [`/v1/audio/transcriptions`](/docs/ai/audio/transcriptions) | Распознавание речи через Whisper | | GET | [`/v1/ai/usage`](/docs/ai/usage) | Статистика использования AI по ключу | | GET | [`/v1/ai/providers`](/docs/ai/providers) | Список провайдеров для BYOK | | GET | [`/v1/ai/credentials`](/docs/ai/credentials/list) | Список собственных ключей провайдеров | | POST | [`/v1/ai/credentials`](/docs/ai/credentials/create) | Подключить ключ провайдера (с верификацией) | | PATCH | [`/v1/ai/credentials/:id`](/docs/ai/credentials/update) | Обновить ключ провайдера | | DELETE | [`/v1/ai/credentials/:id`](/docs/ai/credentials/delete) | Удалить ключ провайдера | | POST | [`/v1/ai/credentials/:id/test`](/docs/ai/credentials/test) | Проверить ключ провайдера | | GET | [`/v1/ai/credentials/:id/usage`](/docs/ai/credentials/usage) | Статистика использования по ключу | | POST | [`/v1/ai/credentials/:id/fetch-models`](/docs/ai/credentials/fetch-models) | Загрузить каталог моделей у Custom-провайдера | | GET | [`/v1/ai/credentials/:id/models`](/docs/ai/credentials/models-list) | Список моделей, привязанных к ключу | | POST | [`/v1/ai/credentials/:id/models`](/docs/ai/credentials/models-add) | Добавить модель к ключу вручную | | DELETE | [`/v1/ai/credentials/:credId/models/:modelRowId`](/docs/ai/credentials/models-delete) | Удалить модель, привязанную к ключу | --- ## Коды ошибок Эндпоинты делятся на две группы по формату ответа об ошибке: **Сырой OpenAI-формат** (`/v1/chat/completions`, `/v1/models`, `/v1/audio/transcriptions`): ```json { "error": { "message": "...", "type": "invalid_request_error", "code": "ai_model_not_found" } } ``` `type` принимает значения: `invalid_request_error` (4xx), `insufficient_quota` (402), `service_unavailable` (503), `server_error` (5xx). `code` всегда в нижнем регистре. **V1-формат** (`/v1/ai/usage`, `/v1/ai/credentials/*`, `/v1/ai/providers`): ```json { "success": false, "error": { "code": "not_found", "message": "Credential not found" } } ``` | Код | HTTP | Описание | |-----|------|----------| | `scope_missing` | 403 | API-ключу не хватает скоупа `vibe:ai` | | `invalid_request` | 400 | Некорректные параметры запроса | | `no_default_model` | 400 | Модель по умолчанию не настроена — укажите `model` явно | | `invalid_image_payload` | 400 | Некорректный `image_url` в массиве `content` | | `invalid_language` | 400 | Код языка не соответствует `ISO 639` | | `no_file` | 400 | Аудиофайл не передан | | `empty_file` | 400 | Файл в multipart присутствует, но тело — 0 байт (часто причина: `curl -F "file=path"` без `@`) | | `ai_model_not_found` | 404 | Модель не найдена или отключена | | `not_found` | 404 | Сущность (BYOK-ключ, модель) не найдена | | `provider_not_found` | 404 | Провайдер не найден или отключён | | `ai_credentials_not_configured` | 402 | Для модели нет учётных данных провайдера — подключите `BYOK` | | `insufficient_balance` | 402 | Недостаточно средств для платной модели | | `credential_invalid` | 422 | Ключ провайдера не прошёл верификацию | | `already_exists` | 409 | Ключ для этого провайдера уже существует | | `base_url_invalid` | 400 | `baseUrl` Custom-провайдера должен использовать `http` или `https` | | `base_url_private` | 400 | `baseUrl` указывает на приватную сеть или не разрешается в IP-адрес через `DNS` | | `not_custom_provider` | 400 | Ручная регистрация моделей разрешена только для Custom-провайдера | | `provider_list_models_unavailable` | 200 | Custom-провайдер не поддерживает `GET /v1/models` — добавьте модели вручную | | `ai_provider_unavailable` | 502 | Внешний провайдер вернул не-2xx или сетевую ошибку (не таймаут) | | `ai_provider_timeout` | 504 | Апстрим Whisper не ответил за 15 минут | | `model_unavailable` | 503 | Модель отключена и резервной нет | > **Whisper / `/v1/audio/transcriptions`:** окно обработки — до 15 минут. Длинное / шумное аудио может занять несколько минут. Для аудио длиннее ~30 мин стоит делить на части. ### Системные ошибки Применимы к любому эндпоинту Vibe API, включая раздел AI Router: | Код | HTTP | Описание | |-----|------|----------| | `MISSING_API_KEY` | 401 | Не передан заголовок `X-Api-Key` или `Authorization: Bearer` | | `INVALID_API_KEY` | 401 | Ключ не существует или отозван | | `RATE_LIMIT_EXCEEDED` | 429 | Превышен лимит запросов в секунду по API-ключу. Повторите запрос через `X-RateLimit-Reset` секунд | | `INTERNAL_ERROR` | 500 | Внутренняя ошибка платформы — повторите запрос; если повторяется, отправьте [feedback-тикет](/docs/feedback) | Полный список общих ошибок API — [Ошибки](/docs/errors). --- ## Миграция со старых маршрутов Если в коде остались вызовы вида `/v1/ai/chat/completions`, `/v1/ai/models`, `/v1/ai/audio/transcriptions` — они продолжают работать в режиме обратной совместимости. В заголовках ответа приходит: ``` Deprecation: true X-Deprecated-Use: /v1/chat/completions ``` `X-Deprecated-Use` подсказывает канонический путь. Перенесите вызовы на канонические маршруты — это снимает заголовок `Deprecation` и убирает риск удаления старого пути в будущем. | Устаревший путь | Канонический путь | |-----------------|-------------------| | `POST /v1/ai/chat/completions` | [`POST /v1/chat/completions`](/docs/ai/chat/completions) | | `GET /v1/ai/models` | [`GET /v1/models`](/docs/ai/models/list) | | `GET /v1/ai/models/:modelId` | [`GET /v1/models/:modelId`](/docs/ai/models/get) | | `POST /v1/ai/audio/transcriptions` | [`POST /v1/audio/transcriptions`](/docs/ai/audio/transcriptions) | Маршруты `/v1/ai/usage`, `/v1/ai/credentials/*`, `/v1/ai/providers` устаревшего эквивалента не имеют — это канонические пути. --- ## Смотрите также - [Лимиты и оптимизация](/docs/optimization) — общие rate-limits Vibe API - [Управление ключами](/docs/keys-auth) — создание API-ключей и работа со скоупами - [Comментарии таймлайна](/docs/timeline-logs) — запись результатов AI-обработки в карточку CRM - [Бот-платформа](/docs/bots) — отправка ответов AI в чаты Битрикс24 --- # Bot: Chats # Чаты Создавайте групповые чаты от имени бота, настраивайте их, добавляйте и удаляйте участников, назначайте менеджеров и владельца. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Операции - [Создать чат](./chats/create.md) — `POST /v1/bots/:botId/chats` - [Получить чат](./chats/get.md) — `GET /v1/bots/:botId/chats/:dialogId` - [Обновить чат](./chats/update.md) — `PATCH /v1/bots/:botId/chats/:dialogId` - [Покинуть чат](./chats/leave.md) — `POST /v1/bots/:botId/chats/:dialogId/leave` - [Назначить владельца](./chats/set-owner.md) — `POST /v1/bots/:botId/chats/:dialogId/owner` - [Добавить участников](./chats/user-add.md) — `POST /v1/bots/:botId/chats/:dialogId/users` - [Удалить участника](./chats/user-delete.md) — `DELETE /v1/bots/:botId/chats/:dialogId/users` - [Список участников](./chats/user-list.md) — `GET /v1/bots/:botId/chats/:dialogId/users` - [Добавить менеджеров](./chats/manager-add.md) — `POST /v1/bots/:botId/chats/:dialogId/managers` - [Удалить менеджеров](./chats/manager-delete.md) — `DELETE /v1/bots/:botId/chats/:dialogId/managers` --- # Bot: Create ## Создать чат `POST /v1/bots/:botId/chats` Создаёт новый групповой чат от имени бота. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `fields.title` | string | нет | Название чата | | `fields.description` | string | нет | Описание чата | | `fields.color` | string | нет | Цвет чата (16 именованных цветов). Некорректные значения назначаются автоматически | | `fields.avatar` | string | нет | URL аватара чата | | `fields.userIds` | number[] | нет | Массив ID пользователей для добавления | | `fields.ownerId` | number | нет | ID владельца. Если не указан — владельцем становится бот | | `fields.message` | string | нет | Первое сообщение в чате | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "title": "Чат поддержки", "description": "Канал технической поддержки", "userIds": [1, 5, 12], "color": "AZURE" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fields": { "title": "Чат поддержки", "description": "Канал технической поддержки", "userIds": [1, 5, 12], "color": "AZURE" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ fields: { title: 'Чат поддержки', description: 'Канал технической поддержки', userIds: [1, 5, 12], color: 'AZURE', }, }), }) const { success, data } = await res.json() console.log('Chat ID:', data.chatId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ fields: { title: 'Чат поддержки', description: 'Канал технической поддержки', userIds: [1, 5, 12], color: 'AZURE', }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `chat.id` | number | ID созданного чата | | `chat.dialogId` | string | ID диалога (`chatXXX`) | | `chat.name` | string | Название чата | | `chat.owner` | number | ID владельца | | `chat.type` | string | Тип чата | | `chat.color` | string | Цвет чата | | `chat.dateCreate` | string | Дата создания (ISO 8601) | | `chat.permissions` | object | Права в чате | | `users` | array | Массив участников чата | ## Пример ответа ```json { "success": true, "data": { "chat": { "id": 3555, "dialogId": "chat3555", "name": "Чат поддержки", "type": "chat", "owner": 42, "color": "#4ba984", "description": "", "dateCreate": "2026-04-13T17:12:03+03:00", "permissions": { "manageUsersAdd": "member", "manageUsersDelete": "manager", "manageSettings": "owner", "canPost": "member" } }, "users": [ { "id": 42, "name": "Техподдержка", "active": true, "bot": true } ] } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 при создании чата | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Владелец по умолчанию:** если `ownerId` не указан, владельцем чата становится бот. **Некорректные цвета:** если передать несуществующий цвет, Битрикс24 назначит цвет автоматически. ## Смотрите также - [Получить чат](/docs/bots/chats/get) - [Добавить участников](/docs/bots/chats/user-add) - [Сообщения](/docs/bots/messages) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Get ## Получить чат `GET /v1/bots/:botId/chats/:dialogId` Возвращает информацию о чате. Бот должен быть участником чата. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` (path) | number | да | ID бота | | `dialogId` (path) | string | да | ID диалога: `chatXXX` для групповых, числовой ID пользователя для личных | ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456 \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Чат:', data.name) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID чата | | `dialogId` | string | ID диалога (`chatXXX`) | | `type` | string | Тип чата | | `name` | string | Название чата | | `description` | string | Описание | | `owner` | number | ID владельца | | `avatar` | string | URL аватара | | `color` | string | Цвет чата | | `entityType` | string | Тип связанной сущности | | `entityId` | string | ID связанной сущности | | `dateCreate` | string | Дата создания (ISO 8601) | ## Пример ответа ```json { "success": true, "data": { "id": 456, "dialogId": "chat456", "type": "chat", "name": "Чат поддержки", "description": "Канал технической поддержки", "owner": 42, "avatar": "", "color": "AZURE", "entityType": "", "entityId": "", "dateCreate": "2026-03-31T10:30:00+03:00" } } ``` ## Пример ответа при ошибке 502 — бот не является участником чата: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Access denied" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (бот не участник чата) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить чат](/docs/bots/chats/update) - [Список участников](/docs/bots/chats/user-list) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Leave ## Покинуть чат `POST /v1/bots/:botId/chats/:dialogId/leave` Бот покидает групповой чат. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` (path) | number | да | ID бота | | `dialogId` (path) | string | да | ID диалога (`chatXXX`) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/leave \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/leave \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/leave', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/leave', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном выходе | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать чат](/docs/bots/chats/create) - [Удалить участника](/docs/bots/chats/user-delete) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Manager Add ## Добавить менеджеров `POST /v1/bots/:botId/chats/:dialogId/managers` Назначает пользователей менеджерами чата. Менеджеры имеют расширенные права: управление участниками и настройками. Бот должен быть владельцем чата. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `userIds` | number[] | да | Массив ID пользователей для назначения менеджерами | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userIds": [5, 12] }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "userIds": [5, 12] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userIds: [5, 12] }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userIds: [5, 12] }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном назначении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 502 — бот не является владельцем чата: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "You are not the owner of this chat" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (бот не владелец чата) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только владелец:** добавить менеджеров может только владелец чата, не менеджер и не обычный участник. **Аддитивная операция:** новые менеджеры добавляются к существующим, а не заменяют их. **Пользователи не в чате игнорируются:** если в `userIds` есть ID пользователей, не являющихся участниками чата, они пропускаются без ошибки. ## Смотрите также - [Удалить менеджеров](/docs/bots/chats/manager-delete) - [Список участников](/docs/bots/chats/user-list) - [Назначить владельца](/docs/bots/chats/set-owner) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Manager Delete ## Удалить менеджеров `DELETE /v1/bots/:botId/chats/:dialogId/managers` Снимает роль менеджера с указанных пользователей. Бот должен быть владельцем чата. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `userIds` | number[] | да | Массив ID пользователей для снятия роли менеджера | ## Примеры ### curl — личный ключ ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userIds": [5] }' ``` ### curl — OAuth-приложение ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "userIds": [5] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userIds: [5] }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/managers', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userIds: [5] }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном удалении роли | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 502 — бот не является владельцем чата: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "You are not the owner of this chat" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (бот не владелец чата) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только владелец:** снять роль менеджера может только владелец чата. ## Смотрите также - [Добавить менеджеров](/docs/bots/chats/manager-add) - [Список участников](/docs/bots/chats/user-list) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Set Owner ## Назначить владельца `POST /v1/bots/:botId/chats/:dialogId/owner` Передаёт права владельца чата другому пользователю. Бот должен быть текущим владельцем чата. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `userId` | number | да | ID нового владельца | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/owner \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userId": 5 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/owner \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "userId": 5 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/owner', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 5 }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/owner', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 5 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешной смене владельца | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 502 — бот не является владельцем чата: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "You are not the owner of this chat" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (бот не владелец чата) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только владелец:** передать права может только текущий владелец чата. Менеджеры и обычные участники не могут. ## Смотрите также - [Добавить менеджеров](/docs/bots/chats/manager-add) - [Получить чат](/docs/bots/chats/get) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Update ## Обновить чат `PATCH /v1/bots/:botId/chats/:dialogId` Обновляет настройки чата. Бот должен быть участником чата. Обновляются только переданные поля. > **Две формы тела запроса — обе корректны.** Платформа принимает плоскую запись (`{ title, description, ... }`) и формат Битрикс24 с обёрткой `fields`. Если в теле есть `fields`, запрос передаётся в Битрикс24 без изменений. Иначе известные поля верхнего уровня автоматически разворачиваются в `fields.*`. ## Поля запроса (body) | Параметр (плоский) | Параметр (формат Битрикс24) | Тип | Описание | |---|---|-----|---------| | `title` | `fields.title` | string | Новое название чата | | `description` | `fields.description` | string | Новое описание | | `color` | `fields.color` | string | Новый цвет | | `avatar` | `fields.avatar` | string | Новый URL аватара | ## Примеры ### curl — личный ключ ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "title": "Новое название чата", "description": "Обновлённое описание" } }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fields": { "title": "Новое название чата", "description": "Обновлённое описание" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ fields: { title: 'Новое название чата', description: 'Обновлённое описание', }, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ fields: { title: 'Новое название чата', description: 'Обновлённое описание', }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном обновлении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 403 — бот принадлежит другому ключу: ```json { "success": false, "error": { "code": "BOT_ACCESS_DENIED", "message": "This bot belongs to a different API key" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить чат](/docs/bots/chats/get) - [Создать чат](/docs/bots/chats/create) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: User Add ## Добавить участников `POST /v1/bots/:botId/chats/:dialogId/users` Добавляет пользователей в чат. Несуществующие или неактивные пользователи игнорируются без ошибки. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `userIds` | number[] | да | Массив ID пользователей для добавления | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userIds": [5, 12] }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "userIds": [5, 12] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userIds: [5, 12] }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userIds: [5, 12] }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном добавлении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 403 — бот принадлежит другому ключу: ```json { "success": false, "error": { "code": "BOT_ACCESS_DENIED", "message": "This bot belongs to a different API key" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Несуществующие пользователи игнорируются:** если в массиве `userIds` есть несуществующие или неактивные ID, они пропускаются без ошибки. ## Смотрите также - [Удалить участника](/docs/bots/chats/user-delete) - [Список участников](/docs/bots/chats/user-list) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: User Delete ## Удалить участника `DELETE /v1/bots/:botId/chats/:dialogId/users` Удаляет пользователя из чата. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `userId` | number | да | ID пользователя для удаления | ## Примеры ### curl — личный ключ ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userId": 12 }' ``` ### curl — OAuth-приложение ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "userId": 12 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 12 }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 12 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном удалении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Идемпотентность:** метод возвращает `true` даже если пользователь уже не в чате. **Один пользователь:** эндпоинт принимает `userId` (число), а не массив. Для удаления нескольких участников вызывайте эндпоинт для каждого. ## Смотрите также - [Добавить участников](/docs/bots/chats/user-add) - [Список участников](/docs/bots/chats/user-list) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: User List ## Список участников `GET /v1/bots/:botId/chats/:dialogId/users` Возвращает список участников чата. Бот должен быть участником чата. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `botId` (path) | number | да | — | ID бота | | `dialogId` (path) | string | да | — | ID диалога (`chatXXX`) | | `limit` (query) | number | нет | `50` | Количество записей (1-200) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users?limit=100" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users?limit=100" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users?limit=100', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Участников:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/users?limit=100', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив участников | | `data[].id` | number | ID пользователя | | `data[].name` | string | Полное имя | | `data[].firstName` | string | Имя | | `data[].lastName` | string | Фамилия | | `data[].workPosition` | string | Должность | | `data[].color` | string | Цвет аватара | | `data[].avatar` | string | URL аватара | | `data[].gender` | string | Пол | | `data[].active` | boolean | Активен ли аккаунт | | `data[].bot` | boolean | Является ли ботом | | `data[].status` | string | Статус пользователя | ## Пример ответа ```json { "success": true, "data": [ { "id": 1, "name": "Иван Петров", "firstName": "Иван", "lastName": "Петров", "workPosition": "Менеджер", "color": "AZURE", "avatar": "", "gender": "M", "active": true, "bot": false, "status": "online" }, { "id": 42, "name": "Техподдержка", "firstName": "Техподдержка", "lastName": "", "workPosition": "Помощник", "color": "AZURE", "avatar": "", "gender": "", "active": true, "bot": true, "status": "online" } ] } ``` ## Пример ответа при ошибке 502 — бот не является участником чата: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Access denied" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Добавить участников](/docs/bots/chats/user-add) - [Удалить участника](/docs/bots/chats/user-delete) - [Добавить менеджеров](/docs/bots/chats/manager-add) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Commands # Команды Регистрируйте slash-команды бота, обновляйте и удаляйте их, отвечайте на вызовы. Пользователи вызывают команды через `/` в чате. Команды также срабатывают через поле `COMMAND` в кнопках [клавиатуры](/docs/bots/messages/keyboard) — оба способа генерируют одно событие `ONIMBOTV2COMMANDADD`. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Операции - [Зарегистрировать команду](./commands/register.md) — `POST /v1/bots/:botId/commands` - [Список команд](./commands/list.md) — `GET /v1/bots/:botId/commands` - [Обновить команду](./commands/update.md) — `PATCH /v1/bots/:botId/commands/:commandId` - [Удалить команду](./commands/delete.md) — `DELETE /v1/bots/:botId/commands/:commandId` - [Ответить на команду](./commands/answer.md) — `POST /v1/bots/:botId/commands/:commandId/answer` ## Возможная задержка между записью и чтением Чтение списка команд (`GET /v1/bots/:botId/commands`) не кешируется на стороне Вайбкода. Однако сам Битрикс24 кеширует список: после регистрации, обновления или удаления команды `GET` может несколько секунд (иногда минут) возвращать прежние значения. Подробности — в [Список команд](./commands/list.md). --- # Bot: Answer ## Ответить на команду `POST /v1/bots/:botId/commands/:commandId/answer` Отправляет ответ на вызов slash-команды. Вызывайте из обработчика события `ONIMBOTV2COMMANDADD`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `messageId` | number | да | ID сообщения с вызовом команды (из события) | | `dialogId` | string | да | ID диалога. Для группового чата — `chat{chatId}`, для личного — `{userId}`. Берите из события `ONIMBOTV2COMMANDADD` (`PARAMS.DIALOG_ID`) | | `fields` | object | нет | Поля ответного сообщения | | `fields.message` | string | нет | Текст ответа. Поддерживает [BB-коды](/docs/bots/messages/formatting) | | `fields.keyboard` | array | нет | Интерактивная [клавиатура](/docs/bots/messages/keyboard) | | `fields.attach` | array/object | нет | [ATTACH-блоки](/docs/bots/messages/attach) | | `fields.system` | boolean | нет | Системное сообщение. По умолчанию `false` | | `fields.urlPreview` | boolean | нет | Показывать превью ссылок. По умолчанию `true` | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/commands/7/answer \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "messageId": 1510, "dialogId": "chat123", "fields": { "message": "[b]Справка по задачам[/b]\n\nДоступные действия:\n[SEND=/status]Проверить статус[/SEND]\n[SEND=/create]Создать задачу[/SEND]" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/commands/7/answer \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messageId": 1510, "dialogId": "chat123", "fields": { "message": "[b]Справка по задачам[/b]\n\nДоступные действия:\n[SEND=/status]Проверить статус[/SEND]\n[SEND=/create]Создать задачу[/SEND]" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands/7/answer', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ messageId: 1510, dialogId: 'chat123', fields: { message: '[b]Справка по задачам[/b]\n\nДоступные действия:\n[SEND=/status]Проверить статус[/SEND]', }, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands/7/answer', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ messageId: 1510, dialogId: 'chat123', fields: { message: '[b]Справка по задачам[/b]\n\nДоступные действия:\n[SEND=/status]Проверить статус[/SEND]', }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешной отправке ответа | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Не требует членства в чате:** бот может ответить на команду даже если не является участником чата. Доступ предоставляется временно через связку `messageId` + `commandId`. Если бот не участник — ответ отправляется как системное сообщение с именем бота. ## Смотрите также - [Зарегистрировать команду](/docs/bots/commands/register) - [События](/docs/bots/events) - [Форматирование текста](/docs/bots/messages/formatting) - [Клавиатура](/docs/bots/messages/keyboard) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Delete ## Удалить команду `DELETE /v1/bots/:botId/commands/:commandId` Удаляет зарегистрированную команду бота. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` (path) | number | да | ID бота | | `commandId` (path) | number | да | ID команды | ## Примеры ### curl — личный ключ ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/commands/7 \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/commands/7 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands/7', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands/7', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном удалении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (команда не найдена) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Зарегистрировать команду](/docs/bots/commands/register) - [Список команд](/docs/bots/commands/list) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: List ## Список команд `GET /v1/bots/:botId/commands` Возвращает все зарегистрированные команды бота. ## ⚠️ Возможная задержка после мутаций Вайбкод не кеширует этот ответ. Однако сам Битрикс24 **держит свой кеш** списка команд и не всегда обновляет его сразу после регистрации, обновления или удаления команды. В течение нескольких секунд (иногда минут) после успешной мутации `GET` может возвращать: - удалённые команды (их id ещё видны в списке) - старые значения `title` / `params` / `common` / `hidden` для только что обновлённой команды - отсутствие только что зарегистрированной команды. При этом сама команда уже **действует** на стороне Битрикс24 (на неё реагирует событие `ONIMBOTV2COMMANDADD`, бот её обрабатывает) — расхождение видно только в этом `GET`. ### Что делать - **Не использовать `GET /commands` как единственный источник правды сразу после мутации.** Опирайтесь на ответ самой мутации: `POST` возвращает данные с новым id, `PATCH` — обновлённую команду, `DELETE` — признак успеха. - **Если нужна синхронизация со списком** (например для сверки интерфейса с реальным состоянием), запросите `GET` повторно через 10–30 секунд. - **Если расхождение сохраняется дольше минуты**, это уже не штатная задержка. Приложите к обращению в поддержку `botId`, время мутации и то, что именно ожидалось и что получено. Принудительно сбросить этот кеш на стороне Битрикс24 нельзя. Если список не обновился — повторите `GET` через несколько секунд. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` (path) | number | да | ID бота | ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/commands \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/commands \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Команды:', data) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив команд | | `data[].id` | number | ID команды | | `data[].command` | string | Текст команды | | `data[].title` | string | Заголовок (локализованный) | | `data[].params` | string | Описание параметров (локализованное) | | `data[].common` | boolean | Доступна во всех чатах | | `data[].hidden` | boolean | Скрыта из списка | | `data[].extranetSupport` | boolean | Доступна экстранет-пользователям | ## Пример ответа ```json { "success": true, "data": [ { "id": 7, "command": "help", "title": "Помощь", "params": "тема", "common": true, "hidden": false, "extranetSupport": false }, { "id": 8, "command": "status", "title": "Статус", "params": "", "common": false, "hidden": false, "extranetSupport": false } ] } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Зарегистрировать команду](/docs/bots/commands/register) - [Обновить команду](/docs/bots/commands/update) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Register ## Зарегистрировать команду `POST /v1/bots/:botId/commands` Регистрирует новую slash-команду бота. Вайбкод принимает плоский формат и автоматически оборачивает в `fields` для Битрикс24. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `command` | string | да | — | Текст команды без `/` (например, `help`) | | `title` | string/object | нет | — | Заголовок. Строка или мультиязычный объект `{ "ru": "Помощь", "en": "Help" }` | | `params` | string/object | нет | — | Описание параметров. Строка или объект `{ "ru": "тема", "en": "topic" }` | | `common` | string | нет | `"N"` | `"Y"` — доступна во всех чатах, `"N"` — только в личном диалоге с ботом и чатах с ботом | | `hidden` | string | нет | `"N"` | `"Y"` — скрыть из списка команд | | `extranetSupport` | string | нет | `"N"` | `"Y"` — доступна для экстранет-пользователей | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/commands \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "command": "help", "title": { "ru": "Помощь", "en": "Help" }, "params": { "ru": "тема", "en": "topic" }, "common": "Y" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/commands \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "command": "help", "title": { "ru": "Помощь", "en": "Help" }, "params": { "ru": "тема", "en": "topic" }, "common": "Y" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ command: 'help', title: { ru: 'Помощь', en: 'Help' }, params: { ru: 'тема', en: 'topic' }, common: 'Y', }), }) const { success, data } = await res.json() console.log('Command ID:', data.commandId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ command: 'help', title: { ru: 'Помощь', en: 'Help' }, params: { ru: 'тема', en: 'topic' }, common: 'Y', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `command.id` | number | ID зарегистрированной команды | | `command.botId` | number | ID бота | | `command.command` | string | Текст команды (с `/`) | | `command.common` | boolean | Доступна во всех чатах | | `command.hidden` | boolean | Скрыта из списка | | `command.extranetSupport` | boolean | Доступна экстранет-пользователям | ## Пример ответа ```json { "success": true, "data": { "command": { "id": 117, "botId": 1327, "command": "/help", "common": true, "hidden": false, "extranetSupport": false } } } ``` ## Пример ответа при ошибке 502 — ошибка Битрикс24: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Command 'help' already registered" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Идемпотентность:** повторный вызов с тем же `command` для того же бота возвращает существующую команду без изменений. Для обновления используйте `PATCH`. **Мультиязычность:** `title` и `params` принимают как строку, так и объект с языковыми ключами (`ru`, `en`, `de` и т.д.). **Событие:** при вызове команды пользователем срабатывает событие `ONIMBOTV2COMMANDADD`. ## Смотрите также - [Список команд](/docs/bots/commands/list) - [Ответить на команду](/docs/bots/commands/answer) - [События](/docs/bots/events) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Update ## Обновить команду `PATCH /v1/bots/:botId/commands/:commandId` Обновляет параметры существующей команды. Вайбкод принимает плоский формат и автоматически оборачивает в `fields` для Битрикс24. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `command` | string | Новый текст команды без `/` | | `title` | string/object | Новый заголовок. Строка или `{ "ru": "...", "en": "..." }`. Передача `null` для ключа удаляет перевод: `{ "en": null }` | | `params` | string/object | Новое описание параметров. Строка или объект | | `common` | string | `"Y"` / `"N"` | | `hidden` | string | `"Y"` / `"N"` | | `extranetSupport` | string | `"Y"` / `"N"` | ## Примеры ### curl — личный ключ ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42/commands/7 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": { "ru": "Обновлённая справка", "en": "Updated help" }, "common": "Y" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42/commands/7 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": { "ru": "Обновлённая справка", "en": "Updated help" }, "common": "Y" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands/7', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: { ru: 'Обновлённая справка', en: 'Updated help' }, common: 'Y', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/commands/7', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: { ru: 'Обновлённая справка', en: 'Updated help' }, common: 'Y', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.command.id` | number | ID команды | | `data.command.botId` | number | ID бота | | `data.command.command` | string | Имя команды с префиксом `/` | | `data.command.common` | boolean | Доступна во всех чатах, а не только в диалоге с ботом | | `data.command.hidden` | boolean | Скрыта из подсказки автодополнения | | `data.command.extranetSupport` | boolean | Доступна экстранет-пользователям | ## Пример ответа ```json { "success": true, "data": { "command": { "id": 189, "botId": 42, "command": "/help", "common": true, "hidden": false, "extranetSupport": false } } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Удаление перевода:** передайте `null` для языкового ключа: `{ "title": { "en": null } }` — удалит английский перевод, оставив остальные. **Строковые флаги:** `common`, `hidden`, `extranetSupport` принимают строки `"Y"` / `"N"` (не boolean). ## Смотрите также - [Зарегистрировать команду](/docs/bots/commands/register) - [Удалить команду](/docs/bots/commands/delete) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Events # События Получайте входящие события бота методом опроса и обрабатывайте их: новые сообщения, команды, реакции и добавление бота в чат. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Операции - [Получить события опросом](./events/polling.md) — `GET /v1/bots/:botId/events` - [Bot-события (ONIMBOTV2*)](./events/bot-events.md) — `GET ONIMBOTV2*` - [User-события (ONIMV2*)](./events/user-events.md) — `GET ONIMV2*` --- # Bot: Bot Events ## Bot-события (ONIMBOTV2*) Приходят автоматически для всех ботов с `eventMode: "fetch"`. Получаются через [polling](/docs/bots/events/polling). Каждое событие имеет структуру: ```json { "eventId": 29, "type": "ONIMBOTV2JOINCHAT", "date": "2026-04-13T17:12:00+03:00", "data": { "dialogId": "chat3553", "bot": { ... }, "chat": { ... }, "user": { ... }, "language": "ru" } } ``` | Поле | Тип | Описание | |------|-----|---------| | `eventId` | number | ID события — передайте как `offset` в следующем запросе polling | | `type` | string | Код типа события | | `date` | string | Дата и время (ISO 8601) | | `data` | object | Данные события (структура зависит от типа) | ## Список событий | Тип | Описание | |-----|---------| | [ONIMBOTV2MESSAGEADD](#onimbotv2messageadd) | Новое сообщение боту | | [ONIMBOTV2MESSAGEUPDATE](#onimbotv2messageupdate) | Сообщение отредактировано | | [ONIMBOTV2MESSAGEDELETE](#onimbotv2messagedelete) | Сообщение удалено | | [ONIMBOTV2JOINCHAT](#onimbotv2joinchat) | Бот добавлен в чат | | [ONIMBOTV2COMMANDADD](#onimbotv2commandadd) | Вызвана slash-команда | | [ONIMBOTV2REACTIONCHANGE](#onimbotv2reactionchange) | Реакция на сообщение бота | | [ONIMBOTV2DELETE](#onimbotv2delete) | Бот удалён с портала | | [ONIMBOTV2CONTEXTGET](#onimbotv2contextget) | Запрошен контекст диалога | --- ## Как обрабатывать события Цикл опроса описан на странице [Получить события](/docs/bots/events/polling). Получив массив `events`, маршрутизируйте каждое событие по полю `type`. Отвечать боту нужно в диалог `event.data.dialogId` (для групп — `chatXXX`, для личных — id пользователя, тот же, что `event.data.chat.dialogId`). **Перед обработкой сообщения отфильтруйте лишнее:** - `message.isSystem === true` — служебное сообщение (вход в чат, смена настроек). Пропускайте. - `message.authorId === event.data.bot.id` — собственное сообщение бота. Боты типа `personal` и `supervisor` получают все сообщения чата, включая свои ответы, — без этой проверки обработчик зациклится. Бот типа `bot` получает только личные сообщения и `@упоминания` и свои сообщения обратно не получает, но проверка не повредит. **Диспетчер событий:** ```javascript async function handleEvent(event) { const { type, data } = event const dialogId = data.dialogId switch (type) { case 'ONIMBOTV2MESSAGEADD': { const m = data.message if (m.isSystem || m.authorId === data.bot.id) return // пропустить служебные и свои // Ответить: POST /v1/bots/:botId/messages с { dialogId, fields: { message } } break } case 'ONIMBOTV2COMMANDADD': // Ответить на команду: POST /v1/bots/:botId/commands/:commandId/answer // commandId = data.command.id, messageId = data.message.id break case 'ONIMBOTV2JOINCHAT': // Бот добавлен в чат — можно отправить приветствие в dialogId break case 'ONIMBOTV2REACTIONCHANGE': // data.reaction (код реакции) + data.action ('add' | 'delete') break case 'ONIMBOTV2CONTEXTGET': // Диалог открыт по ссылке с контекстом — данные в data.context break case 'ONIMBOTV2MESSAGEUPDATE': // Сообщение отредактировано — data.message с новым текстом break case 'ONIMBOTV2MESSAGEDELETE': // Сообщение удалено — data.messageId (число) break case 'ONIMBOTV2DELETE': // Бот удалён с портала — освободите ресурсы, прекратите опрос break } } ``` Ответ в диалог — всегда [`POST /v1/bots/:botId/messages`](/docs/bots/messages/send) с `dialogId = event.data.dialogId`. --- ## ONIMBOTV2MESSAGEADD Новое сообщение боту (личное или @упоминание в групповом чате). ```json { "eventId": 35, "type": "ONIMBOTV2MESSAGEADD", "date": "2026-04-13T17:15:00+03:00", "data": { "dialogId": "chat123", "bot": { "id": 42, "code": "support_bot", "type": "bot", "isHidden": false, "isReactionsEnabled": true, "eventMode": "fetch" }, "message": { "id": 1501, "chatId": 123, "authorId": 1, "date": "2026-04-13T17:15:00+03:00", "text": "Привет, бот! Подскажи по задаче #42", "isSystem": false, "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "forward": null, "params": { "FILE_ID": ["15423"] }, "viewedByOthers": false }, "chat": { "id": 123, "dialogId": "chat123", "type": "chat", "name": "Рабочий чат", "owner": 1, "color": "#64a513", "entityType": "", "entityId": "", "permissions": { "manageUsersAdd": "member", "manageUsersDelete": "manager", "manageSettings": "owner", "manageMessages": "member", "canPost": "member" } }, "user": { "id": 1, "active": true, "name": "Иван Петров", "firstName": "Иван", "lastName": "Петров", "workPosition": "Менеджер", "color": "#1eb4aa", "gender": "M", "extranet": false, "bot": false, "status": "online", "departments": [1, 5], "type": "employee" }, "language": "ru" } } ``` **Поля data:** | Поле | Тип | Описание | |------|-----|---------| | `dialogId` | string | ID диалога для ответа (`chatXXX` или id пользователя) | | `message.id` | number | ID сообщения — для цитирования через [replyId](/docs/bots/messages/send) | | `message.text` | string | Текст сообщения | | `message.authorId` | number | ID автора. Сравните с `bot.id`, чтобы пропустить собственные сообщения | | `message.isSystem` | boolean | `true` для служебных сообщений — пропускайте их | | `message.params.FILE_ID` | string[] | ID прикреплённых файлов. Скачать: [GET /files/:fileId](/docs/bots/files/download) | | `message.forward` | object \| null | Объект пересланного сообщения или `null` | | `bot` | object | Объект бота (`id`, `code`, `type`, `eventMode`) | | `chat.entityType` | string | Тип привязки: `LINES` (открытая линия), `CRM`, пустая строка (обычный чат) | | `chat.permissions` | object | Права в чате (`manageUsersAdd`, `manageSettings` и др.) | | `user` | object | Автор сообщения (`id`, `name`, `departments`, `status` и др.) | | `language` | string | Язык интерфейса пользователя | ### Обработка голосовых и файловых сообщений Голосовые сообщения и файлы-вложения попадают в `ONIMBOTV2MESSAGEADD` со следующими особенностями: - У голосового сообщения `message.text` пуст или содержит только пояснение (`"Голосовое сообщение"`). - Массив `message.params.FILE_ID` — **авторитативный источник** информации о вложениях, появляется сразу в теле события. - `GET /v1/chats/:dialogId/messages` **не гарантирует**, что то же сообщение вернётся сразу — disk-индекс Битрикс24 иногда догоняет событие с задержкой в 1–2 секунды. Не ждите его через polling. **Корректный паттерн:** ```javascript const FILE_FETCH_TIMEOUT_MS = 10_000 async function handleMessageAdd(event) { const { message } = event.data const fileIds = message.params?.FILE_ID ?? [] // Обычное текстовое сообщение if (fileIds.length === 0) { return handleText(message) } // Есть вложение — читаем метаданные через disk API for (const fileId of fileIds) { let meta = null for (let attempt = 0; attempt < 2; attempt++) { // encodeURIComponent защищает от future-regressions если fileId когда-то // окажется не чисто-числовым (например, B24 поменяет формат ID или // этот паттерн расширят на user-provided ID из другого источника). const url = `https://vibecode.bitrix24.tech/v1/files/${encodeURIComponent(fileId)}` // AbortController защищает handler от зависания, если B24 или наш proxy // отвечают медленно. Без timeout одно «залипшее» событие может заблокировать poll-loop. const controller = new AbortController() const timer = setTimeout(() => controller.abort(), FILE_FETCH_TIMEOUT_MS) let res try { res = await fetch(url, { headers: { 'X-Api-Key': process.env.VIBE_KEY }, signal: controller.signal, }) } catch (err) { clearTimeout(timer) if (err.name === 'AbortError') { console.warn(`File ${fileId} fetch timed out after ${FILE_FETCH_TIMEOUT_MS}ms, retrying`) continue } throw err } clearTimeout(timer) if (res.ok) { meta = await res.json() break } // 403 BITRIX_ACCESS_DENIED или 404 сразу после события — типично: // disk ещё не проиндексировал файл. Ждём 1.5 секунды и ретраим. if (res.status === 403 || res.status === 404) { await sleep(1500) continue } throw new Error(`Failed to read file ${fileId}: HTTP ${res.status}`) } if (!meta) { // Файл всё ещё недоступен — логируем и продолжаем без attachment console.warn(`File ${fileId} not available after retry, skipping`) continue } await processAttachment(meta.data) } } const sleep = (ms) => new Promise((r) => setTimeout(r, ms)) ``` **Требуемые скоупы у API-ключа:** `imbot` (получение событий) + **`disk`** (вызов `/v1/files/:id`). Без скоупа `disk` запрос `GET /v1/files/:id` возвращает `SCOPE_DENIED` 403. Скоуп `im` нужен дополнительно, если вы вызываете методы `im.*` напрямую (для этого паттерна не требуется). **Модель прав в Битрикс24:** - Бот-пользователь (от чьего имени работает API-ключ) должен быть **участником чата**, в котором пришло сообщение. Для групповых ботов участие добавляется автоматически при установке. Для ботов типа `personal` и `supervisor` требуется настройка в интерфейсе портала (см. [Зарегистрировать бота](/docs/bots/management/create)). - Файл-вложение доступно только в пределах срока хранения файлов в Битрикс24, который зависит от тарифа портала. После удаления файла запрос возвращает `BITRIX_ACCESS_DENIED` даже с корректным скоупом. - Скоуп `disk` у ключа **необходим, но недостаточен** — он открывает эндпоинт `/v1/files/:id`, но права на конкретный файл Битрикс24 проверяет отдельно по участию бота в чате. **Расшифровка голосового сообщения.** Получив `fileId` из `message.params.FILE_ID`, скачайте байты файла и отправьте их на распознавание. Полная цепочка: событие → `fileId` → скачать содержимое → расшифровать. ```javascript async function transcribeVoice(fileId) { // 1. Скачать байты файла (бинарный ответ) const fileRes = await fetch( `https://vibecode.bitrix24.tech/v1/files/${encodeURIComponent(fileId)}/download`, { headers: { 'X-Api-Key': process.env.VIBE_KEY } }, ) const audio = await fileRes.blob() // 2. Отправить аудио на расшифровку (Whisper, бесплатно; скоуп `vibe:ai`) const form = new FormData() form.append('file', audio, 'voice.ogg') const trRes = await fetch('https://vibecode.bitrix24.tech/v1/audio/transcriptions', { method: 'POST', headers: { 'X-Api-Key': process.env.VIBE_KEY }, body: form, }) const { text } = await trRes.json() return text } ``` Контракт распознавания (форматы, лимиты, коды ошибок `empty_file` / `AI_PROVIDER_TIMEOUT`) — [Расшифровка аудио](/docs/ai/audio). Скоуп `vibe:ai` добавляется к ключу автоматически. --- ## ONIMBOTV2MESSAGEUPDATE Сообщение отредактировано. Структура `data` совпадает с `ONIMBOTV2MESSAGEADD`: объект `message` содержит обновлённый `text` и те же поля `id`, `authorId`, `params.FILE_ID`. Находите исходное сообщение по `message.id`. --- ## ONIMBOTV2MESSAGEDELETE Сообщение удалено. Вместо объекта `message` содержит `messageId` (число). ```json { "eventId": 37, "type": "ONIMBOTV2MESSAGEDELETE", "date": "2026-04-13T17:16:00+03:00", "data": { "dialogId": "chat123", "bot": { "id": 42, "code": "support_bot", "type": "bot" }, "messageId": 1501, "chat": { "id": 123, "dialogId": "chat123", "type": "chat", "name": "Рабочий чат" }, "user": { "id": 1, "name": "Иван Петров" } } } ``` --- ## ONIMBOTV2JOINCHAT Бот добавлен в чат. `user` — кто добавил бота. ```json { "eventId": 29, "type": "ONIMBOTV2JOINCHAT", "date": "2026-04-13T17:12:00+03:00", "data": { "dialogId": "chat3553", "bot": { "id": 42, "code": "support_bot", "type": "bot", "eventMode": "fetch" }, "chat": { "id": 3553, "dialogId": "chat3553", "type": "chat", "name": "Отдел продаж", "owner": 42, "color": "#64a513", "permissions": { "manageUsersAdd": "member", "manageSettings": "owner" } }, "user": { "id": 3, "name": "Мария Сидорова", "workPosition": "Руководитель" }, "language": "ru" } } ``` --- ## ONIMBOTV2COMMANDADD Вызвана slash-команда бота. Содержит дополнительный объект `command`. ```json { "eventId": 40, "type": "ONIMBOTV2COMMANDADD", "date": "2026-04-13T17:18:00+03:00", "data": { "dialogId": "chat123", "bot": { "id": 42, "code": "support_bot", "type": "bot" }, "message": { "id": 1510, "text": "/help задачи" }, "chat": { "id": 123, "dialogId": "chat123" }, "user": { "id": 1, "name": "Иван Петров" }, "command": { "id": 7, "command": "help", "params": "задачи", "context": "textarea" } } } ``` **Поля command:** | Поле | Описание | |------|---------| | `id` | ID команды | | `command` | Текст команды без `/` | | `params` | Параметры, введённые после команды | | `context` | Откуда вызвана: `textarea` (поле ввода), `keyboard` (кнопка), `menu` (контекстное меню) | Для ответа используйте [POST /commands/:commandId/answer](/docs/bots/commands/answer) с `messageId` из `message.id`. --- ## ONIMBOTV2REACTIONCHANGE Реакция добавлена или удалена на сообщение бота. ```json { "eventId": 42, "type": "ONIMBOTV2REACTIONCHANGE", "date": "2026-04-13T17:19:00+03:00", "data": { "dialogId": "chat123", "bot": { "id": 42, "code": "support_bot", "type": "bot" }, "reaction": "like", "action": "add", "message": { "id": 1502, "text": "Привет! Чем могу помочь?" }, "chat": { "id": 123, "dialogId": "chat123" }, "user": { "id": 1, "name": "Иван Петров" } } } ``` | Поле | Описание | |------|---------| | `reaction` | Код реакции (см. [коды реакций](/docs/bots/ui/reactions)) | | `action` | `"add"` — добавлена, `"delete"` — удалена | --- ## ONIMBOTV2DELETE Бот удалён с портала. Содержит только объект `bot` — без `chat` и `user`. ```json { "eventId": 50, "type": "ONIMBOTV2DELETE", "date": "2026-04-13T17:25:00+03:00", "data": { "bot": { "id": 42, "code": "support_bot", "type": "bot" } } } ``` --- ## ONIMBOTV2CONTEXTGET Пользователь открыл диалог с ботом по ссылке, в которую вложен контекст. В поле `context` приходят произвольные данные из этой ссылки — бот может сразу ответить с их учётом. ```json { "eventId": 45, "type": "ONIMBOTV2CONTEXTGET", "date": "2026-04-13T17:20:00+03:00", "data": { "dialogId": "5", "bot": { "id": 42, "code": "support_bot", "type": "bot" }, "context": { "action": "openTask", "taskId": "456" }, "chat": { "id": 789, "dialogId": "5", "type": "private" }, "user": { "id": 5, "name": "Алексей Козлов" } } } ``` | Поле | Описание | |------|---------| | `context` | Произвольные данные из ссылки, по которой открыли диалог. Приходит строкой или объектом. Битрикс24 передаёт значения строками — число `456` придёт как `"456"` | Событие приходит для личного диалога с ботом, поэтому `dialogId` — это id пользователя, открывшего ссылку. **Как боту передают контекст.** Диалог с ботом открывают по ссылке с параметром `BOT_CONTEXT` — в него кладут произвольный JSON в URL-кодировке: ``` https:///online/?IM_DIALOG=&BOT_CONTEXT= ``` `` — домен портала, `` — идентификатор диалога с ботом. Значение `BOT_CONTEXT` приходит боту в поле `context` этого события без изменений. --- ## Общие объекты в событиях Все события (кроме `ONIMBOTV2DELETE`) содержат объекты `bot`, `chat`, `user` с одинаковой структурой. Полные объекты показаны в примере `ONIMBOTV2MESSAGEADD` выше. В сокращённых примерах показаны только ключевые поля. ## Смотрите также - [Получить события](/docs/bots/events/polling) - [User-события](/docs/bots/events/user-events) - [Отправить сообщение](/docs/bots/messages/send) - [Ответить на команду](/docs/bots/commands/answer) - [Коды реакций](/docs/bots/ui/reactions) - [Бот-платформа](/docs/bots) --- # Bot: Polling ## Получить события (polling) `GET /v1/bots/:botId/events` Основной механизм получения входящих сообщений и команд. Бот периодически запрашивает новые события. Вайбкод хранит `lastOffset` в базе данных — при первом запросе без `offset` используется сохранённое значение. Это позволяет боту продолжить с места остановки после перезапуска. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `botId` (path) | number | да | — | ID бота | | `offset` (query) | number | нет | из БД | Начальная позиция. Без параметра — сохранённое в БД значение. `offset=0` — начать с начала | | `limit` (query) | number | нет | `100` | Максимальное количество событий (1-1000) | | `withUserEvents` (query) | boolean | нет | `false` | Включить [user-события](/docs/bots/events/user-events) (ONIMV2*). Требует предварительной подписки — порядок настройки описан на странице User-события. Без подписки запрос вернёт `502 BITRIX_ERROR: User is not subscribed` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('События:', data.events.length, 'Ещё:', data.hasMore) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `events` | array | Массив событий (см. [типы событий](/docs/bots/events/bot-events)) | | `events[].eventId` | number | ID события — передайте как `offset` в следующем запросе | | `events[].type` | string | Код события (`ONIMBOTV2MESSAGEADD`, `ONIMBOTV2COMMANDADD` и т.д.) | | `events[].date` | string | Дата и время события (ISO 8601) | | `events[].data` | object | Данные события (структура зависит от типа, ключи в camelCase) | | `nextOffset` | number | Смещение для следующего запроса | | `hasMore` | boolean | Есть ещё необработанные события | | `storedOffset` | number | Текущее сохранённое смещение в БД | | `persisted` | boolean | `true` если `lastOffset` в БД продвинулся (доставлено хотя бы одно событие). `false` — ответ пустой, курсор не изменился | | `hint` | string | Диагностическое сообщение, появляется после 5+ подряд пустых ответов — указывает на состояние установки на стороне Битрикс24 | ## Пример ответа Есть новые события (`persisted: true`): ```json { "success": true, "data": { "events": [ { "eventId": 35, "type": "ONIMBOTV2MESSAGEADD", "date": "2026-04-13T17:15:00+03:00", "data": { "dialogId": "chat123", "message": { "id": 1501, "text": "Привет, бот!" }, "user": { "id": 1, "name": "Иван Петров" } } } ], "nextOffset": 36, "hasMore": false, "storedOffset": 35, "persisted": true } } ``` Пустой ответ после нескольких запросов подряд (появляется поле `hint`): ```json { "success": true, "data": { "events": [], "nextOffset": 36, "hasMore": false, "storedOffset": 36, "persisted": false, "hint": "Events queue empty for 5+ consecutive polls. If you expect events: (1) verify the bot is registered correctly via GET /v1/bots/:botId, (2) confirm your OAuth app's INSTALL event handler responded 200 to Bitrix24, (3) try POST /v1/bots to re-register if the bot was deleted on the B24 side, (4) check that eventMode='fetch' was set when the bot was created. The Вайбкод platform forwards what B24 delivers — empty results indicate B24 is not routing events to this bot." } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Какой токен использовать.** Для личного ключа `vibe_api_…` достаточно заголовка `X-Api-Key`. Для ключа авторизации `vibe_app_…` обязательно добавлять `Authorization: Bearer ` — без Bearer запрос вернёт `401 TOKEN_MISSING`. Получение `session_token` для OAuth-приложения — см. [Ключи и авторизация](/docs/keys-auth). **Серверное хранение offset:** Вайбкод хранит `lastOffset` в базе. При первом запросе без `offset` — используется сохранённое значение. После получения событий `lastOffset` обновляется автоматически, не дожидаясь результата записи. **offset=0:** явная передача `offset=0` начинает с начала истории — для отладки или первичной загрузки. **offset=N (конкретное значение):** само событие с указанным ID попадает в ответ. Чтобы не получить дубли, всегда передавайте `nextOffset` из предыдущего ответа, а не `eventId` последнего обработанного события. **Цепочка запросов:** ``` GET /events → { nextOffset: 42, hasMore: true } GET /events?offset=42 → { nextOffset: 55, hasMore: false } GET /events?offset=55 → { events: [], hasMore: false } ``` **Рекомендуемый интервал polling:** 2-5 секунд между запросами. **Polling-цикл (готовый пример):** ```javascript const BOT_ID = 42 const API_KEY = 'YOUR_API_KEY' const BASE = 'https://vibecode.bitrix24.tech/v1' async function pollEvents() { let offset = undefined while (true) { try { const url = new URL(`${BASE}/bots/${BOT_ID}/events`) if (offset !== undefined) url.searchParams.set('offset', String(offset)) const res = await fetch(url, { headers: { 'X-Api-Key': API_KEY }, }) const { data } = await res.json() for (const event of data.events ?? []) { await handleEvent(event) } if (data.nextOffset !== undefined) { offset = data.nextOffset } } catch (err) { console.error('Poll error:', err.message) } await new Promise(r => setTimeout(r, 3000)) } } async function handleEvent(event) { const { data } = event switch (event.type) { case 'ONIMBOTV2MESSAGEADD': // Ответить на сообщение await fetch(`${BASE}/bots/${BOT_ID}/messages`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ dialogId: data.chat.dialogId, fields: { message: `Получил: ${data.message.text}` }, }), }) break case 'ONIMBOTV2COMMANDADD': // Ответить на команду await fetch(`${BASE}/bots/${BOT_ID}/commands/${data.command.id}/answer`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ messageId: data.message.id, message: `Команда /${data.command.command}: ${data.command.params}`, }), }) break } } pollEvents() ``` ## Смотрите также - [Диагностика проблем](/docs/bots/troubleshooting) - [Bot-события](/docs/bots/events/bot-events) - [User-события](/docs/bots/events/user-events) - [Отправить сообщение](/docs/bots/messages/send) - [Ответить на команду](/docs/bots/commands/answer) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: User Events ## User-события (ONIMV2*) Общий первый шаг — подписка: [`POST /v1/chats/events/subscribe`](/docs/chats/events/subscribe) (скоуп `im`, не `imbot`). Без активной подписки Битрикс24 не регистрирует пользовательские события. Дальше события забирают одним из двух способов: 1. **Вместе с bot-событиями** — передать `withUserEvents=true` в [polling бота](/docs/bots/events/polling). Bot-события (`ONIMBOTV2*`) и user-события (`ONIMV2*`) приходят в одном массиве `events`. 2. **Отдельным опросом от имени пользователя** — [`GET /v1/chats/events`](/docs/chats/events/poll). Не требует зарегистрированного бота, подходит для агентов, работающих от имени пользователя. ## Список событий | Событие | Описание | |---------|---------| | `ONIMV2MESSAGEADD` | Новое сообщение в подписанном чате | | `ONIMV2MESSAGEUPDATE` | Сообщение отредактировано | | `ONIMV2MESSAGEDELETE` | Сообщение удалено | | `ONIMV2JOINCHAT` | Участник зашёл в чат | | `ONIMV2REACTIONCHANGE` | Реакция изменена | ## Известные особенности **Отдельный скоуп:** [подписка](/docs/chats/events/subscribe) и [отписка](/docs/chats/events/unsubscribe) требуют скоуп `im`, а не `imbot`. ## Смотрите также - [Получить события](/docs/bots/events/polling) - [Получить пользовательские события](/docs/chats/events/poll) - [Bot-события](/docs/bots/events/bot-events) - [Бот-платформа](/docs/bots) --- # Bot: Files # Файлы Загружайте файлы в чат от имени бота и скачивайте файлы, которые присылают пользователи. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Операции - [Загрузить файл](./files/upload.md) — `POST /v1/bots/:botId/files` - [Скачать файл](./files/download.md) — `GET /v1/bots/:botId/files/:fileId` --- # Bot: Download ## Скачать файл `GET /v1/bots/:botId/files/:fileId` Возвращает информацию о файле и одноразовую ссылку для скачивания. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` (path) | number | да | ID бота | | `fileId` (path) | number | да | ID файла | ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/files/789 \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/files/789 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/files/789', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Download URL:', data.downloadUrl) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/files/789', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID файла | | `name` | string | Имя файла | | `size` | number | Размер в байтах | | `downloadUrl` | string | Одноразовая ссылка для скачивания | ## Пример ответа ```json { "success": true, "data": { "id": 789, "name": "report.pdf", "size": 2048576, "downloadUrl": "https://portal.bitrix24.ru/rest/download.json?token=abc123..." } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Одноразовая ссылка:** `downloadUrl` — временная ссылка. Для повторного скачивания нужен новый вызов метода. ## Смотрите также - [Загрузить файл](/docs/bots/files/upload) - [Отправить сообщение](/docs/bots/messages/send) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Upload ## Загрузить файл `POST /v1/bots/:botId/files` Загружает файл в чат от имени бота. Содержимое передаётся в base64. Максимальный размер — 100 МБ. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `dialogId` | string | да | ID диалога: числовой ID пользователя для личных, `chatXXX` для групповых | | `file.name` | string | да | Имя файла с расширением | | `file.content` | string | да | Содержимое файла в base64 | | `message` | string | нет | Текст сообщения, прикреплённый к файлу | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/files \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "file": { "name": "report.pdf", "content": "JVBERi0xLjQKJcOkw7zDtsOfCjEgMCBv..." }, "message": "Вот запрошенный отчёт" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/files \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "file": { "name": "report.pdf", "content": "JVBERi0xLjQKJcOkw7zDtsOfCjEgMCBv..." }, "message": "Вот запрошенный отчёт" }' ``` ### JavaScript — личный ключ ```javascript import { readFileSync } from 'fs' const base64 = readFileSync('./report.pdf').toString('base64') const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/files', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', file: { name: 'report.pdf', content: base64 }, message: 'Вот запрошенный отчёт', }), }) const { success, data } = await res.json() console.log('File ID:', data.fileId) ``` ### JavaScript — OAuth-приложение ```javascript import { readFileSync } from 'fs' const base64 = readFileSync('./report.pdf').toString('base64') const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/files', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', file: { name: 'report.pdf', content: base64 }, message: 'Вот запрошенный отчёт', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `messageId` | number | ID созданного сообщения с файлом | | `fileId` | number | ID загруженного файла | ## Пример ответа ```json { "success": true, "data": { "messageId": 1520, "fileId": 789 } } ``` ## Пример ответа при ошибке 502 — ошибка Битрикс24: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "File size exceeds limit" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 при загрузке | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Base64:** содержимое файла передаётся целиком в base64. Для больших файлов это увеличивает размер body на ~33%. **Сообщение с файлом:** параметр `message` прикрепляет текст к тому же сообщению, что и файл — отдельного вызова для отправки текста не нужно. ## Смотрите также - [Скачать файл](/docs/bots/files/download) - [Отправить сообщение](/docs/bots/messages/send) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Management # Управление ботами Зарегистрируйте бота на портале Битрикс24, получайте и обновляйте его данные, восстанавливайте доступ при сбоях авторизации и удаляйте бота, когда он больше не нужен. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Операции - [Зарегистрировать бота](./management/create.md) — `POST /v1/bots` - [Список ботов](./management/list.md) — `GET /v1/bots` - [Получить бота](./management/get.md) — `GET /v1/bots/:botId` - [Обновить бота](./management/update.md) — `PATCH /v1/bots/:botId` - [Удалить бота](./management/delete.md) — `DELETE /v1/bots/:botId` - [Повторная авторизация](./management/reauth.md) — `POST /v1/bots/:botId/reauth` - [Перепривязка подписки на события](./management/resubscribe.md) — `POST /v1/bots/:botId/resubscribe` - [Ревизия бот-платформы](./management/revision.md) — `GET /v1/bots/revision` --- # Bot: Create ## Зарегистрировать бота `POST /v1/bots` Регистрирует нового бота на портале Битрикс24. Операция идемпотентна по `code` — повторный вызов с тем же кодом вернёт `409 BOT_ALREADY_EXISTS` с данными существующего бота. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `code` | string | да | — | Уникальный код бота (латиница, цифры, подчёркивание) | | `name` | string | да | — | Отображаемое имя бота | | `type` | string | нет | `bot` | [Тип бота](#типы-ботов): `bot`, `personal`, `supervisor`, `openline`. Нельзя изменить после регистрации | | `eventMode` | string | нет | `fetch` | Режим событий: `fetch` (polling) или `webhook` (push) | | `webhookUrl` | string | нет | — | URL для push-уведомлений (только при `eventMode: "webhook"`) | | `lastName` | string | нет | — | Фамилия бота | | `workPosition` | string | нет | — | Должность бота (отображается под именем) | | `color` | string | нет | — | Цвет аватара: `RED`, `GREEN`, `MINT`, `LIGHT_BLUE`, `DARK_BLUE`, `PURPLE`, `AQUA`, `PINK`, `LIME`, `BROWN`, `AZURE`, `KHAKI`, `SAND`, `MARENGO`, `GRAY`, `GRAPHITE` | | `gender` | string | нет | — | Пол: `M` или `F` | | `avatar` | string | нет | — | URL изображения для аватара | | `isHidden` | boolean | нет | `false` | Скрыть бота из списка контактов | | `isReactionsEnabled` | boolean | нет | `true` | Разрешить реакции на сообщения бота | | `backgroundId` | string | нет | — | Фон чата: `azure`, `mint`, `steel`, `slate`, `teal`, `cornflower`, `sky`, `peach`, `frost` | | `isSupportOpenline` | boolean | нет | `false` | Поддержка открытых линий (только для `type: "openline"`) | ## Типы ботов | Тип | Описание | |-----|---------| | `bot` | Стандартный бот — реагирует на @упоминание и личные сообщения | | `personal` | AI-ассистент — получает все сообщения без @упоминания. Доступны `Message.get` и `Message.getContext` | | `supervisor` | Системный наблюдатель — получает все сообщения в чатах, где состоит | | `openline` | Бот для открытых линий. Требует `isSupportOpenline: true` | > ⚠ **`personal` и `supervisor` — привилегированные типы:** они получают все сообщения в чатах, где состоят, даже без @упоминания бота. Используйте их осознанно. Регистрация через `POST /v1/bots` разрешена и не требует админ-роли на стороне Битрикс24 — ограничение задаётся правами вашего webhook/OAuth-токена. ## Доступные цвета Используются в параметре `color` при создании и обновлении бота: ``` RED, GREEN, MINT, LIGHT_BLUE, DARK_BLUE, PURPLE, AQUA, PINK, LIME, BROWN, AZURE, KHAKI, SAND, MARENGO, GRAY, GRAPHITE ``` ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "code": "support_bot", "name": "Техподдержка", "type": "bot", "eventMode": "fetch", "color": "AZURE", "workPosition": "Помощник по техническим вопросам" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "code": "support_bot", "name": "Техподдержка", "type": "bot", "eventMode": "fetch", "color": "AZURE", "workPosition": "Помощник по техническим вопросам" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ code: 'support_bot', name: 'Техподдержка', type: 'bot', eventMode: 'fetch', color: 'AZURE', workPosition: 'Помощник по техническим вопросам', }), }) const { success, data } = await res.json() // `data.botId` зеркалит ответ 409 BOT_ALREADY_EXISTS — один и тот же путь для // success и conflict. `data.bot.id` оставлен для обратной совместимости. console.log('Bot ID:', data.botId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ code: 'support_bot', name: 'Техподдержка', type: 'bot', eventMode: 'fetch', color: 'AZURE', workPosition: 'Помощник по техническим вопросам', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `botId` | number | ID бота на портале Битрикс24. Зеркалит `data.botId` из 409-ответа — один и тот же путь для success и conflict | | `bot.id` | number | Дубликат `botId` для обратной совместимости. ID бота на портале Битрикс24 | | `bot.code` | string | Уникальный код бота | | `bot.type` | string | Тип бота | | `bot.eventMode` | string | Режим событий: `fetch` или `webhook` | | `bot.isHidden` | boolean | Скрыт из списка контактов | | `bot.isReactionsEnabled` | boolean | Разрешены реакции | | `users` | array | Массив пользователей Битрикс24, созданных для бота | ## Пример ответа ```json { "success": true, "data": { "botId": 42, "bot": { "id": 42, "code": "support_bot", "type": "bot", "eventMode": "fetch", "isHidden": false, "isReactionsEnabled": true }, "users": [ { "id": 42, "name": "Техподдержка", "active": true, "bot": true } ] } } ``` ## Пример ответа при ошибке 409 — бот с таким кодом уже существует: ```json { "success": false, "error": { "code": "BOT_ALREADY_EXISTS", "message": "Bot with this code already exists" }, "data": { "botId": 42, "code": "support_bot", "name": "Техподдержка" } } ``` В поле `data` возвращаются `botId`, `code` и `name` уже зарегистрированного бота — это идемпотентный путь восстановления записи в базе Вайбкод после рассинхронизации. ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `CODE_REQUIRED` | Не передан параметр `code` | | 400 | `NAME_REQUIRED` | Не передан параметр `name` | | 409 | `BOT_ALREADY_EXISTS` | Бот с таким `code` уже зарегистрирован. Ответ содержит `data` с `botId` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку при регистрации (текст ошибки в `message`) | | 502 | `REGISTRATION_FAILED` | Битрикс24 не вернул ID бота | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Тип нельзя изменить:** после регистрации `type` фиксируется. `PATCH /v1/bots/:botId` не принимает это поле. **Восстановление при рассинхронизации:** если бот существует на портале Битрикс24, но отсутствует в базе Вайбкод (после сбоя), повторный `POST` с тем же `code` восстановит запись в базе. **Формат body отличается от PATCH:** при создании поля передаются плоско (`code`, `name`, `color`). При обновлении — вложенная структура `{ fields: { properties: { name, color } } }`. **Идемпотентность по code:** если бот с таким кодом уже есть и в базе Вайбкод, и на портале Битрикс24, вернётся `409 BOT_ALREADY_EXISTS` с `data: { botId, code, name }` существующего бота. Подходит для перезапуска скриптов и проверки факта регистрации без обработки 200/400 раздельно. **Жизненный цикл бота.** Бот существует ровно столько, сколько существует локальное приложение, через которое он зарегистрирован. Удаление приложения с портала удаляет и бота. ## Смотрите также - [Диагностика проблем](/docs/bots/troubleshooting) - [События](/docs/bots/events) - [Сообщения](/docs/bots/messages) - [Обновить бота](/docs/bots/management) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Delete ## Удалить бота `DELETE /v1/bots/:botId` Удаляет бота из Битрикс24 и из базы Вайбкод. Действие необратимо. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` | number | да | ID бота (path-параметр) | ## Примеры ### curl — личный ключ ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42 \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data } = await res.json() console.log(data) // { deleted: true } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.deleted` | boolean | `true` при успешном удалении | ## Пример ответа ```json { "success": true, "data": { "deleted": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 42 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Каскадное удаление:** при удалении бота также удаляются связанные записи AI-агента или управляемого бота, если они были привязаны к этому боту. **Необратимость:** бот удаляется и из Битрикс24, и из базы Вайбкод. Для повторного использования нужна новая регистрация через `POST /v1/bots`. ## Смотрите также - [События](/docs/bots/events) - [Сообщения](/docs/bots/messages) - [Бот-платформа](/docs/bots) --- # Bot: Get ## Получить бота `GET /v1/bots/:botId` Получает актуальные данные о боте из Битрикс24 (живой запрос, не из кэша). ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` | number | да | ID бота (path-параметр) | ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/bots/42 \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/bots/42 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data } = await res.json() console.log('Бот:', data) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID бота | | `code` | string | Уникальный код | | `type` | string | Тип бота | | `isHidden` | boolean | Скрыт из контактов | | `eventMode` | string | Режим событий | | `properties.name` | string | Имя | | `properties.lastName` | string | Фамилия | | `properties.workPosition` | string | Должность | | `properties.color` | string | Цвет аватара | | `properties.gender` | string | Пол | | `properties.avatar` | string | URL аватара | ## Пример ответа ```json { "success": true, "data": { "id": 42, "code": "support_bot", "type": "bot", "isHidden": false, "eventMode": "fetch", "properties": { "name": "Техподдержка", "lastName": "", "workPosition": "Помощник по техническим вопросам", "color": "AZURE", "gender": "M", "avatar": "" } } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот не найден — зарегистрируйте через `POST /v1/bots` | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список ботов](/docs/bots/management) - [Обновить бота](/docs/bots/management) - [События](/docs/bots/events) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: List ## Список ботов `GET /v1/bots` Возвращает список ботов, зарегистрированных текущим API-ключом на портале. Запрос **не идёт** в Битрикс24 — возвращаются строки из Вайбкод DB, отфильтрованные по вашему API-ключу. Автоматически отключённые боты (`PORTAL_DELETED` / `AUTH_FAILURES`) в список не попадают — чтобы увидеть их, переключите статус вручную через `PATCH /v1/bots/:botId { disabled: false }`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `limit` | number | нет | Максимальное количество ботов в ответе. По умолчанию 50, максимум 200 | | `offset` | number | нет | Смещение для пагинации. По умолчанию 0 | | `type` | string | нет | Фильтр по типу бота: `bot`, `personal`, `supervisor`, `openline` | ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/bots \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/bots \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data } = await res.json() console.log('Мои боты:', data.bots) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `bots` | array | Массив объектов ботов | | `bots[].id` | number | ID бота на Битрикс24-портале | | `bots[].code` | string | Уникальный код бота | | `bots[].name` | string | Отображаемое имя бота в чате | | `bots[].type` | string | Тип: `bot`, `personal`, `supervisor`, `openline` | | `bots[].eventMode` | string | Режим событий: `fetch` или `webhook` | | `users` | array | Всегда пустой массив. Сохранён для обратной совместимости — чтобы получить пользователей Битрикс24, используйте `GET /v1/users` | | `hasNextPage` | boolean | `true`, если ещё есть записи за пределами текущей страницы — увеличьте `offset` | ## Пример ответа ```json { "success": true, "data": { "bots": [ { "id": 42, "code": "support_bot", "name": "Техподдержка", "type": "bot", "eventMode": "fetch" }, { "id": 58, "code": "analytics_bot", "name": "Аналитик", "type": "openline", "eventMode": "webhook" } ], "users": [], "hasNextPage": false } } ``` ## Пример ответа при ошибке 403 — нет скоупа `imbot`: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'imbot' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить бота](/docs/bots/management) - [Зарегистрировать бота](/docs/bots/management) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Reauth ## Повторная авторизация бота `POST /v1/bots/:botId/reauth` Проверяет учётные данные бота и при необходимости обновляет токен доступа. Снимает автоматическое отключение, если доступ снова действителен. Тело запроса не требуется. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` | number | да | ID бота (path-параметр) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/reauth \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/reauth \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/reauth', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data } = await res.json() console.log(data) // { validated: true, refreshed: false } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/reauth', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.validated` | boolean | `true`, если учётные данные бота действительны | | `data.refreshed` | boolean | `true`, если токен доступа был обновлён в ходе проверки | ## Пример ответа ```json { "success": true, "data": { "validated": true, "refreshed": false } } ``` ## Пример ответа при ошибке 410 — учётные данные недействительны и не восстанавливаются автоматически: ```json { "success": false, "error": { "code": "REAUTH_REQUIRED", "message": "Bot credentials are invalid and could not be refreshed automatically — the refresh token is itself dead. Re-authorize the API key via the OAuth flow (POST /v1/oauth/authorize on an OAuth-app key, or recreate the personal key)." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 410 | `REAUTH_REQUIRED` | Доступ недействителен и не восстанавливается автоматически — ключ нужно авторизовать заново | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Когда применять.** Бот отключён со статусом `BOT_DISABLED` по причине `AUTH_FAILURES`. Проверка подтверждает доступ и снимает отключение — после успешного ответа бот снова принимает события и отправляет сообщения. **Поле `refreshed`.** Принимает `true` только для ключа авторизации с истёкшим токеном доступа: проверка попутно обновляет токен. Для личного ключа `refreshed` всегда `false`. **Ответ `410`.** Когда токен обновления тоже недействителен, автоматическое восстановление невозможно — ключ нужно авторизовать заново через OAuth или пересоздать личный ключ. ## Смотрите также - [Диагностика проблем](/docs/bots/troubleshooting) - [Перепривязка подписки на события](/docs/bots/management/resubscribe) - [Бот-платформа](/docs/bots) --- # Bot: Resubscribe ## Перепривязка подписки на события `POST /v1/bots/:botId/resubscribe` Восстанавливает подписку бота на события Битрикс24. Применяется, когда бот активен, но `GET /v1/bots/:botId/events` перестал возвращать события. Тело запроса не требуется. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` | number | да | ID бота (path-параметр) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/resubscribe \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/resubscribe \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/resubscribe', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data } = await res.json() console.log(data) // { resubscribed: true, eventMode: 'fetch' } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/resubscribe', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.resubscribed` | boolean | `true` при успешной перепривязке | | `data.eventMode` | string | Режим доставки событий бота: `fetch` или `webhook` | ## Пример ответа ```json { "success": true, "data": { "resubscribed": true, "eventMode": "fetch" } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 42 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Когда применять.** Бот зарегистрирован и активен — в чаты приходят сообщения, бот есть в списке `GET /v1/bots` — но очередь событий пуста несколько опросов подряд, и в ответе `GET /v1/bots/:botId/events` появилось поле `hint`. Перепривязка восстанавливает доставку и сохраняет привязки открытых линий и приветственного бота, в отличие от повторной регистрации через `POST /v1/bots`. **Повторный вызов безопасен.** Каждый запрос заново отправляет режим доставки бота в Битрикс24, поэтому перепривязку можно вызывать несколько раз подряд. **Режим `webhook`.** Для бота с `eventMode: "webhook"` перепривязка также повторно отправляет сохранённый адрес вебхука. ## Смотрите также - [События](/docs/bots/events) - [Диагностика проблем](/docs/bots/troubleshooting) - [Повторная авторизация бота](/docs/bots/management/reauth) --- # Bot: Revision ## Ревизия бот-платформы `GET /v1/bots/revision` Возвращает номера ревизий бот-платформы Битрикс24 по типам клиентов. Не требует ID бота. Тело запроса не требуется. ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/bots/revision \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/bots/revision \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/revision', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { data } = await res.json() console.log(data) // { rest: 35, web: 130, mobile: 25, desktop: 6 } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/revision', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.rest` | number | Ревизия REST-возможностей бот-платформы | | `data.web` | number | Ревизия веб-клиента | | `data.mobile` | number | Ревизия мобильного клиента | | `data.desktop` | number | Ревизия десктоп-клиента | ## Пример ответа ```json { "success": true, "data": { "rest": 35, "web": 130, "mobile": 25, "desktop": 6 } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'imbot' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Назначение поля `rest`.** Значение растёт, когда Битрикс24 выпускает новые возможности REST бот-платформы. Сравнение сохранённого значения с текущим показывает, что на портале появились новые методы и события бот-платформы. ## Смотрите также - [Управление ботами](/docs/bots/management) - [Бот-платформа](/docs/bots) --- # Bot: Update ## Обновить бота `PATCH /v1/bots/:botId` Обновляет свойства бота. Передавайте только те поля, которые хотите изменить. > **Две формы тела запроса — обе корректны.** Платформа принимает как **плоскую** запись (та же, что у `POST /v1/bots`), так и формат Битрикс24 с обёрткой `fields`. Если в теле есть `fields`, запрос передаётся в Битрикс24 без изменений. Иначе известные поля верхнего уровня автоматически разворачиваются в `fields.properties.*` / `fields.*`. Поведение обеих форм идентично. ## Поля запроса (body) | Параметр (плоский) | Параметр (формат Битрикс24) | Тип | Описание | |---|---|-----|---------| | `name` | `fields.properties.name` | string | Новое имя бота | | `lastName` | `fields.properties.lastName` | string | Новая фамилия | | `workPosition` | `fields.properties.workPosition` | string | Новая должность | | `color` | `fields.properties.color` | string | Новый цвет аватара | | `gender` | `fields.properties.gender` | string | Пол: `M` или `F` | | `avatar` | `fields.properties.avatar` | string | Аватар бота: PNG или JPEG как base64-строка без префикса `data:image/...;base64,`, до ~50 КБ. См. «Известные особенности» | | `eventMode` | `fields.eventMode` | string | Режим событий: `fetch` или `webhook` | | `webhookUrl` | `fields.webhookUrl` | string | URL для push-уведомлений | | `isHidden` | `fields.isHidden` | boolean | Скрыть из списка контактов | | `isReactionsEnabled` | `fields.isReactionsEnabled` | boolean | Разрешить реакции | | `backgroundId` | `fields.backgroundId` | string | Фон чата: `azure`, `mint`, `steel`, `slate`, `teal`, `cornflower`, `sky`, `peach`, `frost` | ## Примеры ### curl — личный ключ ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "properties": { "name": "Новое имя", "color": "MINT" }, "eventMode": "fetch" } }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fields": { "properties": { "name": "Новое имя", "color": "MINT" }, "eventMode": "fetch" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ fields: { properties: { name: 'Новое имя', color: 'MINT' }, eventMode: 'fetch', }, }), }) const { data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ fields: { properties: { name: 'Новое имя', color: 'MINT' }, eventMode: 'fetch', }, }), }) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.bot` | object | Обновлённый бот. Набор полей совпадает с ответом [регистрации](/docs/bots/management/create) | | `data.bot.id` | number | ID бота на портале Битрикс24 | | `data.bot.code` | string | Системный код бота | | `data.bot.type` | string | Тип бота: `bot`, `personal` или `supervisor` | | `data.bot.eventMode` | string | Режим доставки событий: `fetch` или `webhook` | | `data.users` | array | Карточка бота как пользователя портала | ## Пример ответа Показаны основные поля. Полный набор полей бота — в ответе [регистрации](/docs/bots/management/create). ```json { "success": true, "data": { "bot": { "id": 42, "code": "my_helper_bot", "type": "bot", "eventMode": "fetch", "isHidden": false, "isReactionsEnabled": true, "language": "ru" }, "users": [] } } ``` ## Пример ответа при ошибке 403 — бот принадлежит другому ключу: ```json { "success": false, "error": { "code": "BOT_ACCESS_DENIED", "message": "This bot belongs to a different API key" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Симметрия с регистрацией.** PATCH принимает как плоское тело (`{ name, eventMode, ... }`), так и формат Битрикс24 с обёрткой `fields` — так же, как `POST /v1/bots`. Если в теле есть ключ `fields`, платформа передаёт его в Битрикс24 без изменений. Иначе нормализует плоские поля сама. **`type` нельзя изменить:** поле `type` не принимается при обновлении. **Формат аватара.** Поле `avatar` принимает изображение PNG или JPEG в виде base64-строки **без** префикса `data:image/...;base64,` — передавайте только сами base64-данные. Строка с префиксом `data:` приводит к ответу 422. Размер — до ~50 КБ: при превышении запрос завершается успешно (`success: true`), но аватар не сохраняется и в боте остаётся пустым. Эндпоинт принимает только JSON — загрузка файла через `multipart/form-data` не поддерживается (ответ 415). Передавайте значение как `avatar` (плоская форма) либо как `fields.properties.avatar` (форма с `fields`) — результат одинаковый. ## Смотрите также - [Получить бота](/docs/bots/management) - [Зарегистрировать бота](/docs/bots/management) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Messages # Сообщения Отправляйте сообщения от имени бота, редактируйте и удаляйте их, читайте отдельные сообщения и отмечайте переписку прочитанной. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Операции - [Отправить сообщение](./messages/send.md) — `POST /v1/bots/:botId/messages` - [Обновить сообщение](./messages/update.md) — `PATCH /v1/bots/:botId/messages/:messageId` - [Удалить сообщение](./messages/delete.md) — `DELETE /v1/bots/:botId/messages/:messageId` - [Прочитать сообщения](./messages/read.md) — `POST /v1/bots/:botId/chats/:dialogId/read` - [Получить сообщение](./messages/get.md) — `GET /v1/bots/:botId/messages/:messageId` - [Контекст сообщения](./messages/context.md) — `GET /v1/bots/:botId/messages/:messageId/context` --- # Bot: Attach ## ATTACH-блоки Расширенное форматирование сообщений через поле `fields.attach`. Максимальный размер — 60 000 символов после сериализации. ## Два формата передачи **Полный формат** (с метаданными): ```json { "fields": { "attach": { "ID": 1, "COLOR_TOKEN": "primary", "COLOR": "#29619b", "BLOCKS": [ { "MESSAGE": [{ "MESSAGE": "Текст блока", "STYLE": "bold" }] }, { "DELIMITER": [{ "SIZE": 200, "COLOR": "#c6c6c6" }] } ] } } } ``` **Сокращённый формат** (массив блоков): ```json { "fields": { "attach": [ { "MESSAGE": [{ "MESSAGE": "Текст блока", "STYLE": "bold" }] }, { "DELIMITER": [{}] }, { "GRID": [{ "NAME": "Поле", "VALUE": "Значение" }] } ] } } ``` Если в `attach` нет ключа `BLOCKS`, сервер считает, что передан сокращённый формат. ## Типы блоков ### MESSAGE — стилизованный текст | Поле | Тип | Описание | |------|-----|---------| | `MESSAGE` | string | Текст сообщения | | `STYLE` | string | Стиль: `bold`, `italic`, `base` | ```json { "MESSAGE": [{ "MESSAGE": "Статус обновлён", "STYLE": "bold" }] } ``` ### USER — карточка пользователя | Поле | Тип | Описание | |------|-----|---------| | `NAME` | string | Имя пользователя | | `AVATAR` | string | URL аватара | | `LINK` | string | URL профиля | ```json { "USER": [{ "NAME": "Иван Петров", "AVATAR": "https://example.com/avatar.jpg", "LINK": "https://portal.bitrix24.ru/company/personal/user/1/" }] } ``` ### LINK — превью ссылки | Поле | Тип | Описание | |------|-----|---------| | `NAME` | string | Заголовок ссылки | | `LINK` | string | URL | | `DESC` | string | Описание | | `PREVIEW` | string | URL изображения-превью | ```json { "LINK": [{ "NAME": "Документация API", "LINK": "https://vibecode.bitrix24.tech/docs", "DESC": "Полная документация Vibe API" }] } ``` ### DELIMITER — линия-разделитель | Поле | Тип | Описание | |------|-----|---------| | `SIZE` | integer | Ширина в пикселях | | `COLOR` | string | Цвет в формате HEX | ```json { "DELIMITER": [{ "SIZE": 200, "COLOR": "#c6c6c6" }] } ``` ### GRID — таблица / сетка | Поле | Тип | Описание | |------|-----|---------| | `NAME` | string | Название поля | | `VALUE` | string | Значение поля | | `DISPLAY` | string | Отображение: `LINE` (в строку), `BLOCK` (блок), `ROW` (строка) | | `WIDTH` | integer | Ширина столбца в пикселях | ```json { "GRID": [ { "NAME": "Задача", "VALUE": "Подготовить отчёт", "DISPLAY": "LINE" }, { "NAME": "Статус", "VALUE": "Выполнено", "DISPLAY": "LINE" } ] } ``` ### IMAGE — изображение | Поле | Тип | Описание | |------|-----|---------| | `LINK` | string | URL полного изображения | | `NAME` | string | Подпись | | `PREVIEW` | string | URL превью | | `WIDTH` | integer | Ширина в пикселях | | `HEIGHT` | integer | Высота в пикселях | ```json { "IMAGE": [{ "LINK": "https://example.com/chart.png", "NAME": "График продаж", "WIDTH": 600, "HEIGHT": 400 }] } ``` ### FILE — прикреплённый файл | Поле | Тип | Описание | |------|-----|---------| | `LINK` | string | URL файла | | `NAME` | string | Имя файла | | `SIZE` | integer | Размер в байтах | ```json { "FILE": [{ "LINK": "https://example.com/report.pdf", "NAME": "report.pdf", "SIZE": 2048576 }] } ``` ## Токены цвета (COLOR_TOKEN) `primary`, `secondary`, `alert`, `base` ## Полный пример ```json { "dialogId": "chat123", "fields": { "message": "", "attach": [ { "MESSAGE": [ { "MESSAGE": "Статус задачи обновлён", "STYLE": "bold" } ] }, { "DELIMITER": [{}] }, { "GRID": [ { "DISPLAY": "LINE", "NAME": "Задача", "VALUE": "Подготовить отчёт" }, { "DISPLAY": "LINE", "NAME": "Статус", "VALUE": "Выполнено" }, { "DISPLAY": "LINE", "NAME": "Исполнитель", "VALUE": "Иванов А.П." } ] }, { "LINK": [ { "NAME": "Открыть задачу", "LINK": "https://portal.bitrix24.ru/tasks/42/" } ] } ] } } ``` ## Смотрите также - [Отправить сообщение](/docs/bots/messages/send) - [Обновить сообщение](/docs/bots/messages/update) - [Форматирование текста](/docs/bots/messages/formatting) - [Клавиатура](/docs/bots/messages/keyboard) --- # Bot: Context ## Контекст сообщения `GET /v1/bots/:botId/messages/:messageId/context` Возвращает окно сообщений вокруг указанного. Используется для анализа истории диалога — например, чтобы понять контекст входящего сообщения. > **Ограничение по типу бота.** Метод доступен только для ботов с `type` ∈ {`personal`, `supervisor`}. Для обычного `bot` Битрикс24 возвращает 422 `BITRIX_ERROR: Method is available only for supervisor and personal bots`. Тип задаётся при регистрации через [POST /v1/bots](/docs/bots/management/create) и не меняется без перерегистрации. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` (path) | number | да | ID бота | | `messageId` (path) | number | да | ID центрального сообщения | | `range` (query) | number | нет | Количество сообщений в каждую сторону от центрального (1-50). По умолчанию `50` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/context?range=20" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/context?range=20" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/context?range=20', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Сообщений:', data.messages.length) console.log('Есть ещё до:', data.hasPrevPage) console.log('Есть ещё после:', data.hasNextPage) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/context?range=20', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `messages` | array | Массив сообщений вокруг центрального | | `messages[].id` | number | ID сообщения | | `messages[].chatId` | number | ID чата | | `messages[].authorId` | number | ID автора | | `messages[].date` | string | Дата отправки (ISO 8601) | | `messages[].text` | string | Текст сообщения | | `hasPrevPage` | boolean | Есть ещё сообщения до окна | | `hasNextPage` | boolean | Есть ещё сообщения после окна | ## Пример ответа ```json { "success": true, "data": { "messages": [ { "id": 1499, "chatId": 123, "authorId": 3, "date": "2026-03-31T09:58:00+03:00", "text": "Коллеги, есть вопрос по задаче" }, { "id": 1500, "chatId": 123, "authorId": 1, "date": "2026-03-31T09:59:00+03:00", "text": "Давай обсудим" }, { "id": 1501, "chatId": 123, "authorId": 1, "date": "2026-03-31T10:00:00+03:00", "text": "Привет, бот!" } ], "hasPrevPage": true, "hasNextPage": false } } ``` ## Пример ответа при ошибке 502 — бот не имеет доступа: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Access denied" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только personal и supervisor:** как и `GET /messages/:messageId`, метод доступен только для ботов типа `personal` и `supervisor`. **Пагинация:** `hasPrevPage` и `hasNextPage` указывают, есть ли сообщения за пределами окна. Для полного обхода можно использовать крайние `id` из `messages` как новый `messageId`. ## Смотрите также - [Получить сообщение](/docs/bots/messages/get) - [Прочитать сообщения](/docs/bots/messages/read) - [События](/docs/bots/events) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Delete ## Удалить сообщение `DELETE /v1/bots/:botId/messages/:messageId` Удаляет сообщение. По умолчанию — мягкое скрытие. Для полного удаления из базы данных передайте `complete: true`. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `complete` | boolean | нет | `false` | `true` — полное удаление из БД, `false` — мягкое скрытие | ## Примеры ### curl — личный ключ ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/messages/1502 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "complete": true }' ``` ### curl — OAuth-приложение ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/messages/1502 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "complete": true }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1502', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ complete: true }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1502', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ complete: true }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном удалении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 403 — бот принадлежит другому ключу: ```json { "success": false, "error": { "code": "BOT_ACCESS_DENIED", "message": "This bot belongs to a different API key" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Мягкое vs полное удаление:** без `complete: true` сообщение помечается удалённым, но остаётся в базе. С `complete: true` удаляется полностью. **Системные сообщения:** сообщения с `authorId = 0` (отправленные с `system: true`) бот не может удалить, если не является администратором чата. **Пустое тело:** для мягкого удаления body можно не передавать. ## Смотрите также - [Отправить сообщение](/docs/bots/messages/send) - [Обновить сообщение](/docs/bots/messages/update) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Formatting ## Форматирование текста (BB-коды) Текст сообщений поддерживает BB-коды для стилизации. Используйте их в поле `fields.message` при отправке и обновлении сообщений. ## Список BB-кодов | Код | Описание | Пример | |-----|---------|--------| | `[B]...[/B]` | Жирный текст | `[B]Важно[/B]` | | `[I]...[/I]` | Курсив | `[I]примечание[/I]` | | `[U]...[/U]` | Подчёркнутый | `[U]внимание[/U]` | | `[S]...[/S]` | Зачёркнутый | `[S]устарело[/S]` | | `[URL=ссылка]текст[/URL]` | Гиперссылка | `[URL=https://example.com]Открыть[/URL]` | | `[CODE]...[/CODE]` | Блок кода (моноширинный шрифт) | `[CODE]console.log('hi')[/CODE]` | | `[BR]` или `\n` | Перенос строки | — | | `[SEND=значение]текст[/SEND]` | Клик отправляет значение как сообщение | `[SEND=/help]Помощь[/SEND]` | | `[PUT=значение]текст[/PUT]` | Вставка текста в поле ввода (без отправки) | `[PUT=/search ]Поиск[/PUT]` | | `[IMG]ссылка[/IMG]` | Встроенное изображение | `[IMG]https://example.com/pic.png[/IMG]` | | `[CALL=номер]текст[/CALL]` | Ссылка-звонок | `[CALL=+79161234567]Позвонить[/CALL]` | | `[SIZE=число]...[/SIZE]` | Размер текста | `[SIZE=18]Заголовок[/SIZE]` | | `[COLOR=цвет]...[/COLOR]` | Цвет текста (HEX или имя) | `[COLOR=#ff0000]Красный[/COLOR]` | ## Пример ```json { "dialogId": "chat123", "fields": { "message": "[B]Задача #42[/B]\nСтатус: [COLOR=#00aa00]выполнено[/COLOR]\n[URL=https://portal.bitrix24.ru/tasks/42/]Открыть задачу[/URL]\n\n[SEND=/status 42]Обновить статус[/SEND]" } } ``` ## Смотрите также - [Отправить сообщение](/docs/bots/messages/send) - [Клавиатура](/docs/bots/messages/keyboard) - [ATTACH-блоки](/docs/bots/messages/attach) --- # Bot: Get ## Получить сообщение `GET /v1/bots/:botId/messages/:messageId` Возвращает сообщение по его ID. > **Ограничение по типу бота.** Метод доступен только для ботов с `type` ∈ {`personal`, `supervisor`}. Для обычного `bot` Битрикс24 возвращает 422 `BITRIX_ERROR: Method is available only for supervisor and personal bots`. Тип задаётся при регистрации через [POST /v1/bots](/docs/bots/management/create) и не меняется без перерегистрации. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `botId` (path) | number | да | ID бота | | `messageId` (path) | number | да | ID сообщения | ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/messages/1501 \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/messages/1501 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Сообщение:', data.text) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID сообщения | | `chatId` | number | ID чата | | `authorId` | number | ID автора | | `date` | string | Дата отправки (ISO 8601) | | `text` | string | Текст сообщения | | `isSystem` | boolean | Системное сообщение | | `params` | object | Дополнительные параметры сообщения | ## Пример ответа ```json { "success": true, "data": { "id": 1501, "chatId": 123, "authorId": 1, "date": "2026-03-31T10:00:00+03:00", "text": "Привет, бот!", "isSystem": false, "params": {} } } ``` ## Пример ответа при ошибке 502 — бот не имеет доступа к сообщению: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Access denied" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (бот не имеет доступа к сообщению) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только personal и supervisor:** метод доступен только для ботов типа `personal` и `supervisor`. Для стандартных ботов (`bot`) Битрикс24 вернёт ошибку доступа. **Типичный сценарий:** бот получил событие с `replyId` и хочет прочитать исходное сообщение, на которое ответил пользователь. ## Смотрите также - [Контекст сообщения](/docs/bots/messages/context) - [Отправить сообщение](/docs/bots/messages/send) - [События](/docs/bots/events) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Keyboard ## Клавиатура Интерактивные кнопки, прикрепляемые к сообщению через поле `fields.keyboard`. Каждая кнопка — объект в массиве. ## Поля кнопки | Поле | Тип | По умолч. | Описание | |------|-----|-----------|---------| | `TEXT` | string | — | Текст кнопки. Обязателен для всех кнопок кроме `TYPE: "NEWLINE"` | | `TYPE` | string | — | Специальный тип: `NEWLINE` (перенос на новую строку) | | `LINK` | string | — | URL — кнопка становится ссылкой | | `COMMAND` | string | — | Команда бота (вызывает событие `ONIMBOTV2COMMANDADD`) | | `COMMAND_PARAMS` | string | — | Параметры команды | | `ACTION` | string | — | Действие при нажатии: `PUT` (вставить в поле ввода), `SEND` (отправить текст), `COPY` (скопировать), `CALL` (позвонить), `DIALOG` (открыть чат) | | `ACTION_VALUE` | string | — | Значение для `ACTION` (текст, номер телефона, ID чата) | | `BG_COLOR` | string | — | Цвет фона в формате HEX (`#ff6600`) | | `BG_COLOR_TOKEN` | string | `base` | Токен цвета (см. [таблицу ниже](#токены-цветов)) | | `TEXT_COLOR` | string | — | Цвет текста в формате HEX | | `DISPLAY` | string | `BLOCK` | Отображение: `LINE` (в строке с другими) или `BLOCK` (на всю ширину) | | `DISABLED` | string | `N` | Неактивная кнопка: `Y` или `N` | | `BLOCK` | string | `N` | Блокировка после нажатия: `Y` (деактивируется после клика) или `N` | | `WIDTH` | integer | — | Ширина кнопки в пикселях | | `CONTEXT` | string | `ALL` | Контекст: `MOBILE`, `DESKTOP`, `ALL` | | `OFF_BG_COLOR` | string | — | Цвет фона в неактивном состоянии (после нажатия при `BLOCK: "Y"`) | | `OFF_TEXT_COLOR` | string | — | Цвет текста в неактивном состоянии | ## Токены цветов | Токен | Цвет | Назначение | |-------|------|-----------| | `primary` | Синий | Основное действие | | `secondary` | Серый | Дополнительное действие | | `alert` | Красный | Деструктивное действие | | `base` | Белый | Нейтральная кнопка (по умолчанию) | ## Пример ```json { "dialogId": "chat123", "fields": { "message": "Подтвердите действие:", "keyboard": [ { "TEXT": "Одобрить", "BG_COLOR_TOKEN": "primary", "ACTION": "SEND", "ACTION_VALUE": "/approve", "BLOCK": "Y" }, { "TEXT": "Отклонить", "BG_COLOR_TOKEN": "alert", "ACTION": "SEND", "ACTION_VALUE": "/reject", "BLOCK": "Y" }, { "TYPE": "NEWLINE" }, { "TEXT": "Подробнее", "LINK": "https://portal.bitrix24.ru/tasks/42/", "BG_COLOR_TOKEN": "secondary", "DISPLAY": "LINE" }, { "TEXT": "Позвонить менеджеру", "ACTION": "CALL", "ACTION_VALUE": "+79161234567", "DISPLAY": "LINE", "CONTEXT": "MOBILE" } ] } } ``` ## Смотрите также - [Отправить сообщение](/docs/bots/messages/send) - [Обновить сообщение](/docs/bots/messages/update) - [Форматирование текста](/docs/bots/messages/formatting) - [ATTACH-блоки](/docs/bots/messages/attach) --- # Bot: Read ## Прочитать сообщения `POST /v1/bots/:botId/chats/:dialogId/read` Отмечает сообщения как прочитанные от имени бота. Без `messageId` прочитает все сообщения в чате. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `botId` (path) | number | да | — | ID бота | | `dialogId` (path) | string | да | — | ID диалога: числовой ID пользователя для личных сообщений, `chatXXX` для групповых | | `messageId` (body) | number | нет | — | Прочитать все сообщения до этого включительно. Без параметра — прочитать все | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/read \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "messageId": 1501 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/read \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messageId": 1501 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/read', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ messageId: 1501 }), }) const { success, data } = await res.json() console.log('Прочитано до:', data.lastId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/chats/chat456/read', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ messageId: 1501 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `chatId` | number | ID чата | | `lastId` | number | ID последнего прочитанного сообщения | | `counter` | number | Оставшееся количество непрочитанных | | `viewedMessages` | number[] | ID прочитанных сообщений | ## Пример ответа ```json { "success": true, "data": { "chatId": 456, "lastId": 1501, "counter": 0, "viewedMessages": [1499, 1500, 1501] } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Без messageId:** если не передать `messageId`, будут прочитаны все сообщения в чате. **Чтение до сообщения:** при указании `messageId` прочитываются все сообщения до указанного включительно, а не только это одно сообщение. ## Смотрите также - [Отправить сообщение](/docs/bots/messages/send) - [Получить сообщение](/docs/bots/messages/get) - [События](/docs/bots/events) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Send ## Отправить сообщение `POST /v1/bots/:botId/messages` Отправляет сообщение от имени бота в указанный диалог. Текст поддерживает [BB-коды](/docs/bots/messages/formatting), к сообщению можно прикрепить [клавиатуру](/docs/bots/messages/keyboard) и [ATTACH-блоки](/docs/bots/messages/attach). ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `botId` (path) | number | да | — | ID бота | | `dialogId` | string | да | — | ID диалога: числовой ID пользователя для личных сообщений, `chatXXX` для групповых | | `fields.message` | string | да | — | Текст сообщения (до 20 000 символов). Поддерживает [BB-коды](/docs/bots/messages/formatting) | | `fields.keyboard` | array | нет | — | Интерактивная [клавиатура](/docs/bots/messages/keyboard) | | `fields.attach` | array/object | нет | — | [ATTACH-блоки](/docs/bots/messages/attach) с оформленным содержимым | | `fields.replyId` | number | нет | — | ID сообщения для цитирования | | `fields.forwardIds` | object | нет | — | Сообщения для пересылки: `{uuid: messageId}`, где uuid — произвольная строка-ключ, messageId — ID исходного сообщения. Максимум 100. В ответе `uuidMap` вернёт `{uuid: newMessageId}` | | `fields.system` | boolean | нет | `false` | Системное сообщение (другой стиль, без аватара бота) | | `fields.urlPreview` | boolean | нет | `true` | Показывать превью ссылок в тексте | | `fields.templateId` | string | нет | — | UUID шаблона сообщения | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/messages \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "fields": { "message": "[b]Задача #42[/b]\nСтатус: выполнено", "keyboard": [ { "TEXT": "Открыть задачу", "LINK": "https://portal.bitrix24.ru/tasks/42/", "BG_COLOR_TOKEN": "primary" } ] } }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/messages \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "fields": { "message": "[b]Задача #42[/b]\nСтатус: выполнено", "keyboard": [ { "TEXT": "Открыть задачу", "LINK": "https://portal.bitrix24.ru/tasks/42/", "BG_COLOR_TOKEN": "primary" } ] } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', fields: { message: '[b]Задача #42[/b]\nСтатус: выполнено', keyboard: [ { TEXT: 'Открыть задачу', LINK: 'https://portal.bitrix24.ru/tasks/42/', BG_COLOR_TOKEN: 'primary', }, ], }, }), }) const { success, data } = await res.json() console.log('Message ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', fields: { message: '[b]Задача #42[/b]\nСтатус: выполнено', keyboard: [ { TEXT: 'Открыть задачу', LINK: 'https://portal.bitrix24.ru/tasks/42/', BG_COLOR_TOKEN: 'primary', }, ], }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного сообщения | | `uuidMap` | array | Маппинг UUID при пересылке (пустой массив если без `forwardIds`) | ## Пример ответа ```json { "success": true, "data": { "id": 36357, "uuidMap": [] } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 при отправке (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Системные сообщения:** при `system: true` сообщение отображается без аватара бота и имеет `authorId = 0`. Такие сообщения нельзя обновить или удалить через бота. **Текст обрезается:** если сообщение длиннее 20 000 символов, Битрикс24 обрежет текст и добавит ` (...)`. **Пересылка (forwardIds):** формат — объект `{uuid: messageId}`, где uuid — произвольная строка, а messageId — ID исходного сообщения. Бот может пересылать только сообщения из чатов, где он является участником. ## Смотрите также - [Обновить сообщение](/docs/bots/messages/update) - [Форматирование текста](/docs/bots/messages/formatting) - [Клавиатура](/docs/bots/messages/keyboard) - [ATTACH-блоки](/docs/bots/messages/attach) - [События](/docs/bots/events) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Update ## Обновить сообщение `PATCH /v1/bots/:botId/messages/:messageId` Обновляет ранее отправленное ботом сообщение. Бот может обновлять только собственные сообщения. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `message` | string | Новый текст сообщения (до 20 000 символов). Поддерживает [BB-коды](/docs/bots/messages/formatting) | | `keyboard` | array | Новая [клавиатура](/docs/bots/messages/keyboard). Для удаления передайте `"N"` | | `attach` | array/object | Новые [ATTACH-блоки](/docs/bots/messages/attach) | | `urlPreview` | boolean | Показывать превью ссылок | ## Примеры ### curl — личный ключ ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42/messages/1502 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": "Обновлённый текст сообщения", "keyboard": [ { "TEXT": "Готово", "BG_COLOR_TOKEN": "primary", "DISABLED": "Y" } ] }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42/messages/1502 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "message": "Обновлённый текст сообщения", "keyboard": [ { "TEXT": "Готово", "BG_COLOR_TOKEN": "primary", "DISABLED": "Y" } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1502', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ message: 'Обновлённый текст сообщения', keyboard: [ { TEXT: 'Готово', BG_COLOR_TOKEN: 'primary', DISABLED: 'Y', }, ], }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1502', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ message: 'Обновлённый текст сообщения', keyboard: [ { TEXT: 'Готово', BG_COLOR_TOKEN: 'primary', DISABLED: 'Y', }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном обновлении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 502 — Битрикс24 вернул ошибку (например, сообщение не найдено): ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Message not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Системные сообщения нельзя обновить:** сообщения, отправленные с `system: true`, имеют `authorId = 0` и не принадлежат боту с точки зрения прав. Битрикс24 вернёт ошибку. **Удаление клавиатуры:** передайте `"keyboard": "N"` чтобы убрать клавиатуру с сообщения. ## Смотрите также - [Отправить сообщение](/docs/bots/messages/send) - [Удалить сообщение](/docs/bots/messages/delete) - [Клавиатура](/docs/bots/messages/keyboard) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Troubleshooting # Диагностика проблем бот-платформы Если бот не отвечает на сообщения, начните с разделов ниже. Каждый сценарий — отдельный набор проверок с готовыми curl-командами и эталонными ответами от Вайбкод. ## Сценарии диагностики - [События не приходят](#события-не-приходят) — пользователь пишет боту, но `GET /v1/bots/:botId/events` возвращает пустой массив - [TOKEN_MISSING при ключе авторизации](#token_missing-при-ключе-авторизации) — `vibe_app_…` отправлен без `Authorization: Bearer` - [Пустые events подряд](#пустые-events-подряд) — `success: true`, но `nextOffset` не двигается - [BITRIX_ERROR: User is not subscribed](#bitrix_error-user-is-not-subscribed) — `withUserEvents=true` без предварительной подписки - [INTERNAL_ERROR при опросе событий](#internal_error-при-опросе-событий) — временная ошибка прокси и схема повтора с растущей паузой - [Бот отключён (BOT_DISABLED)](#бот-отключён-bot_disabled) — автоматическое отключение по `AUTH_FAILURES` или `PORTAL_DELETED` - [Отличия fetch от webhook](#отличия-fetch-от-webhook) — разница форматов данных и поведения при доставке событий - [Стикеры](#стикеры) — ограничение платформы - [Куда обратиться](#куда-обратиться) — что приложить к тикету в поддержку --- ## События не приходят Симптом: пользователь пишет боту в чате Битрикс24, бот не отвечает, `GET /v1/bots/:botId/events` возвращает `events: []`. ### Чек-лист по порядку 1. **Бот зарегистрирован и активен.** `GET /v1/bots/:botId` возвращает `success: true` с полями `bot.id`, `bot.code`, `bot.eventMode`. Если 404 — бот не зарегистрирован, выполните `POST /v1/bots`. 2. **`eventMode: "fetch"`.** Проверяется в ответе шага 1. Если `webhook` — события через polling не приходят, бот пушит их на `webhookUrl`. 3. **Тип бота соответствует сценарию.** Бот типа `bot` получает только сообщения с `@упоминанием` и личные сообщения. Для приёма всех сообщений в чате нужен тип `personal` или `supervisor` — указывается при регистрации в поле `type` и не меняется потом. Если ожидаете все сообщения, а тип `bot`, события придут только при `@упоминании`. 4. **Бот добавлен в чат.** Бот получает события только из чатов, где он состоит. Для личного диалога это происходит при первом обращении пользователя к боту. Для группового чата бота нужно добавить явно через `POST /v1/bots/:botId/chats/:dialogId/users`. 5. **Пользователь пишет именно этому боту.** Если на портале есть несколько ботов, проверьте `code` бота, к которому идёт обращение в чате, и сравните с `code` в ответе `GET /v1/bots/:botId`. Сообщения другому боту в очередь этого бота не попадут. 6. **После 5+ пустых опросов проверьте поле `hint`** в ответе `GET /v1/bots/:botId/events`. Платформа добавляет диагностическую подсказку, если очередь пуста подряд. 7. **Перепривяжите подписку на события.** Если бот активен (в чаты приходят сообщения), но очередь пуста и появилось поле `hint`, вызовите [`POST /v1/bots/:botId/resubscribe`](/docs/bots/management/resubscribe). Перепривязка восстанавливает доставку и сохраняет привязки открытых линий и приветственного бота, в отличие от повторной регистрации через `POST /v1/bots`. Если все 7 пунктов пройдены, а очередь по-прежнему пуста — это значит, что портал Битрикс24 не направляет события боту. Соберите данные по разделу [Куда обратиться](#куда-обратиться) и отправьте тикет. --- ## TOKEN_MISSING при ключе авторизации Симптом: ```json { "success": false, "error": { "code": "TOKEN_MISSING", "message": "API key has no tokens configured." } } ``` ### Причина Ключ `vibe_app_…` отправлен без заголовка `Authorization: Bearer `. Ключ авторизации работает в паре с токеном пользовательской сессии — без Bearer у запроса нет контекста, от чьего имени обращаться к Битрикс24. ### Решение Личный ключ `vibe_api_…` — Bearer не нужен: ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/events \ -H "X-Api-Key: YOUR_API_KEY" ``` Ключ авторизации `vibe_app_…` — обязательно с Bearer: ```bash curl https://vibecode.bitrix24.tech/v1/bots/42/events \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` Получение `USER_SESSION_TOKEN` для OAuth-приложения — см. [Ключи и авторизация](/docs/keys-auth). --- ## Пустые events подряд Симптом: ответ корректный, ошибок нет, но `events: []`, `nextOffset === storedOffset`, `persisted: false`. ### Что значат поля ответа - `persisted: false` — курсор `lastOffset` в базе Вайбкод не сдвинулся, потому что Битрикс24 не отдал ни одного события. - `nextOffset === storedOffset` — нечего обрабатывать. - `hint` появляется после 5+ пустых опросов подряд — диагностическая подсказка. ### Это нормально, если - бот только что зарегистрирован — никто ещё не писал - очередь пуста — клиенты прочитали все сообщения - между опросами нет активности в чатах с ботом. ### Когда нужно перейти к диагностике Если выполняется хотя бы одно условие — возвращайтесь к разделу [События не приходят](#события-не-приходят): - в чате есть непрочитанные сообщения боту - прошло больше минуты с момента отправки сообщения - появилось поле `hint`. --- ## BITRIX_ERROR: User is not subscribed Симптом: `GET /v1/bots/:botId/events?withUserEvents=true` отдаёт 502 с этим сообщением. ### Причина User-события (типы `ONIMV2*` — изменения в чатах, реакции пользователей) требуют отдельной подписки. Без подписки параметр `withUserEvents=true` не активирует доставку. ### Решение Подписаться один раз перед использованием `withUserEvents=true`. Полный порядок настройки и список событий — в разделе [User-события](/docs/bots/events/user-events). После подписки `GET /v1/bots/:botId/events?withUserEvents=true` начинает отдавать user-события вместе с bot-событиями в одном массиве. --- ## INTERNAL_ERROR при опросе событий Симптом: ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` ### Что делать 1. **Не повторять запрос сразу.** Частые повторы без паузы могут продлить состояние ошибки и сами стать причиной перегрузки. 2. **Использовать растущую паузу между попытками** — старт 5 секунд, удвоение на каждой следующей неудаче, потолок 60 секунд. После успешного ответа интервал сбрасывается к рабочему значению (2-5 секунд между опросами). 3. **Не сбрасывать `offset`.** Сохранённый курсор не пострадал — продолжайте с того же значения. Сброс приведёт к повторной обработке уже доставленных событий. 4. **Если ошибка не уходит после нескольких циклов задержки** — отправьте тикет в поддержку с `botId`, временем первого появления, последним успешным `nextOffset` и интервалом между попытками. Не наращивайте частоту запросов «на всякий случай» — это ухудшит ситуацию. ### Готовый шаблон с растущей паузой ```javascript const BOT_ID = 42 const API_KEY = 'YOUR_API_KEY' const BASE = 'https://vibecode.bitrix24.tech/v1' let backoffMs = 5000 while (true) { try { const res = await fetch(`${BASE}/bots/${BOT_ID}/events`, { headers: { 'X-Api-Key': API_KEY }, }) const json = await res.json() if (!json.success && json.error?.code === 'INTERNAL_ERROR') { console.warn(`INTERNAL_ERROR — пауза ${backoffMs} мс`) await new Promise(r => setTimeout(r, backoffMs)) backoffMs = Math.min(backoffMs * 2, 60000) continue } backoffMs = 5000 for (const event of json.data?.events ?? []) { // обработка события } } catch { await new Promise(r => setTimeout(r, backoffMs)) backoffMs = Math.min(backoffMs * 2, 60000) } await new Promise(r => setTimeout(r, 3000)) } ``` --- ## Бот отключён (BOT_DISABLED) Симптом: ```json { "success": false, "error": { "code": "BOT_DISABLED", "message": "Bot is disabled (reason: …)" } } ``` HTTP-код — `410 Gone`. Затронуты все эндпоинты бота: события, сообщения, чаты, команды, обновление, удаление. ### Возможные причины (поле `reason`) - `AUTH_FAILURES` — 10 подряд `401 INVALID_CREDENTIALS` от Битрикс24. Платформа защищает портал от шумных запросов и автоматически отключает бота со сломанной авторизацией. - `PORTAL_DELETED` — портал Битрикс24 удалён или подтверждён недоступным. ### Решение `AUTH_FAILURES` — вызовите [`POST /v1/bots/:botId/reauth`](/docs/bots/management/reauth). Проверка подтверждает доступ бота, при необходимости обновляет токен и снимает отключение. Если в ответ пришёл `410 REAUTH_REQUIRED` — доступ восстановить автоматически нельзя, ключ нужно авторизовать заново через OAuth или пересоздать личный ключ. Сбросить только счётчик ошибок авторизации, без проверки доступа, можно через `PATCH /v1/bots/:botId` с body `{"disabled": false}`: ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/bots/42 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"disabled": false}' ``` `PORTAL_DELETED` — бот восстанавливается автоматически, когда портал возвращается к статусу `ACTIVE`. Принудительное включение через `PATCH` для этой причины не требуется. `PATCH … {"disabled": true}` запрещён — вернётся `400 DISABLE_NOT_ALLOWED`. Отключение системное, для удаления используйте `DELETE /v1/bots/:botId`. --- ## Отличия fetch от webhook Вайбкод поддерживает два режима доставки событий: `fetch` (по умолчанию) и `webhook`. Режим задаётся полем `eventMode` при регистрации бота и не меняется после. | | `fetch` | `webhook` | |---|---|---| | Как работает | Клиент сам запрашивает события через `GET /v1/bots/:botId/events` | Битрикс24 пушит события HTTP POST на `webhookUrl` | | Типы значений | Нативные: `number`, `boolean`, `null` | Всё приходит строками (`"1"`, `"true"`, `""`) — следствие сериализации тела на стороне Битрикс24 | | Объект `bot` в событии | Без поля `auth` | Содержит `auth` с OAuth-токенами портала | | Тайм-аут | Нет (long-poll) | 10 секунд — Битрикс24 ждёт 200 от вашего сервера и закрывает соединение | | Повторная доставка | Серверное хранение offset — пропустить событие нельзя | Нет автоматических повторов при таймауте или 5xx ответе | | Когда выбирать | Большинство сценариев, особенно AI-агенты | Когда нужно минимальное время реакции и есть публично доступный сервер | **При `eventMode: "webhook"` `GET /v1/bots/:botId/events` всегда возвращает пустой массив** — события доставляются напрямую на `webhookUrl`, в polling они не попадают. --- ## Стикеры Боты **не могут отправлять** стикеры пользователям. Это ограничение Bot API v2 Битрикс24. Боты могут **получать** стикеры: если пользователь отправил стикер, событие `ONIMBOTV2MESSAGEADD` придёт, но поле `message.text` будет пустым. Реагировать на стикеры можно, отправив текстовое сообщение или вложение через `POST /v1/bots/:botId/messages`. --- ## Куда обратиться Если ни один из разделов выше не помог — оставьте тикет в разделе [Обратная связь](/docs/feedback). К тикету приложите: - `botId` (число) - ответ `GET /v1/bots/:botId` целиком - последние 3 ответа `GET /v1/bots/:botId/events` с полями `nextOffset`, `storedOffset`, `persisted`, `hint` - время первого появления симптома (UTC) - тип ключа (`vibe_api_…` или `vibe_app_…`) — без самого ключа - скриншот чата с непрочитанным сообщением, если есть. --- ## Смотрите также - [Бот-платформа](/docs/bots) - [Получить события (polling)](/docs/bots/events/polling) - [User-события](/docs/bots/events/user-events) - [Зарегистрировать бота](/docs/bots/management/create) - [Ключи и авторизация](/docs/keys-auth) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Ui # Интерфейс Ставьте реакции на сообщения, показывайте индикатор набора текста и управляйте полем ввода в чате. **Скоуп:** `imbot` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` ## Операции - [Добавить реакцию](./ui/reaction-add.md) — `POST /v1/bots/:botId/messages/:messageId/reactions` - [Удалить реакцию](./ui/reaction-delete.md) — `DELETE /v1/bots/:botId/messages/:messageId/reactions` - [Индикатор набора](./ui/typing.md) — `POST /v1/bots/:botId/typing` - [Управление полем ввода](./ui/text-field.md) — `POST /v1/bots/:botId/text-field` ## Справочники - [Коды реакций](./ui/reactions.md) — 48 доступных кодов --- # Bot: Reaction Add ## Добавить реакцию `POST /v1/bots/:botId/messages/:messageId/reactions` Добавляет реакцию бота на сообщение. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `reaction` | string | да | Код реакции (см. [Коды реакций](/docs/bots/ui/reactions)) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reaction": "like" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "reaction": "like" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ reaction: 'like' }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ reaction: 'like' }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном добавлении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Коды реакций](/docs/bots/ui/reactions) - [Удалить реакцию](/docs/bots/ui/reaction-delete) - [Отправить сообщение](/docs/bots/messages/send) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Reaction Delete ## Удалить реакцию `DELETE /v1/bots/:botId/messages/:messageId/reactions` Удаляет реакцию бота с сообщения. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `reaction` | string | да | Код реакции для удаления (см. [Коды реакций](/docs/bots/ui/reactions)) | ## Примеры ### curl — личный ключ ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reaction": "like" }' ``` ### curl — OAuth-приложение ```bash curl -X DELETE https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "reaction": "like" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ reaction: 'like' }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/messages/1501/reactions', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ reaction: 'like' }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном удалении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 403 — бот принадлежит другому ключу: ```json { "success": false, "error": { "code": "BOT_ACCESS_DENIED", "message": "This bot belongs to a different API key" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Коды реакций](/docs/bots/ui/reactions) - [Добавить реакцию](/docs/bots/ui/reaction-add) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Reactions ## Коды реакций 48 доступных кодов для [добавления](/docs/bots/ui/reaction-add) и [удаления](/docs/bots/ui/reaction-delete) реакций. | Код | Описание | |-----|---------| | `like` | Нравится | | `dislike` | Не нравится | | `faceWithTearsOfJoy` | До слёз | | `redHeart` | Сердечко | | `neutralFace` | Равнодушен | | `fire` | Огонь! | | `cry` | Жаль | | `slightlySmilingFace` | Улыбаюсь | | `winkingFace` | Подмигиваю | | `laugh` | Смеюсь | | `kiss` | Восхищаюсь | | `wonder` | Шок | | `slightlyFrowningFace` | Грущу | | `loudlyCryingFace` | Плачу | | `faceWithStuckOutTongue` | Язык | | `faceWithStuckOutTongueAndWinkingEye` | Дразнюсь | | `smilingFaceWithSunglasses` | Круто | | `confusedFace` | Ну не знаю | | `flushedFace` | Смущаюсь | | `thinkingFace` | Сомневаюсь | | `angry` | Злюсь | | `smilingFaceWithHorns` | Злорадно | | `faceWithThermometer` | Болею | | `facepalm` | Без комментариев | | `poo` | Фу | | `flexedBiceps` | Мощно | | `clappingHands` | Великолепно | | `raisedHand` | Дай пять | | `smilingFaceWithHeartEyes` | Красота | | `smilingFaceWithHearts` | Обожаю | | `pleadingFace` | Умоляю | | `relievedFace` | Дзен | | `foldedHands` | Спасибо | | `okHand` | ОК | | `signHorns` | Рок! | | `loveYouGesture` | Всё круто | | `clownFace` | Клоун | | `partyingFace` | Поздравляю | | `questionMark` | Вопрос | | `exclamationMark` | Внимание | | `lightBulb` | Идея | | `bomb` | Бомба | | `sleepingSymbol` | Засыпаю | | `crossMark` | Отмена | | `whiteHeavyCheckMark` | Готово | | `eyes` | Глаза | | `handshake` | Договорились | | `hundredPoints` | Поддерживаю | ## Смотрите также - [Добавить реакцию](/docs/bots/ui/reaction-add) - [Удалить реакцию](/docs/bots/ui/reaction-delete) - [События](/docs/bots/events) --- # Bot: Text Field ## Управление полем ввода `POST /v1/bots/:botId/text-field` Включает или отключает поле ввода текста в чате с ботом. Полезно, если бот принимает ввод только через клавиатуру (кнопки). ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `dialogId` | string | да | ID диалога: числовой ID пользователя для личных, `chatXXX` для групповых | | `enabled` | boolean | да | `true` — включить поле ввода, `false` — отключить | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/text-field \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "enabled": false }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/text-field \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "enabled": false }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/text-field', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', enabled: false }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/text-field', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', enabled: false }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешном изменении | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Индикатор набора](/docs/bots/ui/typing) - [Клавиатура](/docs/bots/messages/keyboard) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # Bot: Typing ## Индикатор набора `POST /v1/bots/:botId/typing` Показывает индикатор статуса в чате. Вызывайте перед отправкой ответа, чтобы пользователь видел, что бот работает. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `dialogId` | string | да | — | ID диалога: числовой ID пользователя для личных, `chatXXX` для групповых | | `statusMessageCode` | string | нет | — | Код статуса действия (см. [таблицу ниже](#коды-статуса)). Без параметра — стандартный индикатор «печатает» | | `duration` | number | нет | — | Длительность отображения в секундах (1-600) | ## Коды статуса | Код | Описание | |-----|---------| | `IMBOT_AGENT_ACTION_THINKING` | Думает | | `IMBOT_AGENT_ACTION_SEARCHING` | Ищет | | `IMBOT_AGENT_ACTION_GENERATING` | Генерирует | | `IMBOT_AGENT_ACTION_ANALYZING` | Анализирует | | `IMBOT_AGENT_ACTION_PROCESSING` | Обрабатывает | | `IMBOT_AGENT_ACTION_TRANSLATING` | Переводит | | `IMBOT_AGENT_ACTION_CONNECTING` | Подключается | | `IMBOT_AGENT_ACTION_CHECKING` | Проверяет | | `IMBOT_AGENT_ACTION_CALCULATING` | Вычисляет | | `IMBOT_AGENT_ACTION_READING_DOCS` | Читает документацию | | `IMBOT_AGENT_ACTION_COMPOSING` | Составляет ответ | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/typing \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "statusMessageCode": "IMBOT_AGENT_ACTION_THINKING", "duration": 30 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/bots/42/typing \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "dialogId": "chat123", "statusMessageCode": "IMBOT_AGENT_ACTION_THINKING", "duration": 30 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/typing', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', statusMessageCode: 'IMBOT_AGENT_ACTION_THINKING', duration: 30, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/typing', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ dialogId: 'chat123', statusMessageCode: 'IMBOT_AGENT_ACTION_THINKING', duration: 30, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.result` | boolean | `true` при успешной отправке | ## Пример ответа ```json { "success": true, "data": { "result": true } } ``` ## Пример ответа при ошибке 404 — бот не найден: ```json { "success": false, "error": { "code": "BOT_NOT_FOUND", "message": "Bot 999 not found. Register it first via POST /v1/bots." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_BOT_ID` | `botId` не является числом | | 404 | `BOT_NOT_FOUND` | Бот с таким ID не найден | | 403 | `BOT_ACCESS_DENIED` | Бот принадлежит другому API-ключу | | 502 | `BITRIX_ERROR` | Ошибка Битрикс24 (текст ошибки в `message`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imbot` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **AI-боты:** используйте `statusMessageCode` для информативного статуса. Например, `IMBOT_AGENT_ACTION_ANALYZING` при обработке запроса, затем `IMBOT_AGENT_ACTION_COMPOSING` перед отправкой ответа. **Автоматическое скрытие:** индикатор исчезает при отправке сообщения ботом или по истечении `duration`. ## Смотрите также - [Управление полем ввода](/docs/bots/ui/text-field) - [Отправить сообщение](/docs/bots/messages/send) - [Бот-платформа](/docs/bots) - [Лимиты и оптимизация](/docs/optimization) --- # OpenClaw: Advanced # Расширенная настройка коннектора Битрикс24 Страница описывает продвинутые параметры коннектора `bitrix24` плагина `@ihazz/bitrix24` — политики доступа, наблюдение за чатами, несколько аккаунтов в одном инстансе и полную таблицу конфигурации. Минимальная конфигурация для типового запуска описана на странице [Коннектор Битрикс24](./connector.md); расширенная настройка нужна только когда требуется тонкая подстройка под конкретный сценарий. ## Идентификация бота `botToken` — токен, по которому Битрикс24 узнаёт бота среди остальных приложений на портале. Если не задан в конфигурации, коннектор вычисляет его автоматически из API-ключа. Указывать `botToken` в конфигурации явно нужно только тогда, когда исходные учётные данные могут поменяться, — иначе после смены ключа на портале появится новый бот вместо обновления существующего. `botCode` — внутренний идентификатор бота. По умолчанию коннектор регистрирует бота как `openclaw_`, где `` — идентификатор пользователя, к которому привязан ключ. При повторной регистрации с тем же `botCode` коннектор подхватывает существующего бота. Чтобы развернуть на одном портале сразу несколько ботов на одном ключе, добавляются суффиксы `_2`, `_3` и так далее. ## Политики доступа ### Личные сообщения | Политика | Кто может писать боту в личных сообщениях | |----------|-------------------------------------------| | `keyOwner` (по умолчанию, рекомендуется) | Только владелец ключа — пользователь портала, к которому привязан `vibe_api_…` или `vibe_app_…`. | | `pairing` | Любой пользователь портала после прохождения привязки через бот. | | `allowlist` | Только пользователи из списка `allowFrom`. | | `open` | Любой пользователь портала. | ### Групповые чаты | Политика | Кто может упоминать бота в групповом чате | |----------|------------------------------------------| | `disabled` | В групповых чатах бот не работает. При добавлении бота в чат он отправляет короткое уведомление и выходит. | | `keyOwner` (по умолчанию, рекомендуется) | Только владелец ключа. | | `pairing` | Только пользователи, прошедшие привязку через бот. В публичном групповом чате привязка не запускается — бот отправит уведомление. | | `allowlist` | Только пользователи из объединённого списка `allowFrom` и `groups..allowFrom`. | | `open` | Любой пользователь, который имеет доступ к чату. | `groupAllowFrom` отдельно ограничивает, в каких чатах разрешено работать боту. Чат, упомянутый явно в `groups`, считается разрешённым автоматически. ### Переопределения для конкретных групп ```json { "groups": { "chat615": { "groupPolicy": "open", "requireMention": false }, "chat208": { "watch": [ { "userId": "77", "topics": ["договор", "оплата"], "mode": "reply" } ] }, "*": { "requireMention": true } } } ``` Порядок применения: точное совпадение `dialogId` имеет приоритет над числовым `chatId`, оба перекрывают `*`. ## Режим наблюдения `agentMode: true` включает пассивное чтение всей истории группового чата без ответов от лица бота. Коннектор подписывает владельца ключа на пользовательские события Битрикс24 Мессенджера и опрашивает их вместе с обычными событиями бота. Когда применять: - Бот молчит в групповом чате, но запоминает контекст и отвечает в личных сообщениях, если владелец задал вопрос «что обсуждали в чате X». - В сочетании с `agentWatch` — следить за чатом и присылать владельцу уведомления, когда упомянули нужного человека или ключевую тему. ```json { "agentMode": true, "agentWatch": { "chat615": [ { "userId": "77", "topics": ["договор", "оплата"], "mode": "notifyOwnerDm" } ] } } ``` В режиме `notifyOwnerDm` бот отправляет владельцу личное сообщение со ссылкой на оригинал. Если нативная пересылка через Битрикс24 не работает — отправляет цитату как запасной путь. Подписка на пользовательские события действует на весь портал. В конфигурации с несколькими аккаунтами на одном портале — `agentMode: true` ставится только на одном аккаунте, иначе подписки будут конфликтовать. ## Несколько аккаунтов В одном инстансе OpenClaw можно запустить несколько ботов — например, для разных ролей на одном портале: ```json { "channels": { "bitrix24": { "provider": "vibecode", "providerConfig": { "apiKey": "MAIN_KEY" }, "botName": "Помощник", "agentMode": true, "accounts": { "second": { "providerConfig": { "apiKey": "SECOND_KEY" }, "botName": "Аналитик", "agentMode": false } } } } } ``` Корневой блок описывает основной аккаунт, дополнительные идут в `accounts` и наследуют корневые настройки, переопределяя нужные. Ограничение: рабочее пространство OpenClaw, история сессий и хранилище файлов общие для всех аккаунтов в одном инстансе. Для разных порталов на боевом стенде — отдельный инстанс OpenClaw на каждый, чтобы данные не пересекались. ## Полная таблица параметров Полный список параметров блока `channels.bitrix24` в `openclaw.json`. Все параметры опциональны, кроме `provider` и `providerConfig`. | Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | `provider` | string | — | Провайдер подключения. На странице описан только `vibecode` — единственный, с которым работает скилл агента. | | `providerConfig` | object | — | `{ apiKey, baseUrl }`, где `baseUrl` — `https://vibecode.bitrix24.tech/v1`. | | `botName` | string | `OpenClaw` | Отображаемое имя бота в чате. | | `botCode` | string | `openclaw_` | Внутренний идентификатор. Полезно фиксировать вручную, если на одном портале несколько ботов. | | `botAvatar` | string | — | Аватар бота в формате base64. | | `botToken` | string | авто из `apiKey` | Токен бота для Битрикс24. Указывается явно, если ключ может смениться и нужно сохранить идентичность бота. | | `dmPolicy` | enum | `keyOwner` | Политика доступа в личных сообщениях: `keyOwner`, `pairing`, `allowlist`, `open`. | | `groupPolicy` | enum | `keyOwner` | Политика доступа в групповых чатах: `disabled`, `keyOwner`, `pairing`, `allowlist`, `open`. | | `requireMention` | boolean | `true` | Бот отвечает в группах только при упоминании. Сообщения без упоминания всё равно попадают в контекст. | | `allowFrom` | string[] | — | Список разрешённых отправителей для `dmPolicy: "allowlist"` и как источник одобренных пользователей для `pairing`. | | `groupAllowFrom` | string[] | — | Список разрешённых групповых чатов. Значения — `dialogId` (`chat208`) или числовой `chatId` (`208`). | | `groups` | object | — | Переопределения политик для конкретных групп. Ключ — `dialogId`, числовой `chatId` или `*` для всех. | | `agentMode` | boolean | `false` | Режим наблюдения: подписка на пользовательские события + чтение всей истории чата. | | `agentWatch` | object | — | Правила наблюдения за упоминаниями в режиме `agentMode`. | | `historyLimit` | integer | `100` | Сколько последних сообщений на разговор хранить в оперативной памяти. | | `pollingIntervalMs` | integer | `3000` | Базовый интервал опроса событий, миллисекунды. | | `pollingFastIntervalMs` | integer | `100` | Ускоренный интервал, когда есть необработанные события. | | `showTyping` | boolean | `true` | Показывать индикатор набора перед ответом. | | `urlRewriteMap` | object | — | Подмена origin'а в URL файлов. Ключи — исходные домены, значения — замены. Полезно, когда Битрикс24 возвращает внутренние имена хостов. | | `verboseLog` | boolean | `false` | Подробное логирование событий и вызовов API. Только для разработки. | | `enabled` | boolean | `true` | Включает или отключает аккаунт. | | `capabilities` | string[] | `["inlineButtons", "reactions"]` | Список включённых возможностей чата. По умолчанию обе включены; явное указание в конфиге рекомендуется для совместимости с разными версиями OpenClaw. | | `accounts` | object | — | Дополнительные аккаунты для запуска нескольких ботов в одном инстансе OpenClaw. | ## Смотрите также - [Коннектор Битрикс24](./connector.md) — основные параметры и установка - [Скилл Битрикс24](./skill.md) — доступ агента к API портала - [Пошаговая инструкция](./scenario.md) — установка и проверка - [Подключение Битрикс24 к OpenClaw](../openclaw.md) — обзор раздела --- # OpenClaw: Connector # Коннектор Битрикс24 для OpenClaw Коннектор Битрикс24 — часть плагина `@ihazz/bitrix24`, которая регистрирует OpenClaw как чат-бота на портале и пересылает сообщения между Битрикс24 Мессенджером и агентом. Поддерживает личные сообщения, групповые чаты с политиками доступа, реакции, файлы, инлайн-кнопки и пассивный режим наблюдения за чатами. ## Что делает После настройки коннектор: - Регистрирует OpenClaw как бота через API Вайбкод — пользователь не выполняет регистрацию вручную. - Опрашивает входящие события через `GET /v1/bots/:botId/events` каждые несколько секунд и передаёт сообщения агенту. - Преобразует Markdown-ответы агента в BBCode Битрикс24 при отправке. - Делит длинные сообщения на части по 20 000 символов (предел API мессенджера Битрикс24). - Кеширует историю переписки в оперативной памяти — агент видит контекст разговора без дополнительных вызовов API. Регистрация бота, опрос событий, отправка ответов — внутренние операции коннектора. Пользователю достаточно создать API-ключ в личном кабинете Вайбкод, положить его в `openclaw.json` и запустить OpenClaw. ## Установка Установить плагин в OpenClaw: ```bash openclaw plugins install @ihazz/bitrix24@latest ``` Разрешить плагин в `openclaw.json`: ```json { "plugins": { "allow": ["bitrix24"] } } ``` Дальше — настройка канала. ## Минимальная конфигурация Ниже — только блок `channels.bitrix24`. Он входит в общий `openclaw.json`, где также нужны блоки `plugins`, `gateway`, `agents`, `models` и `tools` — без них OpenClaw v2026.4.1 либо подвисает на старте, либо не может работать с ботом. Полный шаблон `openclaw.json` со всеми блоками — на странице [Пошаговая инструкция](./scenario.md#шаг-4-настроить-openclaw-json). ```json { "channels": { "bitrix24": { "enabled": true, "provider": "vibecode", "providerConfig": { "apiKey": "YOUR_API_KEY", "baseUrl": "https://vibecode.bitrix24.tech/v1" }, "botName": "Помощник", "botCode": "openclaw_helper", "dmPolicy": "keyOwner", "showTyping": true, "capabilities": ["inlineButtons", "reactions"] } } } ``` `YOUR_API_KEY` — ключ формата `vibe_api_…` или `vibe_app_…` из [личного кабинета Вайбкод](../keys-auth.md). Скоупы на ключе: обязательно `imbot` (бот-платформа) и `vibe:ai` (LLM агента через AI Router), плюс доменные скоупы под задачи агента — `crm`, `tasks`, `calendar` и так далее. `baseUrl` указывает корень API Вайбкод и подставляется как есть. `botCode` — уникальный код бота, ASCII. Используется при регистрации; повторный запуск с тем же кодом подхватывает существующего бота. ## Основные параметры Шесть ключевых параметров блока `channels.bitrix24`. Полный список из 22 параметров, включая политики доступа, режим наблюдения и переопределения групп, — на странице [Расширенная настройка коннектора](./advanced.md). | Параметр | По умолчанию | Описание | |----------|--------------|----------| | `provider` | — | Всегда `vibecode`. Подключение через прокси Вайбкод. | | `providerConfig` | — | `{ apiKey, baseUrl }`. `apiKey` — ключ Вайбкод, `baseUrl` — `https://vibecode.bitrix24.tech/v1`. | | `botName` | `OpenClaw` | Отображаемое имя бота в Битрикс24 Мессенджере. | | `botCode` | `openclaw_` | Уникальный идентификатор бота. Фиксировать вручную, если на одном портале несколько ботов. | | `dmPolicy` | `keyOwner` | Кто может писать боту в личных сообщениях. По умолчанию — только владелец ключа. | | `groupPolicy` | `keyOwner` | Кто может упоминать бота в групповых чатах. По умолчанию — только владелец ключа. | | `requireMention` | `true` | Бот отвечает в группах только при упоминании. Без упоминания сообщение всё равно попадает в контекст. | | `showTyping` | `true` | Показывать индикатор набора перед ответом. | ## Возможности чата - **Реакции** на сообщения — преобразование эмодзи в код реакции Битрикс24 происходит на стороне коннектора. - **Инлайн-кнопки** через `channelData.bitrix24.keyboard` (нативный формат Битрикс24) или универсальный формат OpenClaw `channelData.telegram.buttons` с автоматической конвертацией. - **Action-ссылки в Markdown** — `send:`, `put:`, `tel:`, `user:`, `chat:`, `context:`, `timestamp:` — преобразуются в нативный BBCode Битрикс24. - **Rich ATTACH-блоки** — карточки `MESSAGE`, `LINK`, `IMAGE`, `FILE`, `DELIMITER`, `GRID`, `USER` через `channelData.bitrix24.attach` или `channelData.bitrix24.attachments`. Это отдельный канал доставки от стандартной загрузки файлов через `mediaUrl`. - **Загрузка и скачивание файлов** через бот-платформу. - **Нативные ответы и пересылки** через бот-платформу с полем `replyId` — коннектор сохраняет контекст ответа в оперативной памяти и подгружает сообщения через API при необходимости. - **Редактирование и удаление** сообщений через бот-платформу. - **Slash-команды** — регистрация и реакция на их вызов в чате. - **Поточная доставка** ответа: коннектор обновляет одно и то же сообщение в чате по мере того, как агент генерирует текст, ограничивая частоту обновлений. Полный список эндпоинтов, через которые работает коннектор — [Бот-платформа](../bots.md). ## Хранение ключа в переменной окружения Чтобы не держать ключ открытым текстом в `openclaw.json`, коннектор поддерживает ссылку на переменную окружения: ```json { "channels": { "bitrix24": { "provider": "vibecode", "providerConfig": { "apiKey": { "source": "env", "id": "B24_VIBE_API_KEY" } } } } } ``` Объект указывается полем `source: "env"` и `id` с именем переменной окружения. На старте плагин подменяет ссылку фактическим значением. ## Совместимость с OpenClaw | Версия OpenClaw | Статус | |-----------------|--------| | **v2026.4.1** | Минимальная поддерживаемая. На ней проверены все возможности коннектора. | | v2026.4.5 | Содержит известную проблему: скиллы плагинов не разрешаются из директории расширений, бот может не отвечать на сообщения. До исправления оставаться на v2026.4.1. | ## Проверка работы 1. Запустить OpenClaw с включённым плагином. 2. Открыть личный чат с ботом в Битрикс24 Мессенджере, отправить сообщение. 3. Убедиться, что бот показывает индикатор набора и присылает ответ. 4. При политике `dmPolicy: "keyOwner"` — проверить, что ответ приходит только владельцу ключа, а другому пользователю бот не отвечает. 5. Добавить бота в групповой чат, разрешённый в `groupAllowFrom`, и упомянуть его через `[USER=]Имя[/USER]`. 6. Убедиться, что бот отвечает на упоминание и молчит без него (при `requireMention: true`). 7. Ответить на одно из своих недавних сообщений — проверить, что бот сохраняет контекст ответа. ## Что делать, если что-то не работает Список типичных симптомов и проверок собран на странице [Пошаговая инструкция](./scenario.md#что-делать-если-что-то-не-работает) — там же, где описана установка. ## Смотрите также - [Подключение Битрикс24 к OpenClaw](../openclaw.md) — обзор раздела - [Скилл Битрикс24](./skill.md) — доступ агента к API портала - [Пошаговая инструкция](./scenario.md) — установка и проверка - [Расширенная настройка коннектора](./advanced.md) — политики доступа, режим наблюдения, несколько аккаунтов, полная таблица параметров - [Бот-платформа](../bots.md) — справочник эндпоинтов - [Управление ботами](../bots/management.md) — регистрация, обновление, удаление - [Опрос событий](../bots/events.md) — формат событий - [Ключи и авторизация](../keys-auth.md) — типы ключей и скоупы --- # OpenClaw: Scenario # Как подключить Битрикс24 к OpenClaw — пошаговая инструкция Пошаговая инструкция, как подключить Битрикс24 к самостоятельно развёрнутому OpenClaw через npm-плагин `@ihazz/bitrix24`. После прохождения сценария OpenClaw-агент переписывается с пользователями портала и работает с данными CRM, задач, календаря через API Вайбкод. ## Что в итоге получится После выполнения шагов: - В Битрикс24 Мессенджере появится бот, имя и аватар которого вы укажете в `openclaw.json` или в личном кабинете Вайбкод. - Бот отвечает в личных сообщениях владельцу API-ключа. - Бот отвечает в групповых чатах, если его упомянуть, и пишет с учётом контекста переписки. - Агент через бота читает и обновляет данные портала: сделки, задачи, контакты, календарь — какие именно, определяется скоупами API-ключа. Время настройки — 15–30 минут при готовом OpenClaw на сервере. ## Что нужно подготовить 1. **Сервер с OpenClaw.** Развёрнутый и работающий инстанс. Документация по установке самого OpenClaw — на [сайте проекта OpenClaw](https://github.com/openclaw/openclaw#readme). Рекомендуемая версия для совместимости с плагином — v2026.4.1. 2. **Аккаунт на портале Битрикс24** с правами устанавливать приложения. Если портала ещё нет — [создать Битрикс24](https://www.bitrix24.ru/create.php) бесплатно. 3. **Аккаунт в Вайбкод** на том же портале — потребуется для создания API-ключа на шаге 3. Регистрация — на [vibecode.bitrix24.tech](https://vibecode.bitrix24.tech/). ## Шаг 1: Установить плагин в OpenClaw Подключиться к серверу с OpenClaw и поставить плагин: ```bash openclaw plugins install @ihazz/bitrix24@latest ``` Команда установит последнюю стабильную версию пакета и зарегистрирует канал `bitrix24` в OpenClaw. После установки в директории расширений OpenClaw появятся два каталога скиллов: `skills/bitrix24/` и `skills/vibe-platform/`. ## Шаг 2: Разрешить плагин в openclaw.json Открыть файл конфигурации OpenClaw и добавить разрешение для плагина: ```json { "plugins": { "allow": ["bitrix24"] } } ``` Без этой строки OpenClaw откажется загружать плагин при старте. ## Шаг 3: Получить API-ключ Вайбкод 1. Открыть [vibecode.bitrix24.tech](https://vibecode.bitrix24.tech/) и войти под учётной записью своего портала Битрикс24. 2. Перейти в раздел **Ключи API** в личном кабинете. 3. Нажать **Создать ключ** и выбрать скоупы: - `imbot` — обязательно, для регистрации бота и обмена сообщениями через бот-платформу. - `vibe:ai` — обязательно, для доступа агента к LLM-моделям Вайбкод через AI Router. - Доменные скоупы под задачи агента: `crm` для CRM, `tasks` для задач, `calendar` для расписания, `im` для пассивного режима наблюдения за чатами, и так далее. 4. Скопировать ключ формата `vibe_api_…` или `vibe_app_…` сразу после создания — он показывается только один раз. Подробное описание типов ключей, скоупов и безопасного хранения — [Ключи и авторизация](../keys-auth.md). ## Шаг 4: Настроить openclaw.json Открыть файл конфигурации OpenClaw и записать блок целиком. Шаблон ниже — рабочий минимум: подставьте API-ключ в двух местах, задайте `botName` и `botCode`, остальное оставьте как есть. ```json { "channels": { "bitrix24": { "enabled": true, "provider": "vibecode", "providerConfig": { "apiKey": "YOUR_API_KEY", "baseUrl": "https://vibecode.bitrix24.tech/v1" }, "botName": "Помощник", "botCode": "openclaw_helper", "dmPolicy": "keyOwner", "showTyping": true, "capabilities": ["inlineButtons", "reactions"] } }, "plugins": { "allow": ["bitrix24"] }, "gateway": { "bind": "lan", "mode": "local", "controlUi": { "enabled": true } }, "agents": { "defaults": { "model": "litellm/bitrixgpt-5-5-agent" } }, "models": { "mode": "replace", "providers": { "litellm": { "baseUrl": "https://vibecode.bitrix24.tech/v1/ai", "apiKey": "YOUR_API_KEY", "api": "openai-completions", "models": [{ "id": "bitrix/bitrixgpt-5.5-agent", "name": "bitrixgpt-5-5-agent", "maxTokens": 65535 }] } } }, "tools": { "exec": { "security": "full", "ask": "off" } } } ``` Что подставляет пользователь: - `apiKey` — ключ `vibe_api_…` из шага 3, в двух местах: `channels.bitrix24.providerConfig.apiKey` (для коннектора) и `models.providers.litellm.apiKey` (для LLM агента). - `botName` — отображаемое имя бота в Битрикс24 Мессенджере. - `botCode` — уникальный код бота, ASCII. Используется при регистрации; повторный запуск с тем же кодом подхватывает существующего бота, не создаёт нового. - `model` — в шаблоне зафиксирована BitrixGPT 5.5 Agent (`bitrix/bitrixgpt-5.5-agent`): та же модель, на которой работают Vibe-managed агенты — для консистентности поведения. Если нужна другая — поменять в `agents.defaults.model` и `models.providers.litellm.models[0].id`; список доступных моделей — [`GET /v1/ai/models`](../ai/models.md). - `maxTokens` — клиентский кап OpenClaw на длину ответа (`models.providers.litellm.models[0].maxTokens`). В шаблоне — `65535`, потолок BitrixGPT 5.5 Agent; уменьшайте, если нужны более короткие ответы или жёсткий бюджет токенов. Что критично оставить как есть: - `models.mode: "replace"` — без этого OpenClaw v2026.4.1 при старте 75–90 секунд тянет внешний каталог цен моделей и подвисает. - `tools.exec.security: "full"` и `ask: "off"` — без этого каждый shell-вызов агента упирается в окно подтверждения, у которого в Битрикс24 Мессенджере нет интерфейса. Полный доступ безопасно держать только на отдельном сервере. Чтобы не держать ключ открытым текстом в файле, его можно вынести в переменную окружения: ```json { "channels": { "bitrix24": { "providerConfig": { "apiKey": { "source": "env", "id": "B24_VIBE_API_KEY" } } } } } ``` И задать `B24_VIBE_API_KEY=vibe_api_…` в окружении процесса OpenClaw. Тот же формат поддерживается для второго вхождения ключа в `models.providers.litellm.apiKey`. Полный список параметров блока `channels.bitrix24` — [Расширенная настройка коннектора](./advanced.md). ## Шаг 5: Запустить OpenClaw и проверить работу Перезапустить OpenClaw, чтобы он подхватил обновлённую конфигурацию. В docker: ```bash docker restart openclaw ``` Без docker — перезапустить процесс OpenClaw тем способом, которым он был запущен. Дождаться, пока gateway откроет порт 18789 — это сигнал, что плагин загружен и готов принимать события. На старте плагин: - Прочитает API-ключ и зарегистрирует бота на портале через API Вайбкод. Регистрация может запаздывать до 10 минут — нормально для первого запуска. - Экспортирует переменные окружения `VIBE_KEY`, `VIBE_BASE_URL`, `VIBE_PLATFORM_URL` для скилла. - Подключит LLM-провайдер `litellm` к AI Router Вайбкод. - Начнёт опрашивать события Битрикс24 каждые несколько секунд. ### Проверить, что плагин жив ```bash curl -s -o /dev/null -w '%{http_code}' --max-time 3 http://127.0.0.1:18789/ ``` Любой код ответа кроме `000` означает, что gateway отвечает. Если OpenClaw запущен внутри docker — выполнить ту же команду через `docker exec openclaw curl …`. ### Проверить, что бот зарегистрирован на портале ```bash curl -H "X-Api-Key: YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/bots ``` В ответе должен быть бот с `code` из `openclaw.json`. Если ответ пустой — подождать до 10 минут после запуска. ### Проверить чат с ботом Открыть Битрикс24 Мессенджер и найти бота по имени из `botName`. Простой запрос: «Привет, что у меня сегодня?». Агент должен вызвать `GET /v1/calendar-events` и `GET /v1/tasks` и собрать единый ответ. Перед записывающим действием агент показывает короткое подтверждение и ждёт «да» — это правило скилла. Например, попросите создать тестовую задачу и проверьте, что бот сначала спрашивает «Создать задачу „Проверить отчёт“ для меня с дедлайном завтра?». Добавить бота в групповой чат, упомянуть его через `[USER=]Имя[/USER]` — он должен ответить только на упоминание. Если на любом шаге что-то не сработало — раздел [Что делать, если что-то не работает](#что-делать-если-что-то-не-работает) ниже. ## Что попробовать дальше После того как базовая связка работает — настроить агента под конкретные задачи. Варианты сценариев: - **Утренний разбор полётов руководителя.** Спросите бота «что у меня сегодня» — он соберёт события календаря и задачи на день, пометит просроченные, предупредит о пересечениях встреч. - **Менеджер по продажам в групповом чате отдела.** Подключите `groupPolicy: "open"` или `"allowlist"` для нужных чатов, упомяните бота — попросите показать зависшие сделки или создать сделку для нового клиента прямо в чате. - **Постановщик задач команды.** «Сделай задачу: проверить отчёт, ответственный — Сергей, до пятницы» — бот разберёт реплику, при необходимости задаст одно уточнение, покажет превью карточки задачи и создаст после подтверждения. Для каждого из этих сценариев — нужный скоуп на API-ключе и подходящие политики доступа в `openclaw.json`. Контракт скилла и базовые curl-вызовы — [Скилл Битрикс24](./skill.md). ## Что делать, если что-то не работает | Симптом | Что проверить | |---------|---------------| | OpenClaw не загружает плагин при старте | Файл `openclaw.json` валиден как JSON, в `plugins.allow` есть `"bitrix24"`. | | Старт OpenClaw подвисает на 75–90 секунд | В `openclaw.json` отсутствует `models.mode: "replace"` — рантайм тянет внешний каталог цен. Поправить конфиг по шаблону из шага 4 и перезапустить. | | Старт в docker подвисает на проверке локальной сети | Bonjour-проверка не завершается на виртуальной машине без поддержки локальных широковещательных сетей. В `.env` контейнера задать `OPENCLAW_DISABLE_BONJOUR=1` и перезапустить контейнер. | | Агент пишет «Approval required» в чат на любое действие | В `openclaw.json` отсутствует `tools.exec.security: "full"` или `ask: "off"`. У бота нет интерфейса для подтверждений — параметры должны быть выставлены как в шаблоне шага 4. | | Плагин запустился, но бот не появился в чате | Подождать до 10 минут — регистрация может запаздывать. Проверить, что API-ключ имеет скоупы `imbot` и `vibe:ai` через `curl -H "X-Api-Key: $VIBE_KEY" https://vibecode.bitrix24.tech/v1/me`. Список ботов на портале — `GET /v1/bots`. | | Бот вышел из группы сразу после добавления | `groupPolicy` запрещает работу в этой группе или чат не входит в `groupAllowFrom`. См. [Политики доступа](./connector.md#политики-доступа). | | Бот в группе, но не отвечает на сообщения | Проверить упоминание формата `[USER=]Имя[/USER]` или временно поставить `requireMention: false`. | | Сообщение «Доступ к Вайбкод истёк» в чате | API-ключ был отозван или пересоздан. Создать новый в личном кабинете и обновить `openclaw.json` в двух местах — `channels.bitrix24.providerConfig.apiKey` и `models.providers.litellm.apiKey`. | | Контекст ответа не находится | Сообщение могло выпасть из памяти при превышении `historyLimit`. Глобальный лимит — 1000 разговоров в LRU-кеше. | | Файл из чата не доходит до агента | Файл лежит вне рабочего пространства OpenClaw. Перенести в каталог рабочего пространства или в управляемую директорию медиа. | | Карточка `ATTACH` не отображается | Использовать `channelData.bitrix24.attach`, а не `mediaUrl`. Это разные каналы доставки. | Если симптом не из списка — проверить логи OpenClaw в режиме `verboseLog: true` и сверить ошибки с разделом [Коды ошибок бот-платформы](../bots.md). ## Смотрите также - [Подключение Битрикс24 к OpenClaw](../openclaw.md) — обзор раздела - [Скилл Битрикс24](./skill.md) — доступ агента к API портала - [Коннектор Битрикс24](./connector.md) — параметры конфигурации и политики - [Ключи и авторизация](../keys-auth.md) — типы ключей и скоупы - [Бот-платформа](../bots.md) — справочник эндпоинтов - [Коды ошибок](../errors.md) — общие коды ответов API - [Документация OpenClaw](https://github.com/openclaw/openclaw#readme) — установка самого OpenClaw --- # OpenClaw: Skill # Скилл Битрикс24 для OpenClaw Скилл Битрикс24 — часть плагина `@ihazz/bitrix24`, которая даёт агенту OpenClaw доступ к API портала Битрикс24. Через скилл агент работает со сделками, задачами, контактами, календарём и другими данными портала. ## Как устроен скилл Скилл — это инструкция для агента, как вызывать API Вайбкод. Он не добавляет в OpenClaw отдельный API-инструмент — вместо этого использует стандартный `exec`-инструмент с `curl`-командами и набором переменных окружения, которые плагин экспортирует на старте. Этот подход даёт три выгоды: - Агент видит реальные ответы API, а не обёртки. Если в ответе ошибка — агент читает сообщение и исправляет запрос. - Любой эндпоинт Вайбкод доступен без обновления плагина — скилл сам читает каталог методов через `GET /v1/guide` при первом обращении. - Документация на сайте Вайбкод — единственный источник правды для скилла. Когда страницы обновляются, агент получает актуальную информацию без релиза npm-пакета. ## Установка Установить плагин в OpenClaw: ```bash openclaw plugins install @ihazz/bitrix24@latest ``` Разрешить плагин в `openclaw.json`: ```json { "plugins": { "allow": ["bitrix24"] } } ``` После установки в директории расширений OpenClaw появятся два каталога: - `skills/bitrix24/` — служебный, для отладки и настройки самого плагина. - `skills/vibe-platform/` — рабочий, для работы агента с данными портала. ## Переменные окружения При регистрации плагин читает `default`-аккаунт из конфигурации канала и экспортирует три переменные. Скилл инструктирует агента использовать их в каждом вызове. | Переменная | Откуда берётся | Что делает | |------------|----------------|------------| | `VIBE_KEY` | `channels.bitrix24.providerConfig.apiKey` | API-ключ Вайбкод. Передаётся в заголовке `X-Api-Key` каждого запроса. | | `VIBE_BASE_URL` | `channels.bitrix24.providerConfig.baseUrl` или `https://vibecode.bitrix24.tech/v1` по умолчанию | Базовый URL для вызовов `/v1/*`. | | `VIBE_PLATFORM_URL` | Корень `VIBE_BASE_URL` без хвоста `/v1` | Корень сайта документации. Скилл загружает с него страницы `docs-content/.md` для справки по эндпоинтам. | Если переменные уже заданы в окружении OpenClaw — плагин их не трогает. Это позволяет хост-процессу задать собственный ключ. Для конфигураций с несколькими аккаунтами автоинъекция работает только для `default`-аккаунта. Остальные объявляют переменные явно: ```json { "skills": { "entries": { "vibe-platform": { "env": { "VIBE_KEY": "vibe_api_…", "VIBE_BASE_URL": "https://vibecode.bitrix24.tech/v1" } } } } } ``` ## Какой скоуп нужен на API-ключе Один API-ключ Вайбкод обслуживает три слоя интеграции, поэтому минимально нужны три категории скоупов: - `imbot` — для коннектора: регистрация бота на портале, опрос событий чата, отправка ответов. - `vibe:ai` — для LLM-провайдера OpenClaw, который через тот же ключ ходит в AI Router Вайбкод (`https://vibecode.bitrix24.tech/v1/ai`) и берёт оттуда модель агента. - Доменные скоупы под задачи самого скилла: `crm` для CRM, `tasks` для задач, `calendar` для расписания, `im` для пассивного чтения чатов в режиме наблюдения и так далее. Точный список скоупов на конкретном ключе агент сам читает через `GET /v1/me` при старте сессии и понимает, какие операции ему доступны. Полный справочник — [Ключи и авторизация](../keys-auth.md). ## Как агент находит данные Скилл инструктирует агента использовать четыре источника в строгом порядке. Полные подробности по каждому — на странице, к которой агент обращается; скилл не дублирует контракт API. 1. **Каталог методов** — `GET $VIBE_BASE_URL/guide` один раз за сессию. Возвращает все доступные ключу эндпоинты с короткими описаниями. Агент держит ответ в контексте и сверяется с ним перед каждым новым типом запроса. 2. **Идентификация** — `GET $VIBE_BASE_URL/me`, когда нужно узнать текущего пользователя, портал, тариф, доступные возможности. Здесь же агент находит свой `responsibleId` для создания задач. 3. **Поля сущности** — `GET $VIBE_BASE_URL//fields` перед записью. Возвращает канонический список полей с пометками обязательности. 4. **Текстовая документация** — `web_fetch` страницы `$VIBE_PLATFORM_URL/docs-content/.md` для справки по фильтрам, batch-запросам, кодам ошибок, рецептам сценариев. Скилл явно запрещает агенту изобретать имена полей, формат body, операторы фильтров. Если в каталоге или справочнике этого нет — этого нет в API. ## Базовые сценарии Канонический формат вызова — `exec`-инструмент OpenClaw с `curl`-командой: ```bash curl -sS --max-time 30 \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ "$VIBE_BASE_URL/me" ``` Дальше — типичные пользовательские запросы и как агент их собирает. ### Получить сделки в работе ```bash curl -sS --max-time 30 \ -H "X-Api-Key: $VIBE_KEY" \ "$VIBE_BASE_URL/deals?filter[stageSemanticId]=P&limit=20" ``` Параметр `filter[stageSemanticId]=P` оставляет только сделки в активной стадии (`P` — processing). Полные правила фильтрации — [Синтаксис фильтрации](../filtering.md). ### Создать задачу Перед записью агент запрашивает подтверждение одним предложением — например, «Создать задачу „Проверить отчёт“ для Сергея с дедлайном пятница?» — и ждёт явного «да». После согласия: ```bash curl -sS --max-time 30 -X POST \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "title": "Проверить отчёт", "responsibleId": 79, "deadline": "2026-05-09T18:00:00+03:00" } }' \ "$VIBE_BASE_URL/tasks" ``` Если `responsibleId` не указан — Битрикс24 вернёт `INVALID_PARAMS` с сообщением «Не указан исполнитель», и скилл инструктирует агента однократно подтянуть ID текущего пользователя из `GET /v1/me`, прежде чем повторить запрос. ### Прочитать контакт по идентификатору ```bash curl -sS --max-time 30 \ -H "X-Api-Key: $VIBE_KEY" \ "$VIBE_BASE_URL/contacts/123" ``` ### Расписание на сегодня ```bash curl -sS --max-time 30 \ -H "X-Api-Key: $VIBE_KEY" \ "$VIBE_BASE_URL/calendar-events?filter[from]=2026-05-08T00:00:00%2B03:00&filter[to]=2026-05-08T23:59:59%2B03:00" ``` Скилл объединяет события календаря и задачи с дедлайном «сегодня» в один ответ пользователю — это поведение скилла, не отдельный эндпоинт. ### Объединить несколько вызовов в один запрос Когда пользователь спросил утренний отчёт — задачи + календарь + просроченное — скилл собирает batch-запрос: ```bash curl -sS --max-time 30 -X POST \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "calls": [ { "method": "GET", "path": "/tasks", "params": { "filter[responsibleId]": "79", "filter[ Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/bank-details` | List all (with filter, sort, pagination) | `crm.requisite.bankdetail.list` | | `GET` | `/v1/bank-details/:id` | Get by ID | `crm.requisite.bankdetail.get` | | `POST` | `/v1/bank-details` | Create new | `crm.requisite.bankdetail.add` | | `PATCH` | `/v1/bank-details/:id` | Update by ID | `crm.requisite.bankdetail.update` | | `DELETE` | `/v1/bank-details/:id` | Delete by ID | `crm.requisite.bankdetail.delete` | | `GET` | `/v1/bank-details/fields` | Get available fields | `crm.requisite.bankdetail.fields` | ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `ID` | number | yes | Идентификатор записи | | `entityTypeId` | `ENTITY_TYPE_ID` | number | | | | `entityId` | `ENTITY_ID` | number | | | | `countryId` | `COUNTRY_ID` | number | | | | `name` | `NAME` | string | | | | `code` | `CODE` | string | | | | `xmlId` | `XML_ID` | string | | | | `originatorId` | `ORIGINATOR_ID` | string | | | | `active` | `ACTIVE` | boolean | | | | `sort` | `SORT` | number | | | | `comments` | `COMMENTS` | string | | Комментарий | | `createdAt` | `DATE_CREATE` | datetime | yes | Дата создания | | `updatedAt` | `DATE_MODIFY` | datetime | yes | Дата изменения | | `createdBy` | `CREATED_BY_ID` | number | yes | ID создателя | | `modifyBy` | `MODIFY_BY_ID` | number | yes | | | `rqBankName` | `RQ_BANK_NAME` | string | | | | `rqBankAddr` | `RQ_BANK_ADDR` | string | | | | `rqBankRouteNum` | `RQ_BANK_ROUTE_NUM` | string | | | | `rqBankCode` | `RQ_BANK_CODE` | string | | | | `rqAccNum` | `RQ_ACC_NUM` | string | | | | `rqCorAccNum` | `RQ_COR_ACC_NUM` | string | | | | `rqIik` | `RQ_IIK` | string | | | | `rqMfo` | `RQ_MFO` | string | | | | `rqAccName` | `RQ_ACC_NAME` | string | | | | `rqAccCurrency` | `RQ_ACC_CURRENCY` | string | | | | `rqBik` | `RQ_BIK` | string | | | | `rqSwift` | `RQ_SWIFT` | string | | | | `rqIban` | `RQ_IBAN` | string | | | ## Examples ### List ```bash curl -X GET '/v1/bank-details?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/bank-details/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/bank-details' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"entityTypeId":1,"entityId":1,"countryId":1}' ``` ### Update ```bash curl -X PATCH '/v1/bank-details/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"name":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/bank-details/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"bank-details","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Basket Items # Позиции корзины Управление товарными позициями в заказах: создание, получение, обновление, удаление, поиск, агрегация. Позиция корзины — отдельная сущность, привязанная к заказу по полю `orderId`. У одного заказа может быть несколько позиций — по одной на каждый купленный товар. Битрикс24 API: `sale.basketitem.*` Скоуп: `sale` ## Операции - [Добавить позицию](./basket-items/create.md) — `POST /v1/basket-items` - [Список позиций](./basket-items/list.md) — `GET /v1/basket-items` - [Получить позицию](./basket-items/get.md) — `GET /v1/basket-items/:id` - [Обновить позицию](./basket-items/update.md) — `PATCH /v1/basket-items/:id` - [Удалить позицию](./basket-items/delete.md) — `DELETE /v1/basket-items/:id` - [Поиск позиций](./basket-items/search.md) — `POST /v1/basket-items/search` - [Агрегация позиций](./basket-items/aggregate.md) — `POST /v1/basket-items/aggregate` ## Ключевые поля | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор позиции (только чтение) | | `orderId` | number | Идентификатор заказа. Источник: [`GET /v1/orders`](./orders/list.md) | | `productId` | number | Идентификатор товара в каталоге. Источник: [`GET /v1/catalog-products`](/docs/entities/catalog-products) | | `name` | string | Название товара (можно переопределить при добавлении) | | `price` | number | Цена за единицу | | `basePrice` | number | Базовая цена до скидки | | `discountPrice` | number | Размер скидки за единицу | | `quantity` | number | Количество | | `currency` | string | Валюта позиции. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `vatRate` | number | Ставка НДС в долях единицы (`0.20` = 20%) | | `vatIncluded` | boolean | Включён ли НДС в цену | | `weight` | number | Вес в граммах | | `dimensions` | string | Габариты в формате сериализации PHP | | `measureCode` | number | Код единицы измерения (`796` = шт, `163` = г, `006` = м и др.) | | `measureName` | string | Название единицы измерения | | `xmlId` | string | Внешний идентификатор позиции | Полный ответ позиции — см. пример в [Получить позицию](./basket-items/get.md). ## Что нужно знать перед работой 1. **Тело запроса плоское.** При создании и обновлении передавайте поля прямо в корне JSON: `{"orderId": 33, "productId": 119, ...}`. Обёртка `fields` не нужна. 2. **Позиция всегда привязана к заказу.** Поле `orderId` обязательно — без существующего заказа позицию создать нельзя, сначала вызовите [`POST /v1/orders`](./orders/create.md). Поле `productId` привязывает позицию к товару каталога; без него позиция создаётся как виртуальный товар без связи с каталогом. 3. **`vatRate` хранится в долях единицы.** Для НДС 20% передавайте `0.20`, не `20`. Для 10% — `0.10`. Для без НДС — `0` или не передавать. 4. **Цены передавайте согласованно.** `price` — итоговая цена за единицу с учётом скидки, `basePrice` — до скидки, `discountPrice` — размер скидки. Битрикс24 не пересчитывает эти поля между собой автоматически. Передайте `customPrice: true`, чтобы цена позиции не обновлялась при изменении цены товара в каталоге. ## Связанные сущности | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Заказы | [`GET /v1/orders/:id`](./orders/get.md) | Родительский заказ — `orderId` указывается при создании позиции. | | Товары каталога | [`GET /v1/catalog-products`](/docs/entities/catalog-products) | Источник `productId` для привязки позиции к товару. | | Оплаты | [`GET /v1/payments?filter[orderId]=:id`](./payments.md) | Платежи по тому же заказу. | ## Типичный сценарий Добавление товаров в заказ из внешней системы: 1. Создать заказ: [`POST /v1/orders`](./orders/create.md) — получить `orderId`. 2. Найти товары в каталоге: [`GET /v1/catalog-products`](/docs/entities/catalog-products) — получить `productId` для каждой позиции. 3. Добавить позиции: цикл [`POST /v1/basket-items`](./basket-items/create.md) с `orderId`, `productId`, `quantity`, `price`, `currency`, `vatRate`. 4. Зарегистрировать оплату: [`POST /v1/payments`](./payments/create.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Заказы](./orders.md) — родительская сущность для позиций - [Оплаты](./payments.md) — платежи по заказам - [Товары каталога](/docs/entities/catalog-products) — источник `productId` - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Bizproc Activities # Bizproc activities **Entity:** `bizprocActivity` | **Scope:** `bizproc` | **Base path:** `/v1/bizproc-activities` > Регистрация кастомных действий для дизайнера бизнес-процессов Битрикс24. Требует OAuth-приложение (вебхуки не поддерживаются Битрикс24 для этого метода). Только администраторы. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/bizproc-activities` | Список зарегистрированных действий | `bizproc.activity.list` | | `POST` | `/v1/bizproc-activities` | Зарегистрировать действие | `bizproc.activity.add` | | `PATCH` | `/v1/bizproc-activities/:code` | Обновить действие | `bizproc.activity.update` | | `DELETE` | `/v1/bizproc-activities/:code` | Удалить действие | `bizproc.activity.delete` | | `POST` | `/v1/workflows/activity-log` | Записать в журнал БП | `bizproc.activity.log` | > **Disabled operations:** `get` (нет метода в Битрикс24) > **Важно:** Идентификатор — `CODE` (строка), не числовой ID. `list` возвращает массив строк (кодов). ## Fields | API Name | Bitrix24 Name | Type | Description | |----------|---------------|------|-------------| | `code` | `CODE` | string | Уникальный код действия (a-z, A-Z, 0-9, ., -, _) | | `handler` | `HANDLER` | string | URL обработчика (тот же домен, что и приложение) | | `name` | `NAME` | string | Название (строка или локализованный объект `{ru: '...', en: '...'}`) | | `description` | `DESCRIPTION` | string | Описание (строка или локализованный объект) | | `authUserId` | `AUTH_USER_ID` | number | ID пользователя, чей токен передаётся приложению | | `useSubscription` | `USE_SUBSCRIPTION` | string | Ожидать ответ от приложения (`Y`/`N`) | | `properties` | `PROPERTIES` | object | Входные параметры действия | | `returnProperties` | `RETURN_PROPERTIES` | object | Выходные параметры действия | | `documentType` | `DOCUMENT_TYPE` | object | Тип документа `[module, object, documentType]` | | `filter` | `FILTER` | object | Правила INCLUDE/EXCLUDE для типа документа | | `usePlacement` | `USE_PLACEMENT` | string | Открывать настройки в слайдере (`Y`/`N`) | | `placementHandler` | `PLACEMENT_HANDLER` | string | URL слайдера (обязателен при `usePlacement: 'Y'`) | ## Examples ### List ```bash curl -X GET 'https://vibecode.bitrix24.tech/v1/bizproc-activities' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` Response: `{ "success": true, "data": ["my_action_1", "my_action_2"] }` ### Create ```bash curl -X POST 'https://vibecode.bitrix24.tech/v1/bizproc-activities' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "code": "my_custom_action", "handler": "https://myapp.example.com/handler", "name": {"ru": "Мое действие", "en": "My Action"}, "useSubscription": "Y", "properties": { "message": { "Name": {"ru": "Сообщение"}, "Type": "string", "Required": "Y" } }, "returnProperties": { "result": { "Name": {"ru": "Результат"}, "Type": "string" } } }' ``` ### Update ```bash curl -X PATCH 'https://vibecode.bitrix24.tech/v1/bizproc-activities/my_custom_action' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"handler": "https://myapp.example.com/new-handler"}' ``` ### Delete ```bash curl -X DELETE 'https://vibecode.bitrix24.tech/v1/bizproc-activities/my_custom_action' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` ### Activity Log ```bash curl -X POST 'https://vibecode.bitrix24.tech/v1/workflows/activity-log' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"eventToken": "TOKEN_FROM_HANDLER", "logMessage": "Processing complete"}' ``` ## Authorization `bizproc.activity.add` requires application context. Personal keys (webhooks) will fail with "Unable to get application by token". Use OAuth app keys with `bizproc` scope and `Authorization: Bearer` header. ## Errors | Code | Description | |------|-------------| | `ERROR_ACTIVITY_ALREADY_INSTALLED` | Action with this CODE already registered | | `ERROR_ACTIVITY_VALIDATION_FAILURE` | Missing required fields or invalid values | | `ERROR_ACTIVITY_NOT_FOUND` | Action with this CODE not found | | `ERROR_UNSUPPORTED_PROTOCOL` | Handler URL protocol not supported | | `ACCESS_DENIED` | User is not administrator | --- # Entity: Bizproc Robots # Bizproc robots **Entity:** `bizprocRobot` | **Scope:** `bizproc` | **Base path:** `/v1/bizproc-robots` > Регистрация роботов для автоматизации Битрикс24. Роботы появляются и в конфигураторе роботов, и в дизайнере бизнес-процессов. Рекомендуемый Битрикс24 формат вместо activities. Требует OAuth-приложение. Только администраторы. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/bizproc-robots` | Список зарегистрированных роботов | `bizproc.robot.list` | | `POST` | `/v1/bizproc-robots` | Зарегистрировать робота | `bizproc.robot.add` | | `PATCH` | `/v1/bizproc-robots/:code` | Обновить робота | `bizproc.robot.update` | | `DELETE` | `/v1/bizproc-robots/:code` | Удалить робота | `bizproc.robot.delete` | > **Disabled operations:** `get` (нет метода в Битрикс24) > **Важно:** Идентификатор — `CODE` (строка), не числовой ID. `list` возвращает массив строк (кодов). ## Fields | API Name | Bitrix24 Name | Type | Description | |----------|---------------|------|-------------| | `code` | `CODE` | string | Уникальный код робота (a-z, A-Z, 0-9, ., -, _) | | `handler` | `HANDLER` | string | URL обработчика (тот же домен, что и приложение) | | `name` | `NAME` | string | Название (строка или локализованный объект `{ru: '...', en: '...'}`) | | `description` | `DESCRIPTION` | string | Описание (строка или локализованный объект) | | `authUserId` | `AUTH_USER_ID` | number | ID пользователя, чей токен передаётся приложению | | `useSubscription` | `USE_SUBSCRIPTION` | string | Ожидать ответ от приложения (`Y`/`N`) | | `properties` | `PROPERTIES` | object | Входные параметры робота | | `returnProperties` | `RETURN_PROPERTIES` | object | Выходные параметры робота | | `documentType` | `DOCUMENT_TYPE` | object | Тип документа `[module, object, documentType]` | | `filter` | `FILTER` | object | Правила INCLUDE/EXCLUDE для типа документа | | `usePlacement` | `USE_PLACEMENT` | string | Открывать настройки в слайдере (`Y`/`N`) | | `placementHandler` | `PLACEMENT_HANDLER` | string | URL слайдера (обязателен при `usePlacement: 'Y'`) | ### Document types | Entity | documentType | |--------|-------------| | Leads | `['crm', 'CCrmDocumentLead', 'LEAD']` | | Deals | `['crm', 'CCrmDocumentDeal', 'DEAL']` | | Quotes | `['crm', 'Bitrix\\Crm\\Integration\\BizProc\\Document\\Quote', 'QUOTE']` | | Invoices | `['crm', 'Bitrix\\Crm\\Integration\\BizProc\\Document\\SmartInvoice', 'SMART_INVOICE']` | | Smart Processes | `['crm', 'Bitrix\\Crm\\Integration\\BizProc\\Document\\Dynamic', 'DYNAMIC_XXX']` | ## Examples ### List ```bash curl -X GET 'https://vibecode.bitrix24.tech/v1/bizproc-robots' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` Response: `{ "success": true, "data": ["my_robot_1", "sms_robot"] }` ### Create ```bash curl -X POST 'https://vibecode.bitrix24.tech/v1/bizproc-robots' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "code": "send_notification", "handler": "https://myapp.example.com/robot-handler", "name": {"ru": "Отправить уведомление", "en": "Send Notification"}, "useSubscription": "Y", "documentType": ["crm", "CCrmDocumentDeal", "DEAL"], "properties": { "message": { "Name": {"ru": "Текст уведомления"}, "Type": "string", "Required": "Y" } }, "returnProperties": { "sent": { "Name": {"ru": "Отправлено"}, "Type": "bool" } } }' ``` ### Update ```bash curl -X PATCH 'https://vibecode.bitrix24.tech/v1/bizproc-robots/send_notification' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"handler": "https://myapp.example.com/new-robot-handler"}' ``` ### Delete ```bash curl -X DELETE 'https://vibecode.bitrix24.tech/v1/bizproc-robots/send_notification' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` ## Authorization `bizproc.robot.add` requires application context. Personal keys (webhooks) will fail with "Unable to get application by token". Use OAuth app keys with `bizproc` scope and `Authorization: Bearer` header. ## Errors | Code | Description | |------|-------------| | `ERROR_ACTIVITY_ALREADY_INSTALLED` | Robot with this CODE already registered | | `ERROR_ACTIVITY_VALIDATION_FAILURE` | Missing required fields or invalid values | | `ERROR_ACTIVITY_NOT_FOUND` | Robot with this CODE not found | | `ERROR_UNSUPPORTED_PROTOCOL` | Handler URL protocol not supported | | `ACCESS_DENIED` | User is not administrator | --- # Entity: Bizproc Templates # Bizproc templates **Entity:** `bizprocTemplate` | **Scope:** `bizproc` | **Base path:** `/v1/bizproc-templates` > Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/bizproc-templates` | List all (with filter, sort, pagination) | `bizproc.workflow.template.list` | | `POST` | `/v1/bizproc-templates` | Create new | `bizproc.workflow.template.add` | | `PATCH` | `/v1/bizproc-templates/:id` | Update by ID | `bizproc.workflow.template.update` | | `DELETE` | `/v1/bizproc-templates/:id` | Delete by ID | `bizproc.workflow.template.delete` | > **Disabled operations:** `get` ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `ID` | number | yes | Идентификатор записи | | `moduleId` | `MODULE_ID` | string | | | | `entity` | `ENTITY` | string | | | | `documentType` | `DOCUMENT_TYPE` | array | | | | `autoExecute` | `AUTO_EXECUTE` | number | | | | `name` | `NAME` | string | | | | `description` | `DESCRIPTION` | string | | | | `modified` | `MODIFIED` | datetime | yes | | | `isModified` | `IS_MODIFIED` | boolean | yes | | | `userId` | `USER_ID` | number | | | ## Examples ### List ```bash curl -X GET '/v1/bizproc-templates?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/bizproc-templates' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"moduleId":"value","entity":"value","documentType":"value"}' ``` ### Update ```bash curl -X PATCH '/v1/bizproc-templates/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"title":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/bizproc-templates/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"bizproc-templates","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Bookings # Бронирования Бронирования резервируют ресурсы портала Битрикс24 на заданный интервал времени: создание, получение по идентификатору, список и поиск по диапазону дат, обновление и удаление. Каждое бронирование привязано к одному или нескольким ресурсам и хранит период от и до. Битрикс24 API: `booking.v1.booking.*` Скоуп: `booking` ## Операции - [Создать бронирование](./bookings/create.md) — `POST /v1/bookings` - [Список бронирований](./bookings/list.md) — `GET /v1/bookings` - [Получить бронирование](./bookings/get.md) — `GET /v1/bookings/:id` - [Обновить бронирование](./bookings/update.md) — `PATCH /v1/bookings/:id` - [Удалить бронирование](./bookings/delete.md) — `DELETE /v1/bookings/:id` - [Поиск бронирований](./bookings/search.md) — `POST /v1/bookings/search` ## Поля ### Изменяемые поля Принимаются при [создании](./bookings/create.md) и [обновлении](./bookings/update.md). | Поле | Тип | Описание | |------|-----|---------| | `resourceIds` | number[] | Идентификаторы ресурсов, которые резервирует бронирование. Обязательно при создании, массив не может быть пустым. Получить список ресурсов через API Вайбкод нельзя — укажите известные идентификаторы | | `datePeriod` | object | Период бронирования. Обязательно при создании. Структура: `from` и `to`, у каждого `timestamp` (Unix-секунды) и `timezone` (часовой пояс в формате IANA, например `Europe/Moscow`) | | `name` | string | Название бронирования. Необязательно — может быть `null` | | `description` | string | Описание бронирования. Необязательно — может быть `null` | ### Только для чтения Приходит в ответе, не принимается при создании и обновлении. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор бронирования | ## Что нужно знать перед работой 1. **Для создания нужны два поля:** `resourceIds` (непустой массив) и `datePeriod`. Без любого из них ответ — `422 BITRIX_ERROR` с перечнем недостающих полей. `name` и `description` необязательны. 2. **`datePeriod` — вложенный объект, а не строка.** Время задаётся как `{"from": {"timestamp": 1780132384, "timezone": "Europe/Moscow"}, "to": {"timestamp": 1780135984, "timezone": "Europe/Moscow"}}`. `timestamp` — Unix-секунды, `timezone` — часовой пояс в формате IANA. 3. **Список и поиск требуют интервал дат.** `GET /v1/bookings` и `POST /v1/bookings/search` принимают обязательные `dateFrom` и `dateTo` (формат ISO 8601 или Unix-секунды). Без них — `400 MISSING_REQUIRED_PARAMS`. Бронирования вне интервала в ответ не попадают. 4. **Имена полей остаются как есть.** Имена полей в ответе совпадают с именами в запросе (`resourceIds`, `datePeriod`) — дополнительного преобразования регистра нет. 5. **Набор полей фиксирован.** Все доступные поля перечислены в разделе «Поля» выше. ## Типичный сценарий 1. Создать бронирование на нужный период: [`POST /v1/bookings`](./bookings/create.md). 2. Получить бронирования за интервал: [`GET /v1/bookings?dateFrom=...&dateTo=...`](./bookings/list.md). 3. Изменить период или название: [`PATCH /v1/bookings/:id`](./bookings/update.md). 4. Снять бронь: [`DELETE /v1/bookings/:id`](./bookings/delete.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Обязательный интервал для списка и поиска | `dateFrom` + `dateTo` | | Размер страницы по умолчанию | 50 (`limit`) | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для API Вайбкод — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Entity API](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) - [Справочник сущностей](/docs/entities-index) --- # Entity: Calendar Events # События календаря Управление событиями календарей Битрикс24: личных, групповых и календарей компании. Поддерживаются создание, получение, обновление и удаление событий, а также получение схемы полей. Битрикс24 API: `calendar.event.*` Скоуп: `calendar` ## Операции - [Создать событие](./calendar-events/create.md) — `POST /v1/calendar-events` - [Список событий](./calendar-events/list.md) — `GET /v1/calendar-events` - [Получить событие](./calendar-events/get.md) — `GET /v1/calendar-events/:id` - [Обновить событие](./calendar-events/update.md) — `PATCH /v1/calendar-events/:id` - [Удалить событие](./calendar-events/delete.md) — `DELETE /v1/calendar-events/:id` - [Поля события](./calendar-events/fields.md) — `GET /v1/calendar-events/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `type` | Тип календаря: `user`, `group`, `company_calendar` | | `ownerId` | ID владельца календаря. Для `type=user` — ID сотрудника из `GET /v1/users`, для `type=group` — ID рабочей группы | | `name` | Название события | | `from` / `to` | Начало и конец события в ISO 8601 | | `timezoneFrom` / `timezoneTo` | Часовой пояс события в формате IANA (`Europe/Moscow`). Необязателен — без него используется часовой пояс сотрудника, к которому привязан API-ключ | | `skipTime` | Событие на весь день — при `true` длительность фиксируется в 24 часа | | `sectionId` | ID секции календаря | | `attendees` | Массив ID приглашённых сотрудников для записи (`POST`/`PATCH`). На чтение участники приходят в полях `attendeeList`, `attendeesCodes`, `attendeesEntityList` | | `rrule` | Расписание повторения регулярного события — объект с полями периодичности и границ серии | Полный список полей — [`GET /v1/calendar-events/fields`](./calendar-events/fields.md). ## Что нужно знать перед работой 1. **Календарь определяется парой `type` + `ownerId`.** Эта пара обязательна и для списка событий, и для создания. События всегда привязаны к конкретному календарю, а не к порталу в целом. 2. **Для создания события нужны 5 полей:** `type`, `ownerId`, `name`, `from`, `to`. Если событие на весь день — передайте `skipTime: true`; время в `from`/`to` будет проигнорировано, длительность события зафиксируется в 24 часа. 3. **`from` и `to` принимают ISO 8601 в любом виде:** с offset (`"2026-06-01T10:00:00+03:00"`), в UTC (`"2026-06-01T07:00:00Z"`) или без зоны (`"2026-06-01T10:00:00"`). В ответе возвращается ISO 8601 с offset; instant и wall-clock соответствуют тому, что отображается в календаре пользователя. 4. **Часовой пояс события задаётся через `timezoneFrom` / `timezoneTo`.** Передайте IANA-имя (`Europe/Moscow`, `Asia/Almaty`, `UTC`). Если параметры опущены, событие создаётся в часовом поясе сотрудника-владельца API-ключа. 5. **`PATCH` — частичный.** При обновлении одного поля Вайбкод дочитывает текущее состояние события и автоматически подставляет `type`, `ownerId`, `name`, которые Битрикс24 требует при каждом обновлении. ## Типичный сценарий 1. Найти владельца календаря: [`GET /v1/users`](/docs/entities/users) для личного календаря или ID рабочей группы для группового. 2. Получить ближайшие события: [`GET /v1/calendar-events?type=user&ownerId=1`](./calendar-events/list.md). 3. Создать новое или обновить существующее: [`POST /v1/calendar-events`](./calendar-events/create.md) / [`PATCH /v1/calendar-events/:id`](./calendar-events/update.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Вайбкод API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Entity API](/docs/entity-api) - [Batch](/docs/batch) - [Справочник сущностей](/docs/entities-index) --- # Entity: Calendar Sections # Секции календаря Управление секциями (календарями) Битрикс24: личных, групповых и календарей переговорных. Секция — это сам календарь, в котором живут события: у одного сотрудника может быть несколько секций («Работа», «Личное»), у группы — один или несколько групповых календарей. Битрикс24 API: `calendar.section.*` Скоуп: `calendar` ## Операции - [Список секций](./calendar-sections/list.md) — `GET /v1/calendar-sections` - [Создать секцию](./calendar-sections/create.md) — `POST /v1/calendar-sections` - [Обновить секцию](./calendar-sections/update.md) — `PATCH /v1/calendar-sections/:id` - [Удалить секцию](./calendar-sections/delete.md) — `DELETE /v1/calendar-sections/:id` ## Что НЕ поддерживается | Операция | Причина | |---|---| | `GET /v1/calendar-sections/:id` | На стороне Битрикс24 нет метода для получения секции по одному `id` — только список по паре `type` + `ownerId`. Чтобы получить одну секцию по `id`, запросите список через `GET /v1/calendar-sections?type=<...>&ownerId=<...>` и отфильтруйте результат на стороне клиента по полю `id` | | `GET /v1/calendar-sections/fields` | На стороне Битрикс24 нет метода описания полей секции — список полей зафиксирован и приведён в [Списке секций](./calendar-sections/list.md) | | `POST /v1/calendar-sections/search` | Поиск по секциям не поддерживается ни одним методом Битрикс24 | | `POST /v1/calendar-sections/aggregate` | Агрегация по секциям не поддерживается ни одним методом Битрикс24 | Если попытаться вызвать запрещённую операцию (например, `GET /v1/calendar-sections/42`), API Вайбкода вернёт `404`. ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Идентификатор секции | | `type` | Тип календаря: `user`, `group`, `company_calendar`, `location` | | `ownerId` | Идентификатор владельца календаря. Для `type=user` — `id` сотрудника из `GET /v1/users`; для `type=group` — `id` рабочей группы; для `type=location` — `0` | | `name` | Название секции | | `color` | Цвет секции (`#RRGGBB`) | | `textColor` | Цвет текста (`#RRGGBB`) | | `export` | Параметры экспорта в формате iCal: `{ "ALLOW": boolean, "SET": "all" \| "3_9" \| "6_12" }` — поле сохраняет регистр Битрикс24 и проходит без преобразований | | `access` | Карта прав доступа к секции. Возвращается только на чтение | | `perm` | Карта разрешений текущего сотрудника. Возвращается только на чтение | | `isCollab` | Принадлежность к коллабе. Возвращается только на чтение | Полный список полей с типами — в ответе [`GET /v1/calendar-sections`](./calendar-sections/list.md). ## Что нужно знать перед работой 1. **Секция определяется парой `type` + `ownerId`.** Эта пара обязательна и для списка, и для удаления. Для создания и обновления — обязательна по требованиям Битрикс24 (методы `calendar.section.add`, `calendar.section.update`). 2. **Поле `export` передаётся как объект Битрикс24.** В отличие от остальных полей, ключи внутри `export` (`ALLOW`, `SET`) идут в верхнем регистре — это формат, который Битрикс24 принимает и возвращает без преобразований. 3. **`PATCH` требует `type` + `ownerId` в теле запроса.** Битрикс24 не умеет находить секцию по одному `id` — поэтому при обновлении нужно явно указать, какой именно секции принадлежит этот `id` (один и тот же числовой `id` теоретически может встречаться в разных контекстах: например, у сотрудника `1` и сотрудника `2`). 4. **`DELETE` требует `type` + `ownerId` в строке запроса или теле.** Если переданы оба — приоритет у строки запроса. Если параметры опущены — API Вайбкода возвращает `400 MISSING_REQUIRED_PARAMS` ещё до вызова Битрикс24. 5. **Удаление секции необратимо.** Запрос выполняется без подтверждения и без возможности отмены через API. Если в секции остались нужные события, заранее перенесите их в другую секцию через [`PATCH /v1/calendar-events/:id`](/docs/entities/calendar-events/update) с новым `sectionId`. ## Типичный сценарий 1. Получить список секций сотрудника: [`GET /v1/calendar-sections?type=user&ownerId=1`](./calendar-sections/list.md). 2. Если нужна новая отдельная секция (например, «Командные встречи») — создать её: [`POST /v1/calendar-sections`](./calendar-sections/create.md). 3. Переименовать или сменить цвет: [`PATCH /v1/calendar-sections/:id`](./calendar-sections/update.md). 4. Если секция больше не нужна, заранее перенести нужные события в другую секцию (см. пункт 5 «Что нужно знать перед работой»), затем удалить: [`DELETE /v1/calendar-sections/:id`](./calendar-sections/delete.md). После создания секции её `id` можно передавать в [`POST /v1/calendar-events`](./calendar-events/create.md) через поле `sectionId`, чтобы все события писались в одну секцию. ## Лимиты | Лимит | Значение | |-------|----------| | Максимум секций на запрос (`limit`) | 5000 | | Авто-пагинация | включается при `limit > 50` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для API Вайбкода — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [События календаря](/docs/entities/calendar-events) — секции содержат события - [Entity API](/docs/entity-api) - [Batch](/docs/batch) - [Справочник сущностей](/docs/entities-index) --- # Entity: Catalog Prices # Цены каталога Цены товаров: список, получение, создание, изменение и удаление. У одного товара может быть несколько цен — по одной на каждый тип цены (`catalogGroupId`). Цены привязаны к товарам из [каталога](/docs/entities/catalog-products). Битрикс24 API: `catalog.price.*` Скоуп: `catalog` ## Операции - [Создать цену](./catalog-prices/create.md) — `POST /v1/catalog-prices` - [Список цен](./catalog-prices/list.md) — `GET /v1/catalog-prices` - [Получить цену](./catalog-prices/get.md) — `GET /v1/catalog-prices/:id` - [Обновить цену](./catalog-prices/update.md) — `PATCH /v1/catalog-prices/:id` - [Удалить цену](./catalog-prices/delete.md) — `DELETE /v1/catalog-prices/:id` - [Поиск цен](./catalog-prices/search.md) — `POST /v1/catalog-prices/search` - [Поля цены](./catalog-prices/fields.md) — `GET /v1/catalog-prices/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `productId` | ID товара, к которому относится цена. Список: [`GET /v1/catalog-products?filter[iblockId]=21`](/docs/entities/catalog-products) | | `catalogGroupId` | Тип цены. Базовая цена — `1`. Какие типы заведены на портале, видно по значениям `catalogGroupId` в [списке цен](./catalog-prices/list.md) | | `price` | Значение цены | | `currency` | Валюта цены, например `RUB`. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `quantityFrom` | Нижняя граница количественного диапазона, если цена зависит от количества | | `quantityTo` | Верхняя граница количественного диапазона | ## Что нужно знать перед работой 1. **Минимум для создания — четыре поля.** `productId`, `catalogGroupId`, `price`, `currency` обязательны; без любого из них запрос вернёт ошибку. `quantityFrom` и `quantityTo` опциональны. 2. **Тип цены задаётся числом `catalogGroupId`.** Базовая цена соответствует `1`. Отдельного эндпоинта со списком типов цен нет — доступные на портале значения видно по полю `catalogGroupId` в [списке цен](./catalog-prices/list.md). Один товар может иметь по одной цене на каждый тип. 3. **Цена привязана к товару.** Перед созданием получите `productId` из [`GET /v1/catalog-products`](/docs/entities/catalog-products) (товарам нужен фильтр `filter[iblockId]`, а `iblockId` — из [`GET /v1/catalogs`](/docs/entities/catalogs)). 4. **В ответе больше полей, чем доступно для фильтра.** Кроме перечисленных, в ответе приходят `extraId`, `priceScale` (цена в базовой валюте) и `timestampX` (дата изменения). Фильтрация и сортировка работают только по полям из таблицы выше. ## Типичный сценарий 1. Найти каталог и его `iblockId`: [`GET /v1/catalogs`](/docs/entities/catalogs). 2. Найти товар: [`GET /v1/catalog-products?filter[iblockId]=21`](/docs/entities/catalog-products) — взять `id` товара. 3. Посмотреть текущие цены товара: [`GET /v1/catalog-prices?filter[productId]=101`](./catalog-prices/list.md). 4. Создать или изменить цену: [`POST /v1/catalog-prices`](./catalog-prices/create.md) / [`PATCH /v1/catalog-prices/:id`](./catalog-prices/update.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для API Вайбкод — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Товары каталога](/docs/entities/catalog-products) - [Каталоги](/docs/entities/catalogs) - [Разделы каталога](/docs/entities/catalog-sections) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Entity: Catalog Products # Catalog products **Entity:** `catalogProduct` | **Scope:** `catalog` | **Base path:** `/v1/catalog-products` > SPA entity (camelCase field names) — field names pass through without transformation. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/catalog-products` | List all (with filter, sort, pagination) | `catalog.product.list` | | `GET` | `/v1/catalog-products/:id` | Get by ID | `catalog.product.get` | | `POST` | `/v1/catalog-products` | Create new | `catalog.product.add` | | `PATCH` | `/v1/catalog-products/:id` | Update by ID | `catalog.product.update` | | `DELETE` | `/v1/catalog-products/:id` | Delete by ID | `catalog.product.delete` | | `GET` | `/v1/catalog-products/fields` | Get available fields | `catalog.product.getFieldsByFilter` | ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `id` | number | yes | Идентификатор записи | | `name` | `name` | string | | | | `active` | `active` | boolean | | | | `iblockId` | `iblockId` | number | | | | `iblockSectionId` | `iblockSectionId` | number | | | | `purchasingPrice` | `purchasingPrice` | number | | | | `purchasingCurrency` | `purchasingCurrency` | string | | | | `quantity` | `quantity` | number | | | | `weight` | `weight` | number | | | | `measure` | `measure` | number | | | | `dateCreate` | `dateCreate` | datetime | yes | Дата создания товара | | `timestampX` | `timestampX` | datetime | yes | Дата последнего изменения | ## Aggregatable Fields These fields can be used with the aggregation engine for analytics: - `purchasingPrice` - `quantity` - `iblockSectionId` ## Доступ из веб-интерфейса По полям `iblockId` и `id` товар открывается в магазине Битрикс24: ``` https://.bitrix24.ru/shop/catalog//product// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Examples ### List ```bash curl -X GET '/v1/catalog-products?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/catalog-products/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/catalog-products' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"name":"value","active":"true","iblockId":1}' ``` ### Update ```bash curl -X PATCH '/v1/catalog-products/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"title":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/catalog-products/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"catalog-products","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Catalog Sections # Catalog sections **Entity:** `catalogSection` | **Scope:** `catalog` | **Base path:** `/v1/catalog-sections` > SPA entity (camelCase field names) — field names pass through without transformation. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/catalog-sections` | List all (with filter, sort, pagination) | `catalog.section.list` | | `GET` | `/v1/catalog-sections/:id` | Get by ID | `catalog.section.get` | | `POST` | `/v1/catalog-sections` | Create new | `catalog.section.add` | | `PATCH` | `/v1/catalog-sections/:id` | Update by ID | `catalog.section.update` | | `DELETE` | `/v1/catalog-sections/:id` | Delete by ID | `catalog.section.delete` | ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `id` | number | yes | Идентификатор записи | | `iblockId` | `iblockId` | number | | | | `iblockSectionId` | `iblockSectionId` | number | | | | `name` | `name` | string | | | | `xmlId` | `xmlId` | string | | | | `code` | `code` | string | | | | `sort` | `sort` | number | | | | `active` | `active` | boolean | | | | `description` | `description` | string | | | | `dateCreate` | `dateCreate` | datetime | yes | | | `createdBy` | `createdBy` | number | yes | ID создателя | | `modifiedBy` | `modifiedBy` | number | yes | | ## Examples ### List ```bash curl -X GET '/v1/catalog-sections?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/catalog-sections/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/catalog-sections' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"iblockId":1,"iblockSectionId":1,"name":"value"}' ``` ### Update ```bash curl -X PATCH '/v1/catalog-sections/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"title":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/catalog-sections/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"catalog-sections","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Catalogs # Каталоги Торговые каталоги портала: список, получение и фильтрация. Каталог задаёт `iblockId`, по которому работают [товары](/docs/entities/catalog-products), [разделы](/docs/entities/catalog-sections) и [цены](/docs/entities/catalog-prices). Каталоги доступны только для чтения. Битрикс24 API: `catalog.catalog.*` Скоуп: `catalog` ## Операции - [Список каталогов](./catalogs/list.md) — `GET /v1/catalogs` - [Получить каталог](./catalogs/get.md) — `GET /v1/catalogs/:id` - [Поиск каталогов](./catalogs/search.md) — `POST /v1/catalogs/search` - [Поля каталога](./catalogs/fields.md) — `GET /v1/catalogs/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Идентификатор каталога. Совпадает с `iblockId` | | `iblockId` | ID информационного блока каталога. Используется как фильтр в [`GET /v1/catalog-products`](/docs/entities/catalog-products), [`GET /v1/catalog-sections`](/docs/entities/catalog-sections), [`GET /v1/catalog-prices`](/docs/entities/catalog-prices) | | `name` | Название каталога | | `iblockTypeId` | Тип информационного блока, например `CRM_PRODUCT_CATALOG` | | `productIblockId` | У каталога предложений — `iblockId` связанного каталога товаров. У базового каталога товаров — `null` | | `skuPropertyId` | У каталога предложений — ID свойства, связывающего предложение с товаром. У базового каталога — `null` | Полный список полей — [`GET /v1/catalogs/fields`](./catalogs/fields.md). ## Что нужно знать перед работой 1. **Каталоги доступны только для чтения.** Через API можно получить список и одну запись; создание, изменение и удаление не поддерживаются. Все поля в ответе помечены «только для чтения». 2. **Каталог — источник `iblockId` для остальных эндпоинтов товарного каталога.** Чтобы получить товары, разделы или цены, сначала возьмите `iblockId` нужного каталога из [`GET /v1/catalogs`](./catalogs/list.md) и передайте его фильтром в [`GET /v1/catalog-products`](/docs/entities/catalog-products), [`GET /v1/catalog-sections`](/docs/entities/catalog-sections), [`GET /v1/catalog-prices`](/docs/entities/catalog-prices). 3. **Базовый каталог товаров и каталог предложений различаются по двум полям.** У каталога предложений заполнены `productIblockId` (ссылка на каталог товаров) и `skuPropertyId`; у базового каталога товаров оба равны `null`. ## Типичный сценарий 1. Получить список каталогов: [`GET /v1/catalogs`](./catalogs/list.md) — взять `iblockId` нужного каталога. 2. Получить товары этого каталога: [`GET /v1/catalog-products?filter[iblockId]=25`](/docs/entities/catalog-products). 3. При необходимости — разделы и цены: [`GET /v1/catalog-sections`](/docs/entities/catalog-sections), [`GET /v1/catalog-prices`](/docs/entities/catalog-prices). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | Batch-запросы | каталоги доступны только для чтения — операции записи в [`POST /v1/batch`](/docs/batch) не поддерживаются | | Rate limit | общий для API Вайбкод — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Товары каталога](/docs/entities/catalog-products) - [Разделы каталога](/docs/entities/catalog-sections) - [Цены каталога](/docs/entities/catalog-prices) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Entity: Companies # Компании Управление компаниями CRM: создание, получение, обновление, удаление, фильтрация. Bitrix24 API: `crm.company.*` Скоуп: `crm` ## Операции - [Создать компанию](./companies/create.md) — `POST /v1/companies` - [Список компаний](./companies/list.md) — `GET /v1/companies` - [Получить компанию](./companies/get.md) — `GET /v1/companies/:id` - [Обновить компанию](./companies/update.md) — `PATCH /v1/companies/:id` - [Удалить компанию](./companies/delete.md) — `DELETE /v1/companies/:id` - [Поиск компаний](./companies/search.md) — `POST /v1/companies/search` - [Поля компании](./companies/fields.md) — `GET /v1/companies/fields` - [Агрегация компаний](./companies/aggregate.md) — `POST /v1/companies/aggregate` --- # Entity: Contacts # Контакты Управление контактами CRM: создание, получение, обновление, удаление, фильтрация. Bitrix24 API: `crm.contact.*` Скоуп: `crm` ## Операции - [Создать контакт](./contacts/create.md) — `POST /v1/contacts` - [Список контактов](./contacts/list.md) — `GET /v1/contacts` - [Получить контакт](./contacts/get.md) — `GET /v1/contacts/:id` - [Обновить контакт](./contacts/update.md) — `PATCH /v1/contacts/:id` - [Удалить контакт](./contacts/delete.md) — `DELETE /v1/contacts/:id` - [Поиск контактов](./contacts/search.md) — `POST /v1/contacts/search` - [Поля контакта](./contacts/fields.md) — `GET /v1/contacts/fields` - [Агрегация контактов](./contacts/aggregate.md) — `POST /v1/contacts/aggregate` --- # Entity: Currencies # Валюты Справочник валют портала с курсами обмена. ID валюты — строковый код (`RUB`, `USD`, `EUR`). Bitrix24 API: `crm.currency.*` Скоуп: `crm` ## Операции - [Создать валюту](./currencies/create.md) — `POST /v1/currencies` - [Список валют](./currencies/list.md) — `GET /v1/currencies` - [Получить валюту](./currencies/get.md) — `GET /v1/currencies/:id` - [Обновить валюту](./currencies/update.md) — `PATCH /v1/currencies/:id` - [Удалить валюту](./currencies/delete.md) — `DELETE /v1/currencies/:id` - [Поля валюты](./currencies/fields.md) — `GET /v1/currencies/fields` --- # Entity: Deal Categories # Воронки сделок Воронки продаж (категории сделок). Каждая воронка содержит свой набор стадий. Воронка с ID 0 — основная, создаётся автоматически. Bitrix24 API: `crm.dealcategory.*` Скоуп: `crm` Стадии воронки: `GET /v1/statuses?filter[entityId]=DEAL_STAGE_{categoryId}` ## Операции - [Создать воронку](./deal-categories/create.md) — `POST /v1/deal-categories` - [Список воронок](./deal-categories/list.md) — `GET /v1/deal-categories` - [Получить воронку](./deal-categories/get.md) — `GET /v1/deal-categories/:id` - [Обновить воронку](./deal-categories/update.md) — `PATCH /v1/deal-categories/:id` - [Удалить воронку](./deal-categories/delete.md) — `DELETE /v1/deal-categories/:id` - [Поля воронки](./deal-categories/fields.md) — `GET /v1/deal-categories/fields` --- # Entity: Deals # Сделки Управление сделками CRM: создание, получение, обновление, удаление, фильтрация. Bitrix24 API: `crm.item.*` Скоуп: `crm` ## Операции - [Создать сделку](./deals/create.md) — `POST /v1/deals` - [Список сделок](./deals/list.md) — `GET /v1/deals` - [Получить сделку](./deals/get.md) — `GET /v1/deals/:id` - [Обновить сделку](./deals/update.md) — `PATCH /v1/deals/:id` - [Удалить сделку](./deals/delete.md) — `DELETE /v1/deals/:id` - [Поиск сделок](./deals/search.md) — `POST /v1/deals/search` - [Поля сделки](./deals/fields.md) — `GET /v1/deals/fields` - [Агрегация сделок](./deals/aggregate.md) — `POST /v1/deals/aggregate` - [Получить товары](./deals/products-get.md) — `GET /v1/deals/:id/products` - [Установить товары](./deals/products-set.md) — `PUT /v1/deals/:id/products` - [Добавить товар](./deals/products-add.md) — `POST /v1/deals/:id/products` - [Удалить товар](./deals/products-delete.md) — `DELETE /v1/deals/:id/products/:rowId` - [Получить товар](./deals/products-get-single.md) — `GET /v1/deals/:id/products/:rowId` - [Обновить товар](./deals/products-update.md) — `PATCH /v1/deals/:id/products/:rowId` - [Поля товаров](./deals/products-fields.md) — `GET /v1/deals/:id/products/fields` --- # Entity: Departments # Отделы Управление организационной структурой портала: создание, получение, обновление, удаление и фильтрация отделов. Отделы образуют дерево — каждый отдел кроме корневого ссылается на родительский через `parentId`, а сотрудники назначаются в отделы через [справочник сотрудников](/docs/entities/users). Битрикс24 API: `department.*` Скоуп: `department` ## Операции - [Создать отдел](./departments/create.md) — `POST /v1/departments` - [Список отделов](./departments/list.md) — `GET /v1/departments` - [Получить отдел](./departments/get.md) — `GET /v1/departments/:id` - [Обновить отдел](./departments/update.md) — `PATCH /v1/departments/:id` - [Удалить отдел](./departments/delete.md) — `DELETE /v1/departments/:id` - [Поиск отделов](./departments/search.md) — `POST /v1/departments/search` - [Поля отдела](./departments/fields.md) — `GET /v1/departments/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Идентификатор отдела | | `name` | Название отдела | | `parentId` | ID родительского отдела. У корневого отдела портала равен `1` | | `headId` | ID руководителя отдела. Источник: [`GET /v1/users`](/docs/entities/users) | | `sort` | Порядок сортировки отдела среди соседей (целое число, по возрастанию) | Полный список полей — [`GET /v1/departments/fields`](./departments/fields.md). ## Что нужно знать перед работой 1. **Структура отделов — дерево с одним корнем.** Отделы верхнего уровня ссылаются на корневой узел через `parentId: 1`. Сам корневой узел не возвращается в [`GET /v1/departments`](./departments/list.md) и не доступен через `GET /v1/departments/:id` — это служебная вершина дерева. Попытка создать второй отдел верхнего уровня (без `parentId` либо с `parentId: 0`) возвращает HTTP 422 с сообщением «В структуре компании должен быть только один раздел верхнего уровня.». 2. **Минимум для создания одного отдела — два поля:** `name` и `parentId`. Если `parentId` опущен — запрос трактуется как попытка создать отдел верхнего уровня (см. пункт выше). 3. **`headId` — ID сотрудника, а не отдела.** Назначить руководителем можно любого сотрудника портала. Если сотрудник с указанным ID не существует, запрос вернёт HTTP 422. 4. **`sort` управляет порядком в списке.** Значение `sort` сравнивается между отделами одного уровня — внутри одного `parentId`. Меньшее значение — выше в списке. 5. **Удалить отдел с дочерними отделами или закреплёнными сотрудниками нельзя.** Перед удалением нужно перенести или удалить дочерние отделы и переназначить сотрудников. ## Типичный сценарий 1. Получить текущую структуру: [`GET /v1/departments`](./departments/list.md) — увидеть дерево по `parentId`. 2. Найти руководителя для нового отдела: [`GET /v1/users?filter[name]=Иван`](/docs/entities/users). 3. Создать отдел: [`POST /v1/departments`](./departments/create.md) с `name`, `parentId`, `headId`. 4. Назначить сотрудников в отдел: через [`PATCH /v1/users/:id`](/docs/entities/users) с указанием поля `departmentId` (массив ID отделов). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | Параметр `offset` | не применяется — возвращается вся выборка фильтра | | Параметр `order` | не применяется — порядок выдачи фиксирован | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch). Поддерживаются `create`, `update`, `delete` | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Сотрудники](/docs/entities/users) — назначение в отделы и поиск руководителей - [Справочник сущностей](/docs/entities-index) --- # Entity: Doc Templates # Шаблоны документов Шаблон документов — это файл `.docx` с подстановочными метками, по которому Битрикс24 формирует готовые документы с подставленными значениями. Битрикс24 API: `documentgenerator.template.*` Скоуп: `documentgenerator` ## Операции - [Создать шаблон](./doc-templates/create.md) — `POST /v1/doc-templates` - [Список шаблонов](./doc-templates/list.md) — `GET /v1/doc-templates` - [Получить шаблон](./doc-templates/get.md) — `GET /v1/doc-templates/:id` - [Обновить шаблон](./doc-templates/update.md) — `PATCH /v1/doc-templates/:id` - [Удалить шаблон](./doc-templates/delete.md) — `DELETE /v1/doc-templates/:id` - [Поиск шаблонов](./doc-templates/search.md) — `POST /v1/doc-templates/search` - [Поля шаблона](./doc-templates/fields.md) — `GET /v1/doc-templates/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `name` | Название шаблона | | `numeratorId` | Идентификатор нумератора | | `region` | Регион, например `ru` | | `file` | Содержимое `.docx` в виде строки base64 | | `fileId` | Идентификатор файла на Диске. Источник: загрузка через `POST /v1/files/upload` | Полный список полей — [Поля шаблона](./doc-templates/fields.md). ## Что нужно знать перед работой 1. При создании нужен файл — либо содержимое в виде base64 в поле `file`, либо `fileId` уже загруженного на Диск файла. Передаётся ровно одно из двух. 2. Обязательные поля при создании: `name`, `numeratorId`, `region`. 3. Поля ответа приходят в camelCase. 4. Эндпоинты `/v1` принимают только JSON; формат `multipart/form-data` не поддерживается. ## Типичный сценарий 1. Загрузить файл `.docx` через `POST /v1/files/upload` — поле `id` из ответа становится значением `fileId`. 2. Создать шаблон с этим `fileId` через [`POST /v1/doc-templates`](./doc-templates/create.md). 3. Получить, обновить или удалить шаблон по `id`: [`GET /v1/doc-templates/:id`](./doc-templates/get.md), [`PATCH /v1/doc-templates/:id`](./doc-templates/update.md), [`DELETE /v1/doc-templates/:id`](./doc-templates/delete.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для API Вайбкода — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Документы](/docs/entities/documents) - [Entity API](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) --- # Entity: Documents # Документы Документ — это готовый файл, который Битрикс24 формирует по шаблону с подстановкой значений. Каждый документ создаётся на основе шаблона документов и провайдера данных. Битрикс24 API: `documentgenerator.document.*` Скоуп: `documentgenerator` ## Операции - [Создать документ](./documents/create.md) — `POST /v1/documents` - [Список документов](./documents/list.md) — `GET /v1/documents` - [Получить документ](./documents/get.md) — `GET /v1/documents/:id` - [Обновить документ](./documents/update.md) — `PATCH /v1/documents/:id` - [Удалить документ](./documents/delete.md) — `DELETE /v1/documents/:id` - [Поиск документов](./documents/search.md) — `POST /v1/documents/search` - [Поля документа](./documents/fields.md) — `GET /v1/documents/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `templateId` | Идентификатор шаблона. Источник: `GET /v1/doc-templates` | | `providerClassName` | Класс провайдера данных, например `Bitrix\DocumentGenerator\DataProvider\Rest` | | `value` | Внешний идентификатор объекта-источника, например `ORDER-1024` | | `values` | Значения полей-меток шаблона | | `number` | Номер документа | | `pdfUrl` | Ссылка на готовый PDF | Полный список полей — [Поля документа](./documents/fields.md). ## Что нужно знать перед работой 1. Документ создаётся по шаблону: обязательны `templateId`, `providerClassName` и `value`. 2. `providerClassName` задаёт класс провайдера данных, `value` — внешний идентификатор объекта-источника, по которому подставляются значения полей-меток. 3. Значения полей-меток шаблона передаются в `values`. 4. Поля ответа приходят в camelCase. 5. Готовый файл доступен по ссылкам `downloadUrl` и `pdfUrl` (для пользователя) и `downloadUrlMachine` / `pdfUrlMachine` (для приложения). ## Типичный сценарий 1. Выбрать шаблон: [`GET /v1/doc-templates`](/docs/entities/doc-templates). 2. Создать документ по шаблону: [`POST /v1/documents`](./documents/create.md) с `templateId`, `providerClassName` и `value`. 3. Получить, обновить или удалить документ по `id`: [`GET /v1/documents/:id`](./documents/get.md), [`PATCH /v1/documents/:id`](./documents/update.md), [`DELETE /v1/documents/:id`](./documents/delete.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для API Вайбкода — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Шаблоны документов](/docs/entities/doc-templates) - [Entity API](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) --- # Entity: Files # Файлы Управление файлами на диске Битрикс24: получение списка, загрузка, скачивание, переименование, перемещение, копирование и удаление. Файлы хранятся в папках внутри хранилищ. Битрикс24 API: `disk.file.*` Скоуп: `disk` ## Операции - [Список файлов папки](./files/list.md) — `GET /v1/files` - [Получить файл](./files/get.md) — `GET /v1/files/:id` - [Переименовать файл](./files/update.md) — `PATCH /v1/files/:id` - [Удалить файл](./files/delete.md) — `DELETE /v1/files/:id` - [Поля файла](./files/fields.md) — `GET /v1/files/fields` - [Загрузить файл](./files/upload.md) — `POST /v1/files/upload` - [Скачать файл](./files/download.md) — `GET /v1/files/:id/download` - [Переместить файл](./files/moveto.md) — `POST /v1/files/:id/moveto` - [Скопировать файл](./files/copyto.md) — `POST /v1/files/:id/copyto` ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Числовой идентификатор файла | | `name` | Имя файла с расширением | | `size` | Размер файла в байтах. ⚠ Только в `GET /v1/files/:id`; в списке не возвращается | | `folderId` | Идентификатор родительской папки (из [`GET /v1/folders`](/docs/entities/folders)) | | `storageId` | Идентификатор хранилища (из [`GET /v1/storages`](/docs/entities/storages)) | | `type` | Тип объекта — для файлов всегда `"file"` | | `downloadUrl` | Прямая ссылка на скачивание. Требует куки-сессии Битрикс24; для программного скачивания используйте [`GET /v1/files/:id/download`](./files/download.md) | | `createdAt` | Дата и время создания в формате ISO 8601 | | `updatedAt` | Дата и время последнего изменения в формате ISO 8601 | Полный список полей — [`GET /v1/files/fields`](./files/fields.md). ## Что нужно знать перед работой 1. **Для получения списка файлов требуется `folderId`.** `GET /v1/files` возвращает содержимое конкретной папки. Чтобы получить идентификатор папки, сначала запросите список хранилищ через `GET /v1/storages`, затем список папок через `GET /v1/folders` с нужным `storageId`. 2. **`GET /v1/files` возвращает смешанный список.** В ответе одновременно присутствуют файлы (`type: "file"`) и подпапки (`type: "folder"`). Для фильтрации по типу используйте поле `type`. 3. **Удаление — мягкое.** `DELETE /v1/files/:id` помечает файл как удалённый, физически файл не стирается. Удалённый файл остаётся в Битрикс24 до окончательной очистки. 4. **Изменить можно только имя.** `PATCH /v1/files/:id` принимает только поле `name`. Прочие поля доступны только для чтения. 5. **Перемещение работает только внутри одного хранилища.** `POST /v1/files/:id/moveto` не перемещает файлы между хранилищами. Для переноса между хранилищами используйте `POST /v1/files/:id/copyto`, затем `DELETE /v1/files/:id`. ## Типичный сценарий 1. Получить идентификатор хранилища: [`GET /v1/storages`](/docs/entities/storages). 2. Найти нужную папку: [`GET /v1/folders`](/docs/entities/folders) с параметром `storageId`. 3. Загрузить файл в папку: [`POST /v1/files/upload`](./files/upload.md) с `folderId` — в ответе придёт `id` нового файла. 4. Скачать содержимое файла: [`GET /v1/files/:id/download`](./files/download.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (при `limit > 50` Вайбкод выполняет несколько запросов автоматически; смещение через `offset`) | | Максимальный размер загружаемого файла | определяется настройками портала Битрикс24 | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Папки](/docs/entities/folders) - [Хранилища](/docs/entities/storages) - [Синтаксис фильтрации](/docs/filtering) - [API-ключи](/docs/api-keys) - [Коды ошибок](/docs/errors) --- # Entity: Folders # Folders **Entity:** `diskFolder` | **Scope:** `disk` | **Base path:** `/v1/folders` > Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/folders` | List all (with filter, sort, pagination) | `disk.folder.getchildren` | | `GET` | `/v1/folders/:id` | Get by ID | `disk.folder.get` | | `POST` | `/v1/folders` | Create new | `disk.folder.addsubfolder` | | `PATCH` | `/v1/folders/:id` | Update by ID | `disk.folder.rename` | | `DELETE` | `/v1/folders/:id` | Delete by ID | `disk.folder.markdeleted` | | `GET` | `/v1/folders/fields` | Get available fields | `disk.folder.getFields` | ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `ID` | number | yes | Идентификатор записи | | `name` | `NAME` | string | | | | `parentId` | `PARENT_ID` | number | | | | `storageId` | `STORAGE_ID` | number | yes | | | `code` | `CODE` | string | | | | `createdBy` | `CREATE_USER_ID` | number | yes | ID создателя | | `createdAt` | `CREATE_TIME` | datetime | yes | Дата создания | ## Relations (reference) | Relation | Entity | Type | Foreign Key | |----------|--------|------|-------------| | storage | `diskStorage` | one | `storageId` | ## Доступ из веб-интерфейса Поле `detailUrl` в ответе `GET /v1/folders` и `POST /v1/folders` — полный URL карточки папки в Битрикс24, например `https://.bitrix24.ru/company/personal/user/1/disk/path/<имя>/`. Доступ ограничен правами сотрудника в Битрикс24. ## Examples ### List ```bash curl -X GET '/v1/folders?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/folders/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/folders' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"name":"value","parentId":1,"code":"value"}' ``` ### Update ```bash curl -X PATCH '/v1/folders/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"title":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/folders/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"folders","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Invoices # Счета Управление счетами CRM: создание, получение, обновление, удаление, фильтрация. Bitrix24 API: `crm.item.*` (SPA-сущность, entityTypeId = 31) Скоуп: `crm` ## Операции - [Создать счёт](./invoices/create.md) — `POST /v1/invoices` - [Список счетов](./invoices/list.md) — `GET /v1/invoices` - [Получить счёт](./invoices/get.md) — `GET /v1/invoices/:id` - [Обновить счёт](./invoices/update.md) — `PATCH /v1/invoices/:id` - [Удалить счёт](./invoices/delete.md) — `DELETE /v1/invoices/:id` - [Поиск счетов](./invoices/search.md) — `POST /v1/invoices/search` - [Поля счёта](./invoices/fields.md) — `GET /v1/invoices/fields` - [Агрегация счетов](./invoices/aggregate.md) — `POST /v1/invoices/aggregate` - [Получить товары](./invoices/products-get.md) — `GET /v1/invoices/:id/products` - [Установить товары](./invoices/products-set.md) — `PUT /v1/invoices/:id/products` - [Добавить товар](./invoices/products-add.md) — `POST /v1/invoices/:id/products` - [Удалить товар](./invoices/products-delete.md) — `DELETE /v1/invoices/:id/products/:rowId` - [Получить товар](./invoices/products-get-single.md) — `GET /v1/invoices/:id/products/:rowId` - [Обновить товар](./invoices/products-update.md) — `PATCH /v1/invoices/:id/products/:rowId` - [Поля товаров](./invoices/products-fields.md) — `GET /v1/invoices/:id/products/fields` --- # Entity: Items # Смарт-процессы (Items) Управление элементами смарт-процессов CRM: создание, получение, обновление, удаление, фильтрация. Bitrix24 API: `crm.item.*` (SPA-сущность) Скоуп: `crm` Путь содержит динамический параметр `:entityTypeId` — ID типа смарт-процесса. Узнать доступные типы: `GET /v1/smart-processes`. ## Операции - [Создать элемент](./items/create.md) — `POST /v1/items/:entityTypeId` - [Список элементов](./items/list.md) — `GET /v1/items/:entityTypeId` - [Получить элемент](./items/get.md) — `GET /v1/items/:entityTypeId/:id` - [Обновить элемент](./items/update.md) — `PATCH /v1/items/:entityTypeId/:id` - [Удалить элемент](./items/delete.md) — `DELETE /v1/items/:entityTypeId/:id` - [Поиск элементов](./items/search.md) — `POST /v1/items/:entityTypeId/search` - [Поля элемента](./items/fields.md) — `GET /v1/items/:entityTypeId/fields` - [Агрегация элементов](./items/aggregate.md) — `POST /v1/items/:entityTypeId/aggregate` - [Получить товары](./items/products-get.md) — `GET /v1/items/:entityTypeId/:id/products` - [Установить товары](./items/products-set.md) — `PUT /v1/items/:entityTypeId/:id/products` - [Добавить товар](./items/products-add.md) — `POST /v1/items/:entityTypeId/:id/products` - [Удалить товар](./items/products-delete.md) — `DELETE /v1/items/:entityTypeId/:id/products/:rowId` - [Получить товар](./items/products-get-single.md) — `GET /v1/items/:entityTypeId/:id/products/:rowId` - [Обновить товар](./items/products-update.md) — `PATCH /v1/items/:entityTypeId/:id/products/:rowId` - [Поля товаров](./items/products-fields.md) — `GET /v1/items/:entityTypeId/:id/products/fields` ## Пользовательские поля Управление пользовательскими полями элементов смарт-процесса — отдельный раздел: [Поля смарт-процессов](/docs/userfields/smart-processes) (`/v1/items/:entityTypeId/userfields*`). ## Смотрите также - [Типы смарт-процессов](/docs/entities/smart-processes) - [Поля смарт-процессов](/docs/userfields/smart-processes) - [Entity API](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Entity: Leads # Лиды Управление лидами CRM: создание, получение, обновление, удаление, фильтрация. Bitrix24 API: `crm.lead.*` Скоуп: `crm` ## Операции - [Создать лид](./leads/create.md) — `POST /v1/leads` - [Список лидов](./leads/list.md) — `GET /v1/leads` - [Получить лид](./leads/get.md) — `GET /v1/leads/:id` - [Обновить лид](./leads/update.md) — `PATCH /v1/leads/:id` - [Удалить лид](./leads/delete.md) — `DELETE /v1/leads/:id` - [Поиск лидов](./leads/search.md) — `POST /v1/leads/search` - [Поля лида](./leads/fields.md) — `GET /v1/leads/fields` - [Агрегация лидов](./leads/aggregate.md) — `POST /v1/leads/aggregate` - [Получить товары](./leads/products-get.md) — `GET /v1/leads/:id/products` - [Установить товары](./leads/products-set.md) — `PUT /v1/leads/:id/products` - [Добавить товар](./leads/products-add.md) — `POST /v1/leads/:id/products` - [Удалить товар](./leads/products-delete.md) — `DELETE /v1/leads/:id/products/:rowId` - [Получить товар](./leads/products-get-single.md) — `GET /v1/leads/:id/products/:rowId` - [Обновить товар](./leads/products-update.md) — `PATCH /v1/leads/:id/products/:rowId` - [Поля товаров](./leads/products-fields.md) — `GET /v1/leads/:id/products/fields` --- # Entity: List Elements # List elements **Entity:** `listElement` | **Scope:** `lists` | **Base path:** `/v1/list-elements` > Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/list-elements/fields` | Get available fields | `lists.element.getFields` | > **Disabled operations:** `list`, `get`, `create`, `update`, `delete` ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `ID` | number | yes | Идентификатор записи | | `iblockId` | `IBLOCK_ID` | number | | | | `iblockTypeId` | `IBLOCK_TYPE_ID` | string | | | | `name` | `NAME` | string | | | | `sectionId` | `SECTION_ID` | number | | | | `code` | `CODE` | string | | | | `active` | `ACTIVE` | boolean | | | | `sort` | `SORT` | number | | | | `createdBy` | `CREATED_BY` | number | yes | ID создателя | | `createdAt` | `DATE_CREATE` | datetime | yes | Дата создания | ## Examples ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"list-elements","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Openline Configs # Конфигурации открытых линий Управление конфигурациями открытых линий Битрикс24: настройка входящих обращений из мессенджеров и социальных сетей, очереди операторов, рабочего времени, интеграции с CRM, приветственных сообщений и оценки качества обслуживания. Битрикс24 API: `imopenlines.config.*` Скоуп: `imopenlines` ## Операции - [Создать конфигурацию](./openline-configs/create.md) — `POST /v1/openline-configs` - [Список конфигураций](./openline-configs/list.md) — `GET /v1/openline-configs` - [Получить конфигурацию](./openline-configs/get.md) — `GET /v1/openline-configs/:id` - [Обновить конфигурацию](./openline-configs/update.md) — `PATCH /v1/openline-configs/:id` - [Удалить конфигурацию](./openline-configs/delete.md) — `DELETE /v1/openline-configs/:id` - [Поиск конфигураций](./openline-configs/search.md) — `POST /v1/openline-configs/search` - [Поля конфигурации](./openline-configs/fields.md) — `GET /v1/openline-configs/fields` - [Агрегация конфигураций](./openline-configs/aggregate.md) — `POST /v1/openline-configs/aggregate` ## Действия оператора над диалогом Помимо CRUD конфигураций есть пара действий, которые выполняет оператор поверх конкретного диалога открытой линии. Оба требуют `imopenlines` скоупа и принимают `chatId` — идентификатор объекта чата (получите его через `imopenlines.session.open` или `imopenlines.dialog.get`; это **не** dialogId с префиксом `chat`): ### `POST /v1/openlines/operator/answer` Принимает диалог к обработке текущим оператором. ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/openlines/operator/answer" \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{"chatId": 2043}' ``` Ответ при успехе: `{ "success": true, "data": { "chatId": 2043, "answered": true } }`. ### `POST /v1/openlines/operator/finish` Завершает диалог от имени текущего оператора. ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/openlines/operator/finish" \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{"chatId": 2043}' ``` Ответ при успехе: `{ "success": true, "data": { "chatId": 2043, "finished": true } }`. ### Ошибки операторских эндпоинтов | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_CHAT_ID` | `chatId` отсутствует, не является положительным целым или передан в неверном формате | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 502 | `OPENLINE_OPERATOR_FAILED` | Битрикс24 вернул `result: false` — диалог уже взят/завершён другим оператором, либо `chatId` не соответствует активному диалогу открытой линии | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку: `CHAT_TYPE` (чат не является открытой линией), `ACCESS_DENIED` (недостаточно прав), `USER_ID` (неверный идентификатор пользователя). Детали — в `error.message` | ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Идентификатор конфигурации (число) | | `name` | Название открытой линии. При создании и обновлении это же поле передаётся в `body` как `LINE_NAME` | | `active` | Признак активности: `true` — линия принимает обращения, `false` — отключена | | `queueType` | Алгоритм распределения: `all` — всем операторам, `evenly` — равномерно, `strictly` — строго по очереди | | `QUEUE` | Массив идентификаторов операторов очереди — приходит только в `GET /v1/openline-configs/:id`. Источник идентификаторов: `GET /v1/users` | | `WELCOME_BOT_ID` | Идентификатор приветственного бота — бот, с которым начинается диалог до передачи оператору. Источник: `/docs/bots/management/list` | | `CRM_CREATE` | Признак автоматического создания лида или контакта в CRM при входящем обращении | | `WORKTIME_ENABLE` | Признак использования расписания рабочего времени | Полный список полей — [`GET /v1/openline-configs/fields`](./openline-configs/fields.md). ## Что нужно знать перед работой 1. **Смешанный регистр полей.** Ответы содержат поля в двух регистрах одновременно: 6 полей в camelCase (`id`, `active`, `name`, `queueType`, `workTimeFrom`, `workTimeTo`) и UPPER_SNAKE_CASE-поля (`CRM_CREATE`, `WORKTIME_ENABLE`, `WELCOME_BOT_ID` и другие). Где какое поле — в [Поля конфигурации](./openline-configs/fields.md). 2. **Разный набор полей в `list`/`search` и в `get`.** `GET /v1/openline-configs` и `POST /v1/openline-configs/search` возвращают по 91 полю на запись (6 camelCase + 85 UPPER_SNAKE_CASE). `GET /v1/openline-configs/:id` дополнительно отдаёт 4 поля очереди операторов (`QUEUE`, `QUEUE_FULL`, `QUEUE_USERS_FIELDS`, `QUEUE_ONLINE`) — итого 95 полей. 3. **Минимум для создания — одно поле `LINE_NAME`.** Остальные поля при создании опциональны. Тело запроса передаётся в `UPPER_SNAKE_CASE`. 4. **Адресация по `id`.** Для получения, обновления и удаления используется числовой `id` из ответа. Бывшие «зарезервированные» поля `lineId` и `agentId` удалены из схемы (VB-5ba3fd91) — `imopenlines.config.*` никогда их не возвращал. ## Связанные сущности | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Пользователи | `GET /v1/users` | Источник идентификаторов операторов для поля `QUEUE` | | Боты | `/docs/bots/management/list` | Источник идентификатора приветственного бота для поля `WELCOME_BOT_ID` | ## Типичный сценарий 1. Получить список конфигураций: [`GET /v1/openline-configs`](./openline-configs/list.md). 2. Создать конфигурацию с минимальным набором полей: [`POST /v1/openline-configs`](./openline-configs/create.md) с `LINE_NAME`. 3. Получить полную запись с очередью операторов: [`GET /v1/openline-configs/:id`](./openline-configs/get.md). 4. Обновить параметры: [`PATCH /v1/openline-configs/:id`](./openline-configs/update.md). 5. Удалить конфигурацию: [`DELETE /v1/openline-configs/:id`](./openline-configs/delete.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 200 (`limit ≤ 200`). На типичном портале конфигураций — десятки, одного запроса хватает на всё | | Пагинация | через `limit` + `offset`. Используйте поле `hasMore` для проверки следующей страницы | | Batch-доступные операции | `create`, `update`, `delete` — через [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Вайбкода — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Справочник сущностей](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Entity: Order Statuses # Статусы заказов Управление статусами заказов и доставки интернет-магазина: создание, получение, обновление, удаление, поиск, агрегация. Статусы — это справочник, на который ссылается поле [`orders.statusId`](./orders/fields.md). У каждого статуса есть тип: `O` — статус заказа, `D` — статус доставки. Битрикс24 API: `sale.status.*` Скоуп: `sale` ## Операции - [Создать статус](./order-statuses/create.md) — `POST /v1/order-statuses` - [Список статусов](./order-statuses/list.md) — `GET /v1/order-statuses` - [Получить статус](./order-statuses/get.md) — `GET /v1/order-statuses/:id` - [Обновить статус](./order-statuses/update.md) — `PATCH /v1/order-statuses/:id` - [Удалить статус](./order-statuses/delete.md) — `DELETE /v1/order-statuses/:id` - [Поиск статусов](./order-statuses/search.md) — `POST /v1/order-statuses/search` - [Агрегация статусов](./order-statuses/aggregate.md) — `POST /v1/order-statuses/aggregate` ## Ключевые поля | Поле | Тип | Описание | |------|-----|---------| | `id` | string | Символьный код статуса (1-2 символа: `N`, `IP`, `DT`). **Задаётся пользователем при создании**, не генерируется автоматически | | `type` | string | Тип статуса: `O` — статус заказа, `D` — статус доставки | | `sort` | number | Порядок сортировки в списках | | `notify` | boolean | Отправлять ли уведомление клиенту при переходе заказа в этот статус | | `color` | string | HEX-код цвета для отображения в интерфейсе (например, `#FFA500`) | | `xmlId` | string | Внешний идентификатор для синхронизации с внешними системами | Полный список полей — см. таблицу выше. У сущности нет других полей кроме перечисленных, поэтому `GET /v1/order-statuses/fields` не зарегистрирован. ## Что нужно знать перед работой 1. **`id` задаётся пользователем.** При создании передавайте короткий символьный код (1-2 символа): например, `N` («новый»), `IP` («в работе»), `DT` («доставлен»). Идентификатор должен быть уникальным независимо от типа — нельзя создать два статуса с одинаковым `id`, даже если один из них для заказа, а второй для доставки. 2. **Тело запроса плоское.** При создании и обновлении передавайте поля прямо в корне JSON: `{"id": "DT", "type": "O", ...}`. Обёртка `fields` не нужна. 3. **Набор статусов по умолчанию.** На новом портале есть стандартные статусы: `N` («Принят, ожидается оплата»), `P` («Оплачен»), `F` («Выполнен»), `D` («Отказ»), `DN` («Доставляется») и другие. Их можно удалять и переименовывать тем же API, но заказы со ссылками на старый `id` после удаления статуса не находятся в выборках по `statusId`. ## Связанные сущности | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Заказы | [`GET /v1/orders?filter[statusId]=:id`](./orders/list.md) | Заказы, находящиеся в этом статусе — поле `orders.statusId` ссылается сюда. | ## Типичный сценарий Создание нового статуса заказа и его использование: 1. Получить существующие статусы: [`GET /v1/order-statuses?filter[type]=O`](./order-statuses/list.md) — убедиться, что новый код `id` не занят. 2. Создать статус: [`POST /v1/order-statuses`](./order-statuses/create.md) с `id`, `type: "O"`, `sort`, `notify`, `color`. 3. Использовать в заказах: [`PATCH /v1/orders/:id`](./orders/update.md) с `statusId: "новый_id"`. ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | Длина `id` | максимум 2 символа (символьный код статуса) | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Заказы](./orders.md) — заказы со ссылкой на статус - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Orders # Заказы Управление заказами интернет-магазина: создание, получение, обновление, удаление, поиск, агрегация. Заказ — корневая сущность интернет-магазина: с него начинается путь покупателя, к нему привязываются позиции корзины, оплаты, отгрузки и статусы. Битрикс24 API: `sale.order.*` Скоуп: `sale` ## Операции - [Создать заказ](./orders/create.md) — `POST /v1/orders` - [Список заказов](./orders/list.md) — `GET /v1/orders` - [Получить заказ](./orders/get.md) — `GET /v1/orders/:id` - [Обновить заказ](./orders/update.md) — `PATCH /v1/orders/:id` - [Удалить заказ](./orders/delete.md) — `DELETE /v1/orders/:id` - [Поиск заказов](./orders/search.md) — `POST /v1/orders/search` - [Поля заказа](./orders/fields.md) — `GET /v1/orders/fields` - [Агрегация заказов](./orders/aggregate.md) — `POST /v1/orders/aggregate` ## Ключевые поля | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор заказа (только чтение) | | `accountNumber` | string | Номер счёта для покупателя — порядковый номер заказа на портале | | `lid` | string | Идентификатор сайта-источника, всегда `"s1"` для облачных порталов | | `personTypeId` | number | Идентификатор типа плательщика (юр. лицо, физ. лицо и т. п.). На каждом портале свой набор типов; перечислить их через REST API нельзя. Узнать ID можно, посмотрев существующие заказы: `GET /v1/orders` или `POST /v1/orders/aggregate` с `groupBy: "personTypeId"` | | `currency` | string | Валюта заказа. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `price` | number | Общая сумма заказа | | `statusId` | string | Текущий статус заказа. Источник: [`GET /v1/order-statuses?filter[type]=O`](./order-statuses/list.md) | | `userId` | number | Идентификатор пользователя Битрикс24 — покупателя в интернет-магазине. Источник: [`GET /v1/users`](/docs/entities/users) | | `companyId` | number | Идентификатор CRM-компании, связанной с заказом. Источник: [`GET /v1/companies`](/docs/entities/companies) | | `clients` | array | Список CRM-привязок (только чтение). Каждый элемент: `{entityTypeId, entityId, isPrimary, roleId, sort}`. `entityTypeId = 3` — контакт, `= 4` — компания. Заполняется Битрикс24 автоматически на основе `userId` и `companyId` | | `payed` | boolean | Оплачен ли заказ полностью | | `canceled` | boolean | Отменён ли заказ | | `responsibleId` | number | Ответственный сотрудник. Источник: [`GET /v1/users`](/docs/entities/users) | | `dateInsert` | datetime | Дата создания (только чтение) | | `dateUpdate` | datetime | Дата последнего изменения (только чтение) | Полный список полей — [`GET /v1/orders/fields`](./orders/fields.md). ## Что нужно знать перед работой 1. **Тело запроса плоское.** При создании и обновлении передавайте поля прямо в корне JSON: `{"lid": "s1", "personTypeId": 5, ...}`. Обёртка `fields` не нужна. 2. **Для создания обязательны три поля:** `lid` (всегда `"s1"` для облачных порталов), `personTypeId` (тип плательщика — на каждом портале свой набор), `currency`. Без них `POST /v1/orders` вернёт `BITRIX_ERROR` с перечислением отсутствующих полей. 3. **Заказ возвращает связанные сущности вложенно.** `GET /v1/orders/:id` отдаёт массивы `basketItems[]` (позиции корзины), `payments[]` (оплаты), `propertyValues[]` (свойства заказа), `clients[]` (CRM-привязки) внутри одного объекта. Отдельные эндпоинты [`/v1/basket-items`](./basket-items.md) и [`/v1/payments`](./payments.md) используются для создания и обновления — но для чтения содержимого одного заказа отдельные вызовы не нужны. 4. **Авто-пагинация** включается при `limit > 50`. Общее количество приходит в `meta.total`. ## Связанные сущности Полноценный жизненный цикл заказа использует семейство сущностей `sale.*`: | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Позиции корзины | [`GET /v1/basket-items?filter[orderId]=:id`](./basket-items.md) | Товарные позиции заказа — что купил покупатель, по какой цене, с какой скидкой. | | Оплаты | [`GET /v1/payments?filter[orderId]=:id`](./payments.md) | Оплаты заказа — сумма, платёжная система, статус «оплачено / возврат». | | Статусы заказов | [`GET /v1/order-statuses?filter[type]=O`](./order-statuses.md) | Каталог статусов для заполнения `statusId`. Тип `O` — статусы заказа, `D` — статусы доставки. | ## Типичный сценарий Обработка нового заказа из внешней системы (CMS, маркетплейс): 1. Получить список статусов заказов: [`GET /v1/order-statuses?filter[type]=O`](./order-statuses/list.md) — найти ID нужного статуса (например, `N` — «Принят»). 2. Создать заказ: [`POST /v1/orders`](./orders/create.md) с минимумом полей (`lid`, `personTypeId`, `currency`, `price`, `statusId`, `userId`). 3. Добавить позиции корзины: [`POST /v1/basket-items`](./basket-items/create.md) — по одной позиции на товар (`orderId`, `productId`, `quantity`, `price`). 4. Зарегистрировать оплату: [`POST /v1/payments`](./payments/create.md) — указав `orderId`, `paySystemId`, `sum`. 5. По мере выполнения — обновить статус: [`PATCH /v1/orders/:id`](./orders/update.md) с новым `statusId`. ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Позиции корзины](./basket-items.md) — товары в заказах - [Оплаты](./payments.md) — платежи по заказам - [Статусы заказов](./order-statuses.md) — каталог статусов - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Pages # Страницы Управление страницами лендингов и интернет-магазинов на платформе Битрикс24: создание, получение, обновление, удаление. Страница всегда принадлежит сайту и наследует от него тип `PAGE` или `STORE`. Битрикс24 API: `landing.landing.*` Скоуп: `landing` ## Операции - [Создать страницу](./pages/create.md) — `POST /v1/pages` - [Список страниц](./pages/list.md) — `GET /v1/pages` - [Получить страницу](./pages/get.md) — `GET /v1/pages/:id` - [Обновить страницу](./pages/update.md) — `PATCH /v1/pages/:id` - [Удалить страницу](./pages/delete.md) — `DELETE /v1/pages/:id` - [Поиск страниц](./pages/search.md) — `POST /v1/pages/search` ## Ключевые поля | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор страницы (только чтение) | | `title` | string | Название страницы, до 255 символов. Обязательно при создании | | `code` | string | Символьный код страницы в URL. Если не передавать — генерируется из `title`. Не должен содержать `/`. Внутри сайта или папки должен быть уникальным — иначе автоматически добавляется числовой суффикс | | `siteId` | number | Идентификатор сайта, которому принадлежит страница. Источник: [`GET /v1/sites`](/docs/entities/sites/list). Обязательно при создании | | `active` | boolean | Активна ли страница. Управляется только в интерфейсе портала Битрикс24: новые страницы создаются неактивными, через API изменить нельзя | | `description` | string \| null | Произвольное описание страницы. Приходит `null`, если не задано (в операционных доках [get](./pages/get.md) / [list](./pages/list.md) тип уже `string \| null` — здесь приведено к ним для единообразия) | | `createdById` | number | Идентификатор создавшего сотрудника (только чтение). Источник: [`GET /v1/users`](/docs/entities/users) | | `dateCreate` | datetime | Дата создания (только чтение) | | `dateModify` | datetime | Дата последнего изменения (только чтение) | ## Что нужно знать перед работой 1. **Тело запроса плоское.** При создании и обновлении передавайте поля прямо в корне JSON: `{"title": "...", "code": "...", "siteId": 3}`. Обёртка `fields` не нужна. 2. **Минимум для создания:** `title` + `siteId`. Остальные поля опциональны. 3. **Поле `active` через API не управляется.** При создании страница получает `active: false`. Передача `active: true` в `POST` или `PATCH` принимается без ошибки, но значение не сохраняется. Активировать страницу можно в интерфейсе портала Битрикс24, в разделе «Сайты». 4. **Списка полей через API нет.** Эндпоинт `GET /v1/pages/fields` не реализован — список доступных полей приведён в разделе «Ключевые поля» выше. 5. **Ответ может содержать дополнительные поля Битрикс24 — в camelCase.** Помимо ключевых полей, по умолчанию возвращаются дополнительные поля, и они приходят в **camelCase** (`deleted`, `xmlId`, `tplId`, `sitemap`, `folder`, `folderId`, `searchContent`, `modifiedById`, `domainId`, а также `initiatorAppCode`, `rule`, `public`, `sys`, `views`, `tplCode`, `version`, `historyStep`, `datePublic` и другие) — **не** в `UPPER_CASE`. Чтение по документированному имени `data[].XML_ID` / `MODIFIED_BY_ID` вернёт `undefined` — используйте camelCase. Чтобы получить только ключевые поля, передавайте параметр `select` в `GET /v1/pages`: `?select=id,title,code,siteId,active,description,createdById,dateCreate,dateModify`. См. примеры в [Списке страниц](./pages/list.md). Для `GET /v1/pages/:id` параметр `select` не применяется — отбор полей доступен только в списке. - Недокументированное поле `datePublic` у неопубликованной страницы приходит пустым объектом `{}` (артефакт сериализации пустой даты Битрикс24), а не датой/`null`. 6. **`offset` для постраничного перехода не поддерживается.** Метод получения списка не принимает параметр смещения. Для больших выборок используйте `limit > 50` (Вайбкод запрашивает несколько страниц и собирает результат) или сужайте фильтр. 7. **Сортировка не применяется.** Параметр `order` / `sort` принимается без ошибки, но порядок результата не меняется — выборка всегда возвращается в порядке возрастания идентификатора. Для подсчёта количества страниц используйте `meta.total` из [Списка страниц](./pages/list.md): `GET /v1/pages?filter[siteId]=3&limit=1` вернёт `meta.total` без выгрузки записей. ## Связанные сущности | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Сайты | [`GET /v1/sites`](/docs/entities/sites) | Контейнеры страниц. Источник `siteId` для создания страницы. Удалить сайт можно только после удаления всех его страниц. | ## Типичный сценарий 1. Найти сайт: [`GET /v1/sites`](/docs/entities/sites/list). 2. Посмотреть его страницы: [`GET /v1/pages?filter[siteId]=3`](./pages/list.md). 3. Создать новую или обновить существующую: [`POST /v1/pages`](./pages/create.md) / [`PATCH /v1/pages/:id`](./pages/update.md). 4. Удалить ненужные: [`DELETE /v1/pages/:id`](./pages/delete.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` | не поддерживается на уровне Битрикс24 | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Сайты](/docs/entities/sites) — управление сайтами, к которым относятся страницы - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Payments # Оплаты Управление оплатами заказов: создание, получение, обновление, удаление, поиск, агрегация. Оплата — отдельная сущность, привязанная к заказу по полю `orderId`. У одного заказа может быть несколько оплат (например, частичная предоплата + доплата при доставке), каждая со своей платёжной системой и статусом. Битрикс24 API: `sale.payment.*` Скоуп: `sale` ## Операции - [Создать оплату](./payments/create.md) — `POST /v1/payments` - [Список оплат](./payments/list.md) — `GET /v1/payments` - [Получить оплату](./payments/get.md) — `GET /v1/payments/:id` - [Обновить оплату](./payments/update.md) — `PATCH /v1/payments/:id` - [Удалить оплату](./payments/delete.md) — `DELETE /v1/payments/:id` - [Поиск оплат](./payments/search.md) — `POST /v1/payments/search` - [Агрегация оплат](./payments/aggregate.md) — `POST /v1/payments/aggregate` ## Ключевые поля | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор оплаты (только чтение) | | `accountNumber` | string | Порядковый номер оплаты на портале (только чтение) | | `orderId` | number | Идентификатор заказа. Источник: [`GET /v1/orders`](./orders/list.md) | | `paySystemId` | number | Идентификатор платёжной системы. На каждом портале свой набор систем; перечислить их через REST API нельзя. Узнать ID можно из существующих оплат: `GET /v1/payments` или `POST /v1/payments/aggregate` с `groupBy: "paySystemId"` | | `paySystemName` | string | Название платёжной системы (только чтение, приходит из карточки платёжной системы) | | `sum` | number | Сумма оплаты | | `currency` | string | Валюта оплаты. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `paid` | boolean | Помечена ли оплата как поступившая | | `datePaid` | datetime | Дата отметки оплаты | | `dateBill` | datetime | Дата выставления счёта | | `responsibleId` | number | Ответственный сотрудник. Источник: [`GET /v1/users`](/docs/entities/users) | | `isReturn` | string | Признак возврата: `"N"` (обычная оплата), `"Y"` (возврат), `"P"` (частичный возврат) | | `comments` | string | Комментарий к оплате | | `xmlId` | string | Внешний идентификатор для синхронизации | Полный ответ оплаты — см. пример в [Получить оплату](./payments/get.md). ## Что нужно знать перед работой 1. **Оплата всегда привязана к заказу.** Поле `orderId` обязательно при создании — без существующего заказа оплату создать нельзя, сначала вызовите [`POST /v1/orders`](./orders/create.md). На один заказ можно зарегистрировать несколько оплат (предоплата, доплата при доставке) — каждая отдельным `POST /v1/payments`. 2. **Тело запроса плоское.** При создании и обновлении передавайте поля прямо в корне JSON: `{"orderId": 19, "paySystemId": 11, ...}`. Обёртка `fields` не нужна. 3. **Поле `isReturn` — строка, а не boolean.** Принимает три значения: `"N"` (обычная оплата), `"Y"` (возврат) и `"P"` (частичный возврат) — фильтр и обновление работают по этим строкам. 4. **Сумма заказа не пересчитывается при создании оплаты.** Регистрация оплаты не меняет статус заказа (`orders.payed`, `orders.statusId`) — обновите их отдельным [`PATCH /v1/orders/:id`](./orders/update.md), если нужно отметить заказ как оплаченный. ## Связанные сущности | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Заказы | [`GET /v1/orders/:id`](./orders/get.md) | Родительский заказ — `orderId` указывается при создании оплаты. | | Позиции корзины | [`GET /v1/basket-items?filter[orderId]=:id`](./basket-items/list.md) | Товары в том же заказе. | | Сотрудники | [`GET /v1/users`](/docs/entities/users) | Источник `responsibleId`. | ## Типичный сценарий Регистрация оплаты от внешнего платёжного шлюза: 1. Найти заказ: [`GET /v1/orders?filter[xmlId]=:externalOrderId`](./orders/list.md) — например, по внешнему идентификатору заказа. 2. Создать оплату: [`POST /v1/payments`](./payments/create.md) с `orderId`, `paySystemId`, `sum`, `paid: true`, `xmlId` платёжной транзакции. 3. Обновить статус заказа после оплаты: [`PATCH /v1/orders/:id`](./orders/update.md) с `payed: true`, `statusId: "F"` (или другим финальным статусом). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Заказы](./orders.md) — родительская сущность для оплат - [Позиции корзины](./basket-items.md) — товары в заказе - [Статусы заказов](./order-statuses.md) — статусы для `orders.statusId` - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Product Sections # Product sections **Entity:** `productSection` | **Scope:** `crm` | **Base path:** `/v1/product-sections` > Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/product-sections` | List all (with filter, sort, pagination) | `crm.productsection.list` | | `GET` | `/v1/product-sections/:id` | Get by ID | `crm.productsection.get` | | `POST` | `/v1/product-sections` | Create new | `crm.productsection.add` | | `PATCH` | `/v1/product-sections/:id` | Update by ID | `crm.productsection.update` | | `DELETE` | `/v1/product-sections/:id` | Delete by ID | `crm.productsection.delete` | | `GET` | `/v1/product-sections/fields` | Get available fields | `crm.productsection.fields` | ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `ID` | number | yes | Идентификатор записи | | `name` | `NAME` | string | | | | `catalogId` | `CATALOG_ID` | number | | | | `sectionId` | `SECTION_ID` | number | | | | `xmlId` | `XML_ID` | string | | | | `sort` | `SORT` | number | | | | `code` | `CODE` | string | | | ## Examples ### List ```bash curl -X GET '/v1/product-sections?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/product-sections/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/product-sections' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"name":"value","catalogId":1,"sectionId":1}' ``` ### Update ```bash curl -X PATCH '/v1/product-sections/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"name":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/product-sections/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"product-sections","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Products # Products **Entity:** `product` | **Scope:** `crm` | **Base path:** `/v1/products` > Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/products` | List all (with filter, sort, pagination) | `crm.product.list` | | `GET` | `/v1/products/:id` | Get by ID | `crm.product.get` | | `POST` | `/v1/products` | Create new | `crm.product.add` | | `PATCH` | `/v1/products/:id` | Update by ID | `crm.product.update` | | `DELETE` | `/v1/products/:id` | Delete by ID | `crm.product.delete` | | `GET` | `/v1/products/fields` | Get available fields | `crm.product.fields` | ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `ID` | number | yes | Идентификатор записи | | `name` | `NAME` | string | | | | `active` | `ACTIVE` | boolean | | | | `price` | `PRICE` | number | | | | `currency` | `CURRENCY_ID` | string | | | | `sectionId` | `SECTION_ID` | number | | | | `catalogId` | `CATALOG_ID` | number | | | | `measure` | `MEASURE` | number | | | | `description` | `DESCRIPTION` | string | | | | `sort` | `SORT` | number | | | | `xmlId` | `XML_ID` | string | | | | `createdAt` | `DATE_CREATE` | datetime | yes | Дата создания | | `updatedAt` | `TIMESTAMP_X` | datetime | yes | Дата изменения | ## Relations (reference) | Relation | Entity | Type | Foreign Key | |----------|--------|------|-------------| | section | `productSection` | one | `sectionId` | ## Aggregatable Fields These fields can be used with the aggregation engine for analytics: - `price` - `sectionId` - `catalogId` - `active` ## Доступ из веб-интерфейса По полям `catalogId` и `id` товар открывается в магазине Битрикс24: ``` https://.bitrix24.ru/shop/catalog//product// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Examples ### List ```bash curl -X GET '/v1/products?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/products/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/products' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"name":"value","active":"true","price":1}' ``` ### Update ```bash curl -X PATCH '/v1/products/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"title":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/products/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"products","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Quotes # Предложения Управление коммерческими предложениями CRM: создание, получение, обновление, удаление, товарные позиции. Bitrix24 API: `crm.quote.*` Скоуп: `crm` ## Операции - [Создать предложение](./quotes/create.md) — `POST /v1/quotes` - [Список предложений](./quotes/list.md) — `GET /v1/quotes` - [Получить предложение](./quotes/get.md) — `GET /v1/quotes/:id` - [Обновить предложение](./quotes/update.md) — `PATCH /v1/quotes/:id` - [Удалить предложение](./quotes/delete.md) — `DELETE /v1/quotes/:id` - [Поиск предложений](./quotes/search.md) — `POST /v1/quotes/search` - [Поля предложения](./quotes/fields.md) — `GET /v1/quotes/fields` - [Агрегация предложений](./quotes/aggregate.md) — `POST /v1/quotes/aggregate` - [Получить товары](./quotes/products-get.md) — `GET /v1/quotes/:id/products` - [Установить товары](./quotes/products-set.md) — `PUT /v1/quotes/:id/products` - [Добавить товар](./quotes/products-add.md) — `POST /v1/quotes/:id/products` - [Удалить товар](./quotes/products-delete.md) — `DELETE /v1/quotes/:id/products/:rowId` - [Получить товар](./quotes/products-get-single.md) — `GET /v1/quotes/:id/products/:rowId` - [Обновить товар](./quotes/products-update.md) — `PATCH /v1/quotes/:id/products/:rowId` - [Поля товаров](./quotes/products-fields.md) — `GET /v1/quotes/:id/products/fields` --- # Entity: Requisite Presets # Requisite presets **Entity:** `requisitePreset` | **Scope:** `crm` | **Base path:** `/v1/requisite-presets` > Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/requisite-presets` | List all (with filter, sort, pagination) | `crm.requisite.preset.list` | | `GET` | `/v1/requisite-presets/:id` | Get by ID | `crm.requisite.preset.get` | | `POST` | `/v1/requisite-presets` | Create new | `crm.requisite.preset.add` | | `PATCH` | `/v1/requisite-presets/:id` | Update by ID | `crm.requisite.preset.update` | | `DELETE` | `/v1/requisite-presets/:id` | Delete by ID | `crm.requisite.preset.delete` | | `GET` | `/v1/requisite-presets/fields` | Get available fields | `crm.requisite.preset.fields` | ## Fields | API Name | Bitrix24 Name | Type | Readonly | Description | |----------|---------------|------|----------|-------------| | `id` | `ID` | number | yes | Идентификатор записи | | `entityTypeId` | `ENTITY_TYPE_ID` | number | | | | `countryId` | `COUNTRY_ID` | number | | | | `name` | `NAME` | string | | | | `active` | `ACTIVE` | boolean | | | | `sort` | `SORT` | number | | | | `xmlId` | `XML_ID` | string | | | | `originatorId` | `ORIGINATOR_ID` | string | | | | `createdAt` | `DATE_CREATE` | datetime | yes | Дата создания | | `updatedAt` | `DATE_MODIFY` | datetime | yes | Дата изменения | | `createdBy` | `CREATED_BY_ID` | number | yes | ID создателя | | `modifyBy` | `MODIFY_BY_ID` | number | yes | | ## Examples ### List ```bash curl -X GET '/v1/requisite-presets?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/requisite-presets/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Create ```bash curl -X POST '/v1/requisite-presets' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"entityTypeId":1,"countryId":1,"name":"value"}' ``` ### Update ```bash curl -X PATCH '/v1/requisite-presets/123' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"name":"updated"}' ``` ### Delete ```bash curl -X DELETE '/v1/requisite-presets/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"requisite-presets","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Requisites # Реквизиты Управление реквизитами CRM: создание, получение, обновление, удаление, фильтрация. Реквизиты всегда привязаны к контакту или компании и содержат юридическую информацию (название, ИНН/КПП/ОГРН, директор, бухгалтер и т. д.). Битрикс24 API: `crm.requisite.*` Скоуп: `crm` ## Операции - [Создать реквизит](./requisites/create.md) — `POST /v1/requisites` - [Список реквизитов](./requisites/list.md) — `GET /v1/requisites` - [Получить реквизит](./requisites/get.md) — `GET /v1/requisites/:id` - [Обновить реквизит](./requisites/update.md) — `PATCH /v1/requisites/:id` - [Удалить реквизит](./requisites/delete.md) — `DELETE /v1/requisites/:id` - [Поиск реквизитов](./requisites/search.md) — `POST /v1/requisites/search` - [Поля реквизита](./requisites/fields.md) — `GET /v1/requisites/fields` - [Агрегация реквизитов](./requisites/aggregate.md) — `POST /v1/requisites/aggregate` ## Ключевые поля | Поле | Описание | |------|---------| | `entityTypeId` | Тип родительской сущности: `3` — контакт, `4` — компания | | `entityId` | ID контакта или компании, которому принадлежит реквизит | | `presetId` | ID пресета (задаёт набор доступных полей, неизменяем после создания) | | `rqName` / `rqInn` / `rqKpp` / `rqOgrn` | Основные реквизиты юрлица | | `rqCompanyName` / `rqCompanyFullName` / `rqDirector` / `rqAccountant` | Название и руководство | | `rqOkpo` / `rqOkved` / `rqOktmo` / `rqVatPayer` | Классификаторы и НДС | Полный список полей — [`GET /v1/requisites/fields`](./requisites/fields.md). ## Что нужно знать перед работой 1. **Пресет определяет набор полей.** У пресета «ООО» одни поля (ИНН, КПП, ОГРН, директор), у пресета «Физлицо» — другие (ФИО, паспорт, дата рождения). 2. **Для создания нужны 3 поля:** `entityTypeId`, `entityId`, `presetId`. `presetId` получается из `GET /v1/requisite-presets` — программное создание реквизита больше не требует копирования ID из UI Битрикса. 3. **60 популярных полей возвращаются в camelCase.** Поля международных пресетов (RQ_EDRPOU/Украина, RQ_KBE/Казахстан, RQ_REGON/Польша, RQ_SIRET/Франция, RQ_CNPJ/Бразилия) возвращаются в `UPPER_SNAKE_CASE` — фильтр по ним также доступен только в исходном регистре. См. [Поля реквизита](./requisites/fields.md). Чтобы получить только поля своего пресета — добавьте `?presetId=N` к `GET /v1/requisites/fields` (фильтрует по `crm.requisite.preset.field.list`). ## Связанные сущности Полноценная работа с реквизитами (счета, договоры, печатные формы) требует сопутствующих сущностей — все обёрнуты в Vibe API: | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Пресеты реквизитов | `GET /v1/requisite-presets` | Шаблоны реквизитов («ООО», «ИП», «Физлицо», «Иностранное юрлицо»). Источник `presetId` для создания реквизита. | | Поля пресета | `GET /v1/requisite-presets/:presetId/fields` | Какие именно поля входят в конкретный пресет (для валидации перед `POST /v1/requisites`). | | Банковские реквизиты | `GET /v1/bank-details?entityTypeId=8&entityId=:requisiteId` | Р/с, БИК, к/с, SWIFT, IBAN. Без них нельзя выставить оплатный счёт. | | Адреса | `GET /v1/addresses?entityTypeId=8&entityId=:requisiteId` | Юридический, фактический, почтовый, доставки. Композитный ключ `(typeId, entityTypeId, entityId)`. | | Связи реквизитов | `POST /v1/requisite-links` | Привязка конкретного реквизита (и опционально банка) к счёту/предложению. Нужно мультиреквизитным компаниям. | | Кастомные UF-поля | `POST /v1/userfields/requisites` | UF_CRM_* поля на реквизитах — добавить, изменить, удалить. | ## Типичный сценарий 1. Найти контакт или компанию: [`GET /v1/contacts`](/docs/entities/contacts) / [`GET /v1/companies`](/docs/entities/companies). 2. Посмотреть её реквизиты: [`GET /v1/requisites?filter[entityTypeId]=4&filter[entityId]=15`](./requisites/list.md). 3. Создать новый или обновить существующий: [`POST /v1/requisites`](./requisites/create.md) / [`PATCH /v1/requisites/:id`](./requisites/update.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Sites # Сайты Управление сайтами на платформе Битрикс24: создание, получение, обновление, удаление, поиск, агрегация. Сайт — это контейнер страниц одного типа: лендинг (`PAGE`) или интернет-магазин (`STORE`). У каждого сайта свой домен или поддомен на портале, символьный код, шаблон и набор страниц. Битрикс24 API: `landing.site.*` Скоуп: `landing` ## Операции - [Создать сайт](./sites/create.md) — `POST /v1/sites` - [Список сайтов](./sites/list.md) — `GET /v1/sites` - [Получить сайт](./sites/get.md) — `GET /v1/sites/:id` - [Обновить сайт](./sites/update.md) — `PATCH /v1/sites/:id` - [Удалить сайт](./sites/delete.md) — `DELETE /v1/sites/:id` - [Поиск сайтов](./sites/search.md) — `POST /v1/sites/search` - [Агрегация сайтов](./sites/aggregate.md) — `POST /v1/sites/aggregate` ## Поля ### Изменяемые поля Принимаются при [создании](./sites/create.md) и [обновлении](./sites/update.md). | Поле | Тип | Описание | |------|-----|---------| | `title` | string | Название сайта, до 255 символов | | `code` | string | Символьный код сайта в URL. Если оставить пустым при создании — генерируется из `title`. Если код состоит только из цифр, добавляется префикс `site` | | `type` | string | Тип сайта: `PAGE` (лендинг) или `STORE` (интернет-магазин) | | `active` | boolean | Активен ли сайт | | `domainId` | number | Идентификатор домена. Если не передать при создании — адрес сгенерируется автоматически | | `description` | string | Описание сайта, до 255 символов | | `xmlId` | string | Внешний идентификатор, до 255 символов | | `landingIdIndex` | number | Идентификатор главной страницы. Задаётся только в обновлении — после создания страниц | | `landingId404` | number | Идентификатор страницы ошибки 404. Задаётся только в обновлении | | `landingId503` | number | Идентификатор страницы ошибки 503. Задаётся только в обновлении | ### Только для чтения Приходят в ответе, но не принимаются при создании и обновлении. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор сайта | | `deleted` | string | Признак нахождения в корзине: `"Y"` / `"N"`. Доступен в фильтре (`filter[deleted]=Y`) | | `createdById` | number | Идентификатор создавшего пользователя | | `modifiedById` | number | Идентификатор пользователя, изменившего сайт последним | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | | `tplId` | number | Идентификатор шаблона сайта | | `tplCode` | string | Символьный код шаблона сайта | | `smnSiteId` | string | Идентификатор связанного сайта «Управление сайтом» (для типа `SMN`) | | `lang` | string | Код языка сайта (например, `ru`) | | `special` | string | Служебный признак Битрикс24: `"Y"` / `"N"` | | `version` | number | Версия внутренней структуры сайта | ## Что нужно знать перед работой 1. **Тело запроса плоское.** При создании и обновлении передавайте поля прямо в корне JSON: `{"title": "...", "code": "..."}`. Обёртка `fields` не нужна. 2. **Удалить можно только пустой сайт.** Если у сайта есть хотя бы одна страница (включая страницы в корзине), `DELETE /v1/sites/:id` вернёт ошибку `BITRIX_ERROR` с описанием «Сайт содержит страницы». Сначала удалите страницы, затем сам сайт. 3. **Видимость зависит от прав пользователя.** Список и агрегация возвращают только те сайты, к которым у владельца API-ключа есть право «просмотр». Если на портале есть сайты, но ответ пустой — проверьте права пользователя, под которым выпущен ключ. 4. **Корзина — `filter[deleted]=Y`.** По умолчанию удалённые сайты не возвращаются. Чтобы получить сайты в корзине, добавьте в фильтр `deleted=Y` (значения `"Y"` / `"N"`). 5. **Списка полей через API нет.** Эндпоинт `GET /v1/sites/fields` не реализован — список доступных полей фиксирован и приведён в разделе «Поля» выше. ## Связанные сущности | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Страницы | [`GET /v1/pages`](/docs/entities/pages) | Страницы сайта. Получите список страниц с `filter[siteId]=:id` перед удалением сайта или для редактирования содержимого. | ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Smart Processes # Типы смарт-процессов Управление типами смарт-процессов: создание, получение, обновление, удаление, поиск. Тип — это шаблон (определение сущности), а не запись в нём. Для работы с элементами внутри типа используйте [`/v1/items/:entityTypeId`](/docs/entities/items). Битрикс24 API: `crm.type.*` Скоуп: `crm` ## Операции - [Создать тип](./smart-processes/create.md) — `POST /v1/smart-processes` - [Список типов](./smart-processes/list.md) — `GET /v1/smart-processes` - [Получить тип](./smart-processes/get.md) — `GET /v1/smart-processes/:entityTypeId` - [Обновить тип](./smart-processes/update.md) — `PATCH /v1/smart-processes/:entityTypeId` - [Удалить тип](./smart-processes/delete.md) — `DELETE /v1/smart-processes/:entityTypeId` - [Поиск типов](./smart-processes/search.md) — `POST /v1/smart-processes/search` - [Поля типа](./smart-processes/fields.md) — `GET /v1/smart-processes/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `entityTypeId` | **Главный идентификатор типа.** Используется во всех запросах к элементам через `/v1/items/:entityTypeId`. Генерируется при создании автоматически, неизменяем | | `title` | Название типа, которое видят пользователи в интерфейсе Битрикс24 | | `isCategoriesEnabled` | Включены ли свои воронки и туннели продаж | | `isStagesEnabled` | Включены ли свои стадии и канбан | | `isClientEnabled` | Есть ли поле «Клиент» (контакты и компании) | | `isLinkWithProductsEnabled` | Можно ли привязывать товары каталога | | `relations` | Связи с другими сущностями CRM (сделки, контакты, другие смарт-процессы) | Полный список из 27 полей — [Поля типа](./smart-processes/fields.md). ## Что нужно знать перед работой 1. **Тип ≠ элемент.** `/v1/smart-processes` управляет **определениями** (шаблонами). Для записей внутри типа — `/v1/items/:entityTypeId`. 2. **`entityTypeId` — ключ связи с элементами.** После создания типа сохраните его и передавайте во все запросы к элементам. Изменить `entityTypeId` нельзя. 3. **Новый тип не инициализирован.** Сразу после `POST /v1/smart-processes` поле `isInitialized: false`. Для готовности к работе добавьте воронки и стадии через [`/v1/categories/:entityTypeId`](/docs/entities/categories). 4. **`relations` двунаправленные.** Связь, созданная в `parent` одного типа, автоматически появится в `child` у связанной сущности. ## Типичный сценарий 1. Посмотреть, какие типы уже есть: [`GET /v1/smart-processes`](./smart-processes/list.md). 2. Создать новый тип со всеми нужными возможностями: [`POST /v1/smart-processes`](./smart-processes/create.md) с флагами `isStagesEnabled`, `isCategoriesEnabled` и т. д. 3. Сохранить `entityTypeId` из ответа — он понадобится для всех дальнейших вызовов. 4. Настроить воронки для типа: [`POST /v1/categories/:entityTypeId`](/docs/entities/categories). 5. Работать с элементами внутри типа: [`/v1/items/:entityTypeId`](/docs/entities/items) — CRUD, поиск, товары, пользовательские поля. ## Лимиты | Лимит | Значение | |-------|----------| | Максимум типов на портал | Зависит от тарифа Битрикс24 (при превышении — `CREATE_DYNAMIC_TYPE_RESTRICTED`) | | Диапазон `entityTypeId` при auto-gen | Чётные числа `≥ 1030` | | Диапазон `entityTypeId` при явной передаче | `128–192` включительно | | Удаление типа с элементами | Запрещено — сначала удалите элементы через [`DELETE /v1/items/:entityTypeId/:id`](/docs/entities/items) | | Rate limit | Общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Элементы смарт-процессов](/docs/entities/items) — CRUD по элементам типа - [Воронки и стадии](/docs/entities/categories) — настройка после создания типа - [Пользовательские поля](/docs/userfields) — создание `ufCrm_*` полей для элементов - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Entity: Statuses # Справочники CRM Стадии сделок, источники, типы контактов, отрасли и другие классификаторы. Центральная сущность для enum-значений всей CRM. Bitrix24 API: `crm.status.*` Скоуп: `crm` Для получения конкретного типа используйте фильтр: `?filter[entityId]=DEAL_STAGE` ## Операции - [Создать запись](./statuses/create.md) — `POST /v1/statuses` - [Список записей](./statuses/list.md) — `GET /v1/statuses` - [Получить запись](./statuses/get.md) — `GET /v1/statuses/:id` - [Обновить запись](./statuses/update.md) — `PATCH /v1/statuses/:id` - [Удалить запись](./statuses/delete.md) — `DELETE /v1/statuses/:id` - [Поля справочника](./statuses/fields.md) — `GET /v1/statuses/fields` ## Типы справочников (entityId) | entityId | Описание | |----------|----------| | `STATUS` | Статусы лидов | | `SOURCE` | Источники | | `CONTACT_TYPE` | Типы контактов | | `COMPANY_TYPE` | Типы компаний | | `INDUSTRY` | Отрасли | | `DEAL_STAGE` | Стадии общей воронки (categoryId 0) | | `DEAL_STAGE_{N}` | Стадии воронки N (напр. `DEAL_STAGE_3`) | | `QUOTE_STATUS` | Статусы предложений | | `HONORIFIC` | Обращения (контакты) | | `EMPLOYEES` | Количество сотрудников (компании) | | `DEAL_TYPE` | Типы сделок | --- # Entity: Storages # Storages **Entity:** `diskStorage` | **Scope:** `disk` | **Base path:** `/v1/storages` > Legacy entity (UPPER_CASE field names) — field names are automatically converted to camelCase. ## Operations | Method | Path | Description | Bitrix24 Method | |--------|------|-------------|-----------------| | `GET` | `/v1/storages` | List all (with filter, sort, pagination) | `disk.storage.getlist` | | `GET` | `/v1/storages/:id` | Get by ID | `disk.storage.get` | | `GET` | `/v1/storages/fields` | Get available fields | `disk.storage.getFields` | > **Disabled operations:** `create`, `update`, `delete` ## Fields | API Name | Bitrix24 Name | Type | Readonly | Nullable | Description | |----------|---------------|------|----------|----------|-------------| | `id` | `ID` | number | yes | no | Идентификатор хранилища | | `name` | `NAME` | string | yes | no | Название хранилища | | `code` | `CODE` | string | yes | **yes** | Символьный код. На практике всегда `null` | | `module` | `MODULE_ID` | string | yes | no | Модуль-владелец хранилища (`"disk"`) | | `entityType` | `ENTITY_TYPE` | string | yes | no | Тип владельца (`user` / `group` / `common`) | | `entityId` | `ENTITY_ID` | **string** | yes | no | Идентификатор владельца. **Строка**, в т.ч. нечисловая (например `"shared_files_s1"` у common-хранилища) — не приводите к числу | | `rootFolderId` | `ROOT_OBJECT_ID` | number | yes | no | ID корневой папки хранилища | > **Типы и нульность (важно):** > - `entityId` — **строка**, а не число: `disk.storage.getlist`/`get` отдаёт ID владельца строкой, а у common-хранилищ значение вообще нечисловое (`"shared_files_s1"`). `GET /v1/storages/fields` уже декларирует `string`. > - Поле API называется `rootFolderId` (ранее в этой таблице ошибочно — `rootObjectId`; так зовётся только исходное B24-поле `ROOT_OBJECT_ID`). > - `code` всегда приходит `null` на проверенных порталах — типизируйте как `string | null`. > - `id` и `rootFolderId` — настоящие JSON-числа; имена полей камелкейсятся на чтении (raw UPPER_SNAKE не утекает). ## Examples ### List ```bash curl -X GET '/v1/storages?limit=10' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Get by ID ```bash curl -X GET '/v1/storages/123' \ -H 'X-Api-Key: YOUR_KEY' ``` ### Batch ```bash curl -X POST '/v1/batch' \ -H 'X-Api-Key: YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{"calls":[{"entity":"storages","action":"list","params":{"limit":5}}]}' ``` --- # Entity: Task Comments # Комментарии задач Комментарии — вложенный ресурс задачи. У каждого комментария есть автор, текст и время создания. Базовый путь — `/v1/tasks/:taskId/comments`. Все операции требуют существующей задачи (`:taskId`) на портале. Битрикс24 API: `tasks.task.chat.message.*`, `task.commentitem.*` Скоуп: `task` ## Операции - [Создать комментарий](./task-comments/create.md) — `POST /v1/tasks/:taskId/comments` - [Список комментариев](./task-comments/list.md) — `GET /v1/tasks/:taskId/comments` - [Получить комментарий](./task-comments/get.md) — `GET /v1/tasks/:taskId/comments/:id` - [Обновить комментарий](./task-comments/update.md) — `PATCH /v1/tasks/:taskId/comments/:id` - [Удалить комментарий](./task-comments/delete.md) — `DELETE /v1/tasks/:taskId/comments/:id` - [Пакет операций](./task-comments/comments-batch.md) — `POST /v1/tasks/:taskId/comments/batch` ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Идентификатор комментария | | `taskId` | ID родительской задачи (берётся из пути URL) | | `authorId` | Автор. Список сотрудников: `GET /v1/users` | | `message` | Текст комментария, до 20 000 символов. Поддерживает BB-код `[USER=ID]Имя[/USER]`, `[B]...[/B]`, `[QUOTE]...[/QUOTE]` и другие | | `createdAt` | Дата и время создания, UTC ISO 8601 | ## Что нужно знать перед работой 1. **У задачи две карточки.** В Битрикс24 параллельно живут две версии карточки задачи: «новая» (на базе чата) и «старая» (с блоком комментариев внутри самой карточки). Вызов одинаковый, но под капотом API сам выбирает рабочий путь в зависимости от того, как настроен портал. Различия видны только в PATCH/DELETE — см. ниже. 2. **PATCH и DELETE на новой карточке возвращают 410 GONE.** На новой карточке Битрикс24 нет публичного API обновления / удаления комментариев — он отправляет только новые сообщения. На порталах со старой карточкой обновление и удаление продолжают работать без изменений. API возвращает `410 GONE` с текстом и подсказкой, если попал на новую карточку, и `200`/`204` — на старой. 3. **POST возвращает реальный `id` сообщения.** На новой карточке после отправки комментария API выполняет дополнительный поиск по чату задачи и возвращает фактический идентификатор. В редком случае (OAuth-приложение + несколько одинаковых сообщений подряд в одном чате) `id` может прийти как `null` — тогда найдите комментарий через `GET /v1/tasks/:taskId/comments`. 4. **Системные сообщения не возвращаются.** Чат задачи содержит уведомления типа «задача поставлена», «срок изменён» — `GET /v1/tasks/:taskId/comments` их пропускает. В списке только пользовательские комментарии. 5. **`meta.total` — оценка.** Метод чата не возвращает общее количество, поэтому API считает по факту. Если в текущей странице меньше элементов, чем `limit`, то `total` равен числу элементов, иначе — `+1`. Опирайтесь на `meta.hasMore` для пагинации. 6. **Плоский путь `/v1/task-comments` не существует.** Все операции — только в виде `/v1/tasks/:taskId/comments/...`. Вызов без префикса вернёт `400 WRONG_PATH` с подсказкой. ## Типичный сценарий 1. Найти задачу: [`GET /v1/tasks`](./tasks/list.md) или прямой ID из создания задачи. 2. Добавить комментарий: [`POST /v1/tasks/:taskId/comments`](./task-comments/create.md) с `message`. 3. Показать обсуждение: [`GET /v1/tasks/:taskId/comments`](./task-comments/list.md) — поддерживает `limit`, сортировку по `id`, фильтр на старой карточке. 4. Если нужно массовое добавление — [`POST /v1/tasks/:taskId/comments/batch`](./task-comments/comments-batch.md) (до 50 сообщений). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум символов в `message` | 20 000 | | Максимум элементов в одном batch-вызове | 50 | | Размер страницы `limit` | до 200 | | Rate limit | общий для API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Задачи](./tasks.md) — родительская сущность - [Учёт времени задач](./tasks/time.md) — другой вложенный ресурс задачи - [Сотрудники](/docs/entities/users) — источник `authorId` - [Batch-запросы](/docs/batch) — массовые операции через универсальный `POST /v1/batch` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Entity: Tasks # Задачи Управление задачами портала: создание, чтение, обновление, удаление, фильтрация, агрегация. Задача — единица работы с ответственным, постановщиком, сроком и статусом. У одной задачи могут быть комментарии и записи учёта времени — это отдельные вложенные ресурсы. Битрикс24 API: `tasks.task.*` Скоуп: `tasks` ## Операции - [Создать задачу](./tasks/create.md) — `POST /v1/tasks` - [Список задач](./tasks/list.md) — `GET /v1/tasks` - [Получить задачу](./tasks/get.md) — `GET /v1/tasks/:id` - [Обновить задачу](./tasks/update.md) — `PATCH /v1/tasks/:id` - [Удалить задачу](./tasks/delete.md) — `DELETE /v1/tasks/:id` - [Поиск задач](./tasks/search.md) — `POST /v1/tasks/search` - [Поля задачи](./tasks/fields.md) — `GET /v1/tasks/fields` - [Агрегация задач](./tasks/aggregate.md) — `POST /v1/tasks/aggregate` У задачи есть вложенные ресурсы со своими CRUD-операциями: [Комментарии задач](./task-comments.md) (`/v1/tasks/:taskId/comments`) и [Учёт времени задач](./tasks/time.md) (`/v1/tasks/:taskId/time`). ## Ключевые поля | Поле | Описание | |------|---------| | `title` | Название задачи | | `description` | Текст задачи (поддерживает BB-код, флаг `descriptionInBbcode`) | | `responsibleId` | Ответственный. Список сотрудников: `GET /v1/users` | | `createdBy` | Постановщик (заполняется системой). Список сотрудников: `GET /v1/users` | | `status` | Статус задачи (число). Расшифровка значений: `GET /v1/tasks/fields` → `fields.status.enum` | | `priority` | Приоритет (число). Расшифровка значений: `GET /v1/tasks/fields` → `fields.priority.enum` | | `deadline` | Крайний срок (ISO 8601) | | `groupId` | Рабочая группа. Список: `GET /v1/workgroups` | Полный список полей — [`GET /v1/tasks/fields`](./tasks/fields.md). ## Что нужно знать перед работой 1. **Минимум для создания:** `title` и `responsibleId`. Если ответственный не указан, портал возвращает ошибку «Не указан исполнитель». 2. **Статус и приоритет — числовые коды**, а не строки. Полная таблица соответствий приходит в ответе `GET /v1/tasks/fields` в поле `fields.status.enum` / `fields.priority.enum`. Например, `status: 2` — задача ждёт выполнения, `status: 5` — завершена. 3. **`realStatus` — имя только для ФИЛЬТРА, в ответах его нет.** `status` (виртуальный) приходит и в списке, и в карточке; `subStatus` приходит **только в списке** — карточка `GET /v1/tasks/:id` его НЕ возвращает (под-статус просрочки `-1`/`-2`/`-3` читается только из списка). Для просроченных и почти просроченных задач `status`/`subStatus` принимают значения `-1` / `-2` / `-3` поверх реальных `1..7`. `REAL_STATUS` — фильтруемое поле B24 (реальный хранимый статус, всегда `1..7`); ключа `realStatus` в JSON-ответе не бывает — читайте `status` + `subStatus`. Из этого выходит ловушка фильтрации: запрос `?filter[STATUS][]=2&filter[STATUS][]=3&filter[STATUS][]=4` тихо теряет просроченные задачи — у них `STATUS = -2`, хотя `REAL_STATUS` всё ещё `2`. Рецепты по сценариям: - «Активные без просроченных»: `filter[STATUS][]=2&filter[STATUS][]=3&filter[STATUS][]=4`. - «Активные включая просроченные»: `filter[REAL_STATUS][]=2&filter[REAL_STATUS][]=3&filter[REAL_STATUS][]=4`. - «Только просроченные»: `filter[STATUS]=-2`. 4. **Числовые поля сериализуются строками.** В ответах списка и одиночной задачи поля-идентификаторы (`id`, `responsibleId`, `createdBy`, `groupId`) и числовые перечисления (`status`, `priority`) приходят как строки, например `"id": "289"`, `"status": "2"`. Конвертация на стороне клиента — простой `Number(...)`. 5. **Даты в собственном часовом поясе портала.** Поля `createdDate`, `changedDate`, `closedDate`, `deadline` и подобные приходят в формате ISO 8601 со смещением (`2026-05-12T11:46:12+03:00`), а не в UTC. Для расчётов приводите к `Date` или `Date.parse`. 6. **Пользователи внутри задачи.** Поля `creator` и `responsible` приходят встроенно как объекты вида `{ id, name, link, icon, workPosition }` — отдельный запрос на профили не нужен. 7. **`accomplices` и `auditors` — массивы строковых идентификаторов** пользователей (соисполнители и наблюдатели). Если задача только что создана и в ней нет соисполнителей и наблюдателей, поля приходят пустыми массивами. ## Типичный сценарий 1. Найти ответственного: [`GET /v1/users`](/docs/entities/users) (или фильтрованный поиск с нужным именем). 2. Создать задачу: [`POST /v1/tasks`](./tasks/create.md) с `title` и `responsibleId`. 3. Дополнить детали: [`PATCH /v1/tasks/:id`](./tasks/update.md) — `deadline`, `priority`, `description`, `auditors`. 4. Зафиксировать прогресс — комментарий: [`POST /v1/tasks/:taskId/comments`](./task-comments/create.md). 5. Учесть время: [`POST /v1/tasks/:taskId/time`](./tasks/time/create.md). 6. Закрыть задачу: [`PATCH /v1/tasks/:id`](./tasks/update.md) → `status: 5`. ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Разбиение по временны́м окнам для больших выборок | `POST /v1/tasks/search` с `autoWindow: true` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Комментарии задач](./task-comments.md) — обсуждение задачи - [Учёт времени задач](./tasks/time.md) — записи о потраченном времени - [Справочник сущностей](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) - [Batch-запросы](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Entity: Timelines # Комментарии таймлайна Управление комментариями таймлайна CRM: запись заметок оператора, истории переговоров и прочего контекста к сделкам, лидам, контактам, компаниям и другим сущностям. Каждый комментарий привязан к конкретной записи CRM через пару `entityType` + `entityId`. Битрикс24 API: `crm.timeline.comment.*` Скоуп: `crm` ## Операции - [Добавить комментарий](./timelines/create.md) — `POST /v1/timelines` - [Список комментариев](./timelines/list.md) — `GET /v1/timelines` - [Получить комментарий](./timelines/get.md) — `GET /v1/timelines/:id` - [Обновить комментарий](./timelines/update.md) — `PATCH /v1/timelines/:id` - [Удалить комментарий](./timelines/delete.md) — `DELETE /v1/timelines/:id` - [Поля комментария](./timelines/fields.md) — `GET /v1/timelines/fields` ## Закрепление, привязки, заметки Операции Bitrix24 семейств `crm.timeline.item.*`, `crm.timeline.bindings.*`, `crm.timeline.note.*` универсальны — работают с любым элементом таймлайна по `id + ownerTypeId + ownerId`. Поэтому к комментариям применимы те же действия, что и к лог-записям. Ниже — копии 8 эндпоинтов из раздела [`/v1/timeline-logs`](/docs/timeline-logs), смонтированные на корне `/v1/timelines`: | Метод | Путь | B24-метод | Назначение | |------|------|-----------|------------| | POST | `/v1/timelines/:id/pin` | `crm.timeline.item.pin` | Закрепить комментарий поверх таймлайна | | POST | `/v1/timelines/:id/unpin` | `crm.timeline.item.unpin` | Снять закрепление | | POST | `/v1/timelines/:id/bind` | `crm.timeline.bindings.bind` | Дополнительно привязать комментарий к другой сущности (например, контакту) | | POST | `/v1/timelines/:id/unbind` | `crm.timeline.bindings.unbind` | Снять одну из привязок | | GET | `/v1/timelines/:id/bindings` | `crm.timeline.bindings.list` | Получить все привязки комментария | | POST | `/v1/timelines/:id/note` | `crm.timeline.note.save` | Сохранить заметку (текстовое примечание) на комментарии | | GET | `/v1/timelines/:id/note` | `crm.timeline.note.get` | Прочитать заметку | | DELETE | `/v1/timelines/:id/note` | `crm.timeline.note.delete` | Удалить заметку | Полные сигнатуры запросов / ответов и примеры — в зеркале раздела [`/v1/timeline-logs`](/docs/timeline-logs): [pins](/docs/timeline-logs/pins), [bindings](/docs/timeline-logs/bindings), [notes](/docs/timeline-logs/notes). Тело запроса, формат ответа и коды ошибок идентичны — отличается только префикс пути. ## Ключевые поля | Поле | Описание | |------|---------| | `entityType` | Тип родительской записи CRM: `deal`, `lead`, `contact`, `company` или `DYNAMIC_` для смарт-процессов (например `DYNAMIC_174`). Обязателен при создании и в фильтре | | `entityId` | ID родительской записи. Источник зависит от типа: `GET /v1/deals`, `GET /v1/leads`, `GET /v1/contacts`, `GET /v1/companies`, `GET /v1/items/:entityTypeId` (элементы смарт-процессов). Обязателен при создании и в фильтре | | `comment` | Текст комментария. Обязателен при создании | | `authorId` | ID автора. Данные пользователя по ID: `GET /v1/users/:id` | | `createdAt` | Дата создания (только чтение) | Полный список полей — [`GET /v1/timelines/fields`](./timelines/fields.md). ## Что нужно знать перед работой 1. **Фильтр по `entityType` + `entityId` обязателен.** Список комментариев выбирается только в контексте конкретной родительской записи — глобального списка «всех комментариев портала» нет. Запрос без этих полей возвращает `400 MISSING_REQUIRED_FILTER`. 2. **Для создания нужно 3 поля:** `entityType`, `entityId`, `comment`. Автор проставляется по владельцу API-ключа, дата — сервером. 3. **Комментарий обновляется по `id`**, а `entityType` и `entityId` фиксируются при создании и после обновлению не подлежат. 4. **Значения `entityType` — строковые идентификаторы CRM-типов.** Числовые коды CRM (`entityTypeId`) для `entityType` не подходят: они возвращают `BITRIX_ERROR Access denied.`. Используйте `deal`, `lead`, `contact`, `company` или `DYNAMIC_` для смарт-процессов (например, `DYNAMIC_174` для смарт-процесса с `entityTypeId: 174` из [`GET /v1/smart-processes`](/docs/entities/smart-processes/list)). В ответе API `entityType` возвращается в нижнем регистре (`dynamic_174`). ## Типичный сценарий 1. Найти родительскую запись: [`GET /v1/deals`](/docs/entities/deals/list), [`GET /v1/leads`](/docs/entities/leads/list), [`GET /v1/contacts`](/docs/entities/contacts), [`GET /v1/companies`](/docs/entities/companies) или [`GET /v1/items/:entityTypeId`](/docs/entities/items/list) для элементов смарт-процессов. 2. Посмотреть её комментарии: [`GET /v1/timelines?filter[entityType]=deal&filter[entityId]=741`](./timelines/list.md). 3. Добавить новый комментарий: [`POST /v1/timelines`](./timelines/create.md). 4. При необходимости изменить текст: [`PATCH /v1/timelines/:id`](./timelines/update.md), удалить: [`DELETE /v1/timelines/:id`](./timelines/delete.md). ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Сделки](./deals.md), [Лиды](./leads.md), [Контакты](./contacts.md), [Компании](./companies.md) — типичные родительские сущности - [Логи таймлайна](/docs/timeline-logs) — чтение полной истории активности записи CRM (включает не только комментарии, но и системные события) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Users # Пользователи Управление сотрудниками портала: список, получение по ID, приглашение нового, обновление, деактивация. Сущность хранит контактные данные, должность, отдел и пользовательские поля (UF) сотрудника. Битрикс24 API: `user.*` Скоуп: `user` ## Операции - [Создать сотрудника](./users/create.md) — `POST /v1/users` - [Пригласить сотрудника](./users/invite.md) — `POST /v1/users/invite` - [Список сотрудников](./users/list.md) — `GET /v1/users` - [Получить сотрудника](./users/get.md) — `GET /v1/users/:id` - [Обновить сотрудника](./users/update.md) — `PATCH /v1/users/:id` - [Деактивировать сотрудника](./users/delete.md) — `DELETE /v1/users/:id` - [Поиск сотрудников](./users/search.md) — `POST /v1/users/search` - [Поля сотрудника](./users/fields.md) — `GET /v1/users/fields` - [Агрегация сотрудников](./users/aggregate.md) — `POST /v1/users/aggregate` ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Идентификатор сотрудника | | `name` / `lastName` / `secondName` | Имя, фамилия, отчество | | `email` | Email — обязательно при создании, должен быть уникальным среди всех сотрудников портала | | `active` | Признак активности: `true` — работает, `false` — деактивирован | | `workPosition` | Должность | | `departmentId` | Массив ID отделов сотрудника. Список: `GET /v1/departments` | | `personalPhone` / `personalMobile` / `workPhone` | Телефоны | | `isAdmin` | Признак администратора портала (только чтение). **Важно:** объявлено в `GET /v1/users/fields`, но `user.get` его **не возвращает** — `data.isAdmin` фактически `undefined` даже у владельца портала. Не используйте его для проверки прав (получите ложное «не админ»). | Полный список полей — [`GET /v1/users/fields`](/docs/entities/users/fields). ## Что нужно знать перед работой 1. **Создание требует email.** Поле `email` обязательное и должно быть уникальным для всего портала. Дубль вернёт `BITRIX_ERROR: wrong_email` без явного указания причины — этот код Битрикс24 использует для нескольких разных кейсов (см. ниже). 2. **Два эндпоинта для создания.** [`POST /v1/users`](/docs/entities/users/create) — обычная entity-форма, проксирует ошибки Битрикс24 как есть. [`POST /v1/users/invite`](/docs/entities/users/invite) — обёртка с предзаполнением `departmentId: [1]` для штатных сотрудников и явной валидацией email на стороне Вайбкод (`EMAIL_REQUIRED`, `EMAIL_INVALID`). Для интеграций предпочтительнее `/invite` — у него понятные коды ошибок. 3. **PATCH и DELETE требуют прав администратора портала.** Битрикс24 применяет обновление сотрудника только если у владельца ключа есть админские права на портале. Без них Битрикс24 возвращает `result: false`, Вайбкод оборачивает это в `403 UPDATE_FAILED` с подсказкой в поле `hint`. 4. **`DELETE /v1/users/:id` — это деактивация.** Эндпоинт снимает у сотрудника доступ к порталу, но сохраняет всю запись и её связи (ответственный за сделки, автор комментариев, участник чатов). Под капотом маппится на обновление поля активности (`active: false`), в ответе явный маркер `deactivated: true`. Восстановить доступ — `PATCH /v1/users/:id { active: true }`. Данные не теряются. 5. **Поля только для чтения.** `id`, `isOnline`, `isAdmin`, `lastLogin`, `dateRegister`, `lastActivityDate`, `userType`, `timestampX` заполняются системой. Попытка передать их в `PATCH /v1/users/:id` отклоняется заранее с `400 READONLY_FIELD` — вызов Битрикс24 не происходит. 6. **`WORK_*` / `PERSONAL_*` обычно не приходят, а пустые поля Битрикс24 опускает.** Стандартные заполненные поля (`name`, `email`, `active`, `departmentId`, `timeZone`, `userType` и др.) — `camelCase`. Поля `WORK_COMPANY`, `WORK_DEPARTMENT`, `PERSONAL_STATE`, `PERSONAL_ZIP` и аналогичные на практике в ответе **отсутствуют** (Битрикс24 не возвращает незаполненные поля); если такое поле всё же приходит — оно сохраняет исходное имя `UPPER_SNAKE_CASE` (не камелкейсится). То есть ключа может **не быть вовсе** — не полагайтесь на его присутствие. 7. **«Пусто» в datetime-полях закодировано тремя способами.** `timestampX` и `lastActivityDate` (объявлены `datetime`) приходят **пустым объектом `{}`**, а не строкой/`null` (`new Date(u.timestampX)` → `Invalid Date`; `if (u.lastActivityDate)` — **истинно** даже без активности). `lastActivityDate` к тому же может **отсутствовать** как ключ. `lastLogin` отдаёт `null`, когда входа не было. `dateRegister` — ISO-строка всегда (полночь UTC). Проверяйте «активность была» сравнением типа (`typeof x === 'string'`), а не truthy-проверкой. 8. **Внешние сотрудники (extranet).** При создании пользователя экстранета `EXTRANET: "Y"` обязательное поле `SONET_GROUP_ID` (массив ID рабочих групп) вместо `departmentId`. `/invite` явно отдаёт `400 SONET_GROUP_ID_REQUIRED`, если оба не переданы. ## Типичный сценарий 1. Найти сотрудника по части имени или email: [`GET /v1/users?filter[NAME]=Иван`](/docs/entities/users/list). 2. Получить полные данные одного: [`GET /v1/users/:id`](/docs/entities/users/get). 3. Пригласить нового через Вайбкод-обёртку: [`POST /v1/users/invite`](/docs/entities/users/invite). 4. Обновить должность или отдел: [`PATCH /v1/users/:id`](/docs/entities/users/update). 5. Если сотрудник уволился — деактивировать: [`DELETE /v1/users/:id`](/docs/entities/users/delete). Восстановить — `PATCH /v1/users/:id { active: true }`. ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Отделы](/docs/entities/departments) — `departmentId` берётся из `GET /v1/departments` - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовые операции - [Справочник сущностей](/docs/entities-index) --- # Entity: Warehouses # Склады Склады портала и товарные остатки на них. Склад — это точка хранения или выдачи товаров каталога: физический склад, магазин или пункт выдачи. Склады можно создавать, изменять и удалять. Остатки товаров доступны только для чтения — по отдельному складу или сводно по всем складам. Битрикс24 API: `catalog.store.*`, `catalog.storeproduct.*` Скоуп: `catalog` ## Операции - [Создать склад](./warehouses/create.md) — `POST /v1/warehouses` - [Список складов](./warehouses/list.md) — `GET /v1/warehouses` - [Получить склад](./warehouses/get.md) — `GET /v1/warehouses/:id` - [Обновить склад](./warehouses/update.md) — `PATCH /v1/warehouses/:id` - [Удалить склад](./warehouses/delete.md) — `DELETE /v1/warehouses/:id` - [Остатки склада](./warehouses/stock.md) — `GET /v1/warehouses/:id/stock` - [Сводные остатки по товарам](./warehouses/stock-totals.md) — `GET /v1/warehouses/stock/totals` ## Поля ### Изменяемые поля Принимаются при [создании](./warehouses/create.md) и [обновлении](./warehouses/update.md). Передаются в корне JSON. | Поле | Тип | Описание | |------|-----|---------| | `title` | string | Название склада. Обязательно при создании | | `address` | string | Адрес склада. Обязательно при создании | | `active` | string | Активность: `"Y"` или `"N"`. По умолчанию `"Y"` | | `issuingCenter` | string | Признак пункта выдачи заказов: `"Y"` или `"N"`. По умолчанию `"N"` | | `description` | string | Описание склада | | `phone` | string | Контактный телефон | | `email` | string | Контактная почта | | `schedule` | string | Режим работы — произвольный текст | | `sort` | number | Порядок сортировки. По умолчанию `100` | | `code` | string | Символьный код | | `xmlId` | string | Внешний идентификатор для синхронизации с внешними системами | | `gpsN` | number | Географическая широта | | `gpsS` | number | Географическая долгота | | `userId` | number | Ответственный сотрудник — идентификатор из [`GET /v1/users`](/docs/entities/users) | ### Только для чтения Приходят в ответе, но не принимаются при создании и обновлении. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор склада | | `imageId` | object | Изображение склада в формате `{ "id": number, "url": string }` либо `null` | | `modifiedBy` | number | Идентификатор пользователя, изменившего склад последним | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | ## Что нужно знать перед работой 1. **Тело запроса плоское.** При создании и обновлении передавайте поля прямо в корне JSON: `{"title": "...", "address": "..."}`. Обёртка `fields` не нужна. 2. **Для создания обязательны два поля.** Без `title` или `address` ответ — `400 MISSING_PARAMS`. Остальные поля необязательны: при отсутствии заполняются значениями по умолчанию (`active: "Y"`, `sort: 100`, `issuingCenter: "N"`). 3. **Несуществующий склад — ошибка `422`.** Получение, обновление или удаление склада по неизвестному `id` возвращает `422` с кодом `BITRIX_ERROR`, а не `404`. Проверить наличие склада можно через [список складов](./warehouses/list.md). 4. **Остатки доступны только для чтения.** Количество товаров на складе нельзя изменить через этот раздел: [остатки склада](./warehouses/stock.md) и [сводные остатки](./warehouses/stock-totals.md) — операции получения. Остатки меняются документами складского учёта на стороне портала. 5. **Сводные остатки агрегируются по товару.** [`GET /v1/warehouses/stock/totals`](./warehouses/stock-totals.md) складывает количество одного товара по всем складам и возвращает список складов (`storeIds`), где этот товар представлен. ## Типичный сценарий 1. Получить список складов: [`GET /v1/warehouses`](./warehouses/list.md) — взять `id` нужного склада. 2. Посмотреть остатки на складе: [`GET /v1/warehouses/:id/stock`](./warehouses/stock.md). 3. Свести остатки одного товара по всем складам: [`GET /v1/warehouses/stock/totals?productId=200`](./warehouses/stock-totals.md). ## Связанные сущности | Сущность | Эндпоинт | Назначение | |----------|----------|-----------| | Товары каталога | [`GET /v1/catalog-products`](/docs/entities/catalog-products) | Товары, остатки которых учитываются на складах. Поле `productId` в [остатках](./warehouses/stock.md) и [сводных остатках](./warehouses/stock-totals.md) ссылается на товар каталога. | ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Rate limit | общий для API Вайбкод — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Товары каталога](/docs/entities/catalog-products) - [Каталоги](/docs/entities/catalogs) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Entity: Workgroups # Рабочие группы Управление рабочими группами и проектами портала: создание, получение, обновление, удаление, поиск. Рабочая группа объединяет сотрудников вокруг общей темы или проекта — у неё есть владелец, тема, флаги открытости и архивирования, а также счётчик участников. Битрикс24 API: `sonet_group.*` Скоуп: `sonet_group` ## Операции - [Создать рабочую группу](./workgroups/create.md) — `POST /v1/workgroups` - [Список рабочих групп](./workgroups/list.md) — `GET /v1/workgroups` - [Получить рабочую группу](./workgroups/get.md) — `GET /v1/workgroups/:id` - [Обновить рабочую группу](./workgroups/update.md) — `PATCH /v1/workgroups/:id` - [Удалить рабочую группу](./workgroups/delete.md) — `DELETE /v1/workgroups/:id` - [Поиск рабочих групп](./workgroups/search.md) — `POST /v1/workgroups/search` - [Поля рабочей группы](./workgroups/fields.md) — `GET /v1/workgroups/fields` ## Ключевые поля | Поле | Описание | |------|---------| | `name` | Название рабочей группы | | `ownerId` | Идентификатор владельца. Источник: [`GET /v1/users`](/docs/entities/users) | | `subjectId` | Идентификатор темы. Список допустимых значений отдаётся в ответах [`GET /v1/workgroups`](./workgroups/list.md) в поле `subjectName` рядом с `subjectId` | | `opened` | Признак открытости — может ли вступить любой сотрудник портала | | `isProject` | Признак проекта — у проектов отдельная семантика в задачах и отчётах | | `archived` | Признак архива — группа скрыта из активных списков, но сохранена | | `membersCount` | Текущее количество участников группы | Полный список полей — [`GET /v1/workgroups/fields`](./workgroups/fields.md). ## Что нужно знать перед работой 1. **Булевы поля имеют разный формат на входе и в ответе.** В URL-фильтрах (`?filter[active]=...`) булевы поля передаются как `Y` или `N`. В теле запросов `POST` / `PATCH` и в body `POST /v1/workgroups/search` работают и `Y` / `N`, и нативные JSON `true` / `false`. В ответах всех эндпоинтов — всегда `true` / `false`. 2. **`archived` и `active` — разные признаки.** `archived: true` означает, что группа перенесена в архив и не отображается в активных списках; `active: false` означает, что группа выключена. Это два независимых состояния. 3. **`isProject: true` — отдельная семантика.** Проектные группы по-другому ведут себя в задачах и отчётах Битрикс24. Чтобы создать обычную рабочую группу без проектной логики, оставьте `isProject` пустым или передайте `false`. 4. **Темы задаются на стороне портала.** Перечень допустимых `subjectId` настраивается администратором Битрикс24 и не редактируется через API рабочих групп. Сопоставление `subjectId` ↔ `subjectName` возвращается в каждом элементе списка рабочих групп. ## Типичный сценарий 1. Найти будущего владельца группы: [`GET /v1/users?filter[name]=Иван`](/docs/entities/users). 2. Создать рабочую группу: [`POST /v1/workgroups`](./workgroups/create.md) с `name`, `ownerId`, `subjectId`, `opened`. 3. Получить список рабочих групп сотрудника: [`GET /v1/workgroups?filter[ownerId]=15`](./workgroups/list.md). 4. Обновить параметры: [`PATCH /v1/workgroups/:id`](./workgroups/update.md) — например, переключить `opened` или изменить `description`. 5. Перенести группу в архив: [`PATCH /v1/workgroups/:id`](./workgroups/update.md) с `archived: true`. ## Лимиты | Лимит | Значение | |-------|----------| | Максимум записей на запрос | 5000 (`limit ≤ 5000`) | | Авто-пагинация | включается при `limit > 50` | | `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` | | Batch-запросы | до 50 операций в [`POST /v1/batch`](/docs/batch) | | Ограничение частоты запросов | общее для API Вайбкода — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Справочник сущностей](/docs/entities-index) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) - [Сотрудники](/docs/entities/users) - [Отделы](/docs/entities/departments) --- # Activities: Aggregate ## Агрегация дел `POST /v1/activities/aggregate` Подсчёт количества дел с фильтрацией и группировкой. **Стандартные поля:** - `typeId` — тип активности (для `groupBy`) - `ownerTypeId` — тип родительской сущности (для `groupBy`) - `responsibleId` — ответственный (для `groupBy`) - `completed` — статус выполнения (для `groupBy`) Все поля в `aggregatable` — категориальные идентификаторы, поэтому основной сценарий — `count` с группировкой. Числовые функции `sum`/`avg`/`min`/`max` применяются редко. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "*", "function": "count" }`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/activities/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше | ## Примеры ### curl — личный ключ Количество дел по сделке (`ownerTypeId: 2` — сделка), сгруппированное по типу активности: ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/activities/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "ownerTypeId": 2, "ownerId": 741, "completed": "Y" }, "groupBy": "typeId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/activities/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "ownerTypeId": 2, "ownerId": 741, "completed": "Y" }, "groupBy": "typeId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { ownerTypeId: 2, ownerId: 741, completed: 'Y' }, groupBy: 'typeId', }), }) const { success, data } = await res.json() console.log('Всего завершённых дел по сделке:', data.count) console.log('Распределение по типу:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { ownerTypeId: 2, ownerId: 741, completed: 'Y' }, groupBy: 'typeId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["typeId", "completed"]` (максимум 5). ## Другие сценарии Общее количество дел в портале — самый быстрый запрос, без выгрузки записей: ```json {} ``` Группировка дел по контакту (`ownerTypeId: 3`) по статусу выполнения: ```json { "filter": { "ownerTypeId": 3, "ownerId": 485 }, "groupBy": "completed" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций (для дел обычно пустой) | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей обработано (для `count` — `0`, записи не выгружаются) | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (`groupBy: "typeId"`): ```json { "success": true, "data": { "count": 2600, "aggregates": {}, "groups": [ { "typeId": 1, "count": 1200 }, { "typeId": 2, "count": 800 }, { "typeId": 6, "count": 600 } ], "meta": { "totalRecords": 2600, "recordsProcessed": 2600, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — `groupBy` по неаггрегируемому полю или несуществующему полю: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "groupBy field 'subject' is not aggregatable on this entity. Available: typeId, ownerTypeId, responsibleId, completed" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Универсальный `ownerTypeId`.** Для счётчиков по родительской сущности используйте пары `ownerTypeId` + `ownerId`: `2` — сделка, `3` — контакт, `4` — компания, `1` — лид. Это самый частый сценарий для `/v1/activities/aggregate`. ## Смотрите также - [Список дел](/docs/entities/activities/list) — получить записи с фильтрацией - [Поиск дел](/docs/entities/activities/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Activities: Create ## Создать дело `POST /v1/activities` Создаёт новое CRM-дело: звонок, встречу, задачу или email. Дело привязывается к CRM-сущности через `ownerTypeId` + `ownerId`. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `typeId` | number | Тип: `1` — звонок, `2` — встреча, `3` — задача, `6` — email | | `ownerTypeId` | number | Тип родительской сущности: `1` — лид, `2` — сделка, `3` — контакт, `4` — компания | | `ownerId` | number | ID родительской сущности. Поиск: `GET /v1/deals`, `GET /v1/leads`, `GET /v1/contacts` | | `subject` | string | Тема дела | | `description` | string | Описание | | `responsibleId` | number | Ответственный. Список: `GET /v1/users` | | `priority` | number | Приоритет: `1` — низкий, `2` — средний, `3` — высокий | | `direction` | number | Направление: `1` — входящее, `2` — исходящее | | `completed` | boolean | Завершена | | `startTime` | datetime | Дата начала | | `endTime` | datetime | Дата окончания | | `deadline` | datetime | Крайний срок | Полный список полей: [GET /v1/activities/fields](/docs/entities/activities/fields). ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/activities \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "typeId": 2, "ownerTypeId": 2, "ownerId": 741, "subject": "Встреча по проекту", "description": "Обсуждение условий поставки", "responsibleId": 1, "priority": 2, "direction": 2, "startTime": "2026-04-16T10:00:00+03:00", "endTime": "2026-04-16T11:00:00+03:00", "deadline": "2026-04-16T11:00:00+03:00" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/activities \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "typeId": 2, "ownerTypeId": 2, "ownerId": 741, "subject": "Встреча по проекту", "description": "Обсуждение условий поставки", "responsibleId": 1, "priority": 2, "direction": 2, "startTime": "2026-04-16T10:00:00+03:00", "endTime": "2026-04-16T11:00:00+03:00", "deadline": "2026-04-16T11:00:00+03:00" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ typeId: 2, ownerTypeId: 2, ownerId: 741, subject: 'Встреча по проекту', description: 'Обсуждение условий поставки', responsibleId: 1, priority: 2, direction: 2, startTime: '2026-04-16T10:00:00+03:00', endTime: '2026-04-16T11:00:00+03:00', deadline: '2026-04-16T11:00:00+03:00', }), }) const { success, data } = await res.json() console.log('Activity ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ typeId: 2, ownerTypeId: 2, ownerId: 741, subject: 'Встреча по проекту', description: 'Обсуждение условий поставки', responsibleId: 1, priority: 2, direction: 2, startTime: '2026-04-16T10:00:00+03:00', endTime: '2026-04-16T11:00:00+03:00', deadline: '2026-04-16T11:00:00+03:00', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного дела | | `typeId` | number | Тип дела | | `ownerTypeId` | number | Тип родительской сущности | | `ownerId` | number | ID родительской сущности | | `subject` | string | Тема | | `responsibleId` | number | Ответственный | | `createdAt` | datetime | Дата создания | | `updatedAt` | datetime | Дата изменения | Ответ содержит все поля дела. ## Пример ответа ```json { "success": true, "data": { "id": 3894, "typeId": 2, "ownerTypeId": 2, "ownerId": 741, "subject": "Встреча по проекту", "description": "Обсуждение условий поставки", "responsibleId": 1, "priority": 2, "direction": 2, "completed": false, "startTime": "2026-04-16T10:00:00+03:00", "endTime": "2026-04-16T11:00:00+03:00", "deadline": "2026-04-16T11:00:00+03:00", "createdAt": "2026-04-15T14:30:00+03:00", "updatedAt": "2026-04-15T14:30:00+03:00" } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список дел](/docs/entities/activities/list) — получение с фильтрами - [Поля дела](/docs/entities/activities/fields) — полный список полей - [Сделки](/docs/entities/deals) — привязка через `ownerTypeId=2` - [Лиды](/docs/entities/leads) — привязка через `ownerTypeId=1` - [Entity API](/docs/entity-api) — общие принципы - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Activities: Delete ## Удалить дело `DELETE /v1/activities/:id` Удаляет дело по ID. Восстановить удалённое дело через API нельзя — создавайте новое при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID дела | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/activities/3894" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/activities/3894" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/3894', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Дело удалено') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/3894', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — дело не найдено: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Activity is not found." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Дело не найдено или нет прав на удаление | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список дел](/docs/entities/activities/list) — найти перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Activities: Fields ## Поля дела `GET /v1/activities/fields` Возвращает полный список доступных полей дела. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/activities/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/activities/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | ID дела | | `typeId` | number | | Тип: `1` — звонок, `2` — встреча, `3` — задача, `6` — email | | `ownerTypeId` | number | | Тип родительской сущности: `1` — лид, `2` — сделка, `3` — контакт, `4` — компания | | `ownerId` | number | | ID родительской сущности. Поиск зависит от `ownerTypeId`: `GET /v1/deals`, `GET /v1/leads`, `GET /v1/contacts`, `GET /v1/companies` | | `associatedEntityId` | number | да | ID связанной сущности (звонок/письмо/встреча в b24-модуле). Заполняется автоматически после создания дела соответствующим провайдером | | `subject` | string | | Тема дела | | `description` | string | | Описание | | `descriptionType` | number | | Тип описания: `1` — plain text, `3` — BBCode/HTML | | `responsibleId` | number | | Ответственный. Список: `GET /v1/users` | | `authorId` | number | да | Автор записи. Заполняется b24 на основании текущего пользователя при создании | | `editorId` | number | да | Последний редактор. Обновляется b24 при каждом изменении | | `priority` | number | | Приоритет: `1` — низкий, `2` — средний, `3` — высокий | | `direction` | number | | Направление: `1` — входящее, `2` — исходящее | | `location` | string | | Место проведения (для встреч) | | `completed` | boolean | | Завершена | | `status` | number | | Статус дела: `1` — ожидание, `2` — в процессе, `3` — выполнено | | `startTime` | datetime | | Дата начала | | `endTime` | datetime | | Дата окончания | | `deadline` | datetime | | Крайний срок | | `createdAt` | datetime | да | Дата создания | | `updatedAt` | datetime | да | Дата изменения | | `notifyType` | number | | Тип напоминания: `0` — выкл., `1` — за минуты, `2` — за часы, `3` — за дни | | `notifyValue` | number | | Значение напоминания (в единицах из `notifyType`) | | `providerId` | string | | ID провайдера дела (`CRM_CALL_LIST`, `IMOL`, `CRM_REQUEST` и т.п.) | | `providerTypeId` | string | | Подтип провайдера (зависит от `providerId`) | | `providerGroupId` | string | | Идентификатор группы провайдера (например, по треду e-mail) | | `providerParams` | object | | Произвольные параметры провайдера (структура зависит от `providerId`) | | `providerData` | string | | Сериализованные данные провайдера (XML/JSON в строке) | | `settings` | object | | Дополнительные настройки дела (структура зависит от `typeId` и `providerId`) | | `originId` | string | | Внешний ID, если дело пришло из стороннего канала (CTI, email) | | `originatorId` | string | | ID источника-инициатора (приложение/коннектор) | | `resultStatus` | number | | Статус результата дела (числовой код) | | `resultStream` | number | | Поток обработки результата | | `resultSourceId` | string | | Источник результата | | `resultMark` | number | | Оценка/маркер результата | | `resultValue` | number | | Численное значение результата | | `resultSum` | number | | Сумма по результату (например, чек) | | `resultCurrencyId` | string | | Валюта результата (`RUB`, `USD`, …) | | `autocompleteRule` | number | | Правило автозавершения дела (числовой код) | | `isIncomingChannel` | boolean | да | Дело пришло из входящего канала (open-line/звонок/письмо). Только чтение | ## Значения typeId | Значение | Тип дела | |----------|---------------| | `1` | Звонок | | `2` | Встреча | | `3` | Задача | | `6` | Email | ## Значения ownerTypeId | Значение | Родительская сущность | Поиск | |----------|----------------------|-------| | `1` | Лид | `GET /v1/leads` | | `2` | Сделка | `GET /v1/deals` | | `3` | Контакт | `GET /v1/contacts` | | `4` | Компания | `GET /v1/companies` | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "assignedById": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Ответственный" } } } } ``` Показаны 3 из множества полей. Полный список в таблице выше. ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать дело](/docs/entities/activities/create) — какие поля передавать - [Entity API](/docs/entity-api) — select для выборки полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Activities: Get ## Получить дело `GET /v1/activities/:id` Возвращает дело по ID со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID дела | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/activities/3894" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/activities/3894" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/3894', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Дело:', data.subject, '— завершена:', data.completed) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/3894', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект дела со всеми полями — см. [Поля дела](/docs/entities/activities/fields). ## Пример ответа ```json { "success": true, "data": { "id": 3894, "typeId": 2, "ownerTypeId": 2, "ownerId": 741, "subject": "Встреча по проекту", "description": "Обсуждение условий поставки", "responsibleId": 1, "priority": 2, "direction": 2, "completed": false, "startTime": "2026-04-16T10:00:00+03:00", "endTime": "2026-04-16T11:00:00+03:00", "deadline": "2026-04-16T11:00:00+03:00", "createdAt": "2026-04-15T14:30:00+03:00", "updatedAt": "2026-04-15T14:30:00+03:00" } } ``` ## Пример ответа при ошибке 404 — дело не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Дело с таким ID не найдено | | 403 | `ACCESS_DENIED` | Нет доступа к делу | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить дело](/docs/entities/activities/update) — изменение полей - [Список дел](/docs/entities/activities/list) — поиск с фильтрами - [Поля дела](/docs/entities/activities/fields) — описание всех полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Activities: List ## Список дел `GET /v1/activities` Возвращает список CRM-дел с поддержкой фильтрации, сортировки и авто-пагинации. Фильтр по `ownerId` + `ownerTypeId` возвращает дела конкретной сделки, лида или контакта. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` авто-пагинация | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,subject,typeId,completed` | | `order` | object | — | Сортировка: `?order[deadline]=asc` | | `filter` | object | — | Фильтрация по полям `GET /v1/activities/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[ownerTypeId]=2&filter[ownerId]=741` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/activities?filter[ownerTypeId]=2&filter[ownerId]=741&limit=10&select=id,subject,typeId,completed" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/activities?filter[ownerTypeId]=2&filter[ownerId]=741&limit=10&select=id,subject,typeId,completed" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities?filter[ownerTypeId]=2&filter[ownerId]=741&limit=10&select=id,subject,typeId,completed', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} дел`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities?filter[ownerTypeId]=2&filter[ownerId]=741&limit=10&select=id,subject,typeId,completed', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив дел (поля — см. [Поля](/docs/entities/activities/fields)) | | `meta.total` | number | Общее количество записей | | `meta.hasMore` | boolean | Есть ещё записи | ## Пример ответа ```json { "success": true, "data": [ { "id": 3894, "typeId": 2, "ownerTypeId": 2, "ownerId": 741, "subject": "Встреча по проекту", "responsibleId": 1, "priority": 2, "direction": 2, "completed": false, "deadline": "2026-04-16T11:00:00+03:00", "createdAt": "2026-04-15T14:30:00+03:00", "updatedAt": "2026-04-15T14:30:00+03:00" } ], "meta": { "total": 84, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц. **Фильтр по сущности:** для получения дел конкретной сделки используйте `filter[ownerTypeId]=2&filter[ownerId]=741`. Значения `ownerTypeId`: `1` — лид, `2` — сделка, `3` — контакт, `4` — компания. **Поля для группировки и агрегации:** `typeId`, `ownerTypeId`, `responsibleId`, `authorId`, `editorId`, `completed`, `status`, `direction`, `providerId`, `providerTypeId`. Используются в `POST /v1/activities/aggregate` (см. [Агрегация](/docs/entities/activities/aggregate)). ## Смотрите также - [Поиск дел](/docs/entities/activities/search) — POST-запрос для сложных фильтров - [Создать дело](/docs/entities/activities/create) — создание нового - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Activities: Search ## Поиск дел `POST /v1/activities/search` Поиск дел с фильтрами через POST — удобнее для сложных запросов. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/activities/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[ownerTypeId]=2&filter[ownerId]=741` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "deadline": "asc" }` | | `select` | string[] | — | Выборка полей: `["id", "subject", "typeId", "completed"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/activities/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "ownerTypeId": 2, "ownerId": 741, "completed": false }, "limit": 20, "order": { "deadline": "asc" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/activities/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "ownerTypeId": 2, "ownerId": 741, "completed": false }, "limit": 20, "order": { "deadline": "asc" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { ownerTypeId: 2, ownerId: 741, completed: false }, limit: 20, order: { deadline: 'asc' }, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { ownerTypeId: 2, ownerId: 741, completed: false }, limit: 20, order: { deadline: 'asc' }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив дел (поля — см. [Поля](/docs/entities/activities/fields)) | ## Пример ответа ```json { "success": true, "data": [ { "id": 3894, "typeId": 2, "ownerTypeId": 2, "ownerId": 741, "subject": "Встреча по проекту", "responsibleId": 1, "completed": false, "deadline": "2026-04-16T11:00:00+03:00", "createdAt": "2026-04-15T14:30:00+03:00" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поля для группировки и агрегации:** `typeId`, `ownerTypeId`, `responsibleId`, `authorId`, `editorId`, `completed`, `status`, `direction`, `providerId`, `providerTypeId`. Используются в `POST /v1/activities/aggregate` (см. [Агрегация](/docs/entities/activities/aggregate)). ## Смотрите также - [Список дел](/docs/entities/activities/list) — GET-запрос для простых фильтров - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Activities: Update ## Обновить дело `PATCH /v1/activities/:id` Обновляет поля существующей дела. Передайте только изменяемые поля. Полный список в [справочнике полей](/docs/entities/activities/fields). ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `completed` | boolean | Отметить завершённой | | `subject` | string | Тема | | `deadline` | datetime | Крайний срок | | `responsibleId` | number | Ответственный. Список: `GET /v1/users` | | `priority` | number | Приоритет: `1` — низкий, `2` — средний, `3` — высокий | | `description` | string | Описание | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/activities/3894" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "completed": true, "subject": "Встреча по проекту (завершена)" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/activities/3894" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "completed": true, "subject": "Встреча по проекту (завершена)" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/3894', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ completed: true, subject: 'Встреча по проекту (завершена)', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/activities/3894', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ completed: true, subject: 'Встреча по проекту (завершена)', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект дела со всеми полями — см. [Поля](/docs/entities/activities/fields) | Обновлённый объект дела — см. [Поля дела](/docs/entities/activities/fields). ## Пример ответа ```json { "success": true, "data": { "id": 100, "subject": "Обновлённая тема", "completed": true, "responsibleId": 1, "createdAt": "2026-04-15T12:00:00.000Z", "updatedAt": "2026-04-15T13:00:00.000Z" } } ``` ## Пример ответа при ошибке 404 — дело не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Дело не найдено | | 403 | `ACCESS_DENIED` | Нет доступа | | 400 | `INVALID_REQUEST` | Невалидные поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить дело](/docs/entities/activities/get) — текущие значения - [Поля дела](/docs/entities/activities/fields) — все доступные поля - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Basket Items: Aggregate ## Агрегация позиций корзины `POST /v1/basket-items/aggregate` Подсчёт количества позиций и числовые агрегации (`sum`, `avg`, `min`, `max`) по полям `price` и `quantity`. Поддерживает фильтрацию и группировку по `orderId`, `productId`, `currency`. ## Стандартные поля | Поле | Назначение | |------|------------| | `price` | Числовое — подходит для `sum` / `avg` / `min` / `max` (агрегации по цене за единицу) | | `quantity` | Числовое — подходит для `sum` / `avg` / `min` / `max` (агрегации по количеству) | | `currency` | Категориальное — используется в `groupBy` (по валюте) | | `orderId`, `productId` | Идентификаторы — используются в `groupBy` (по заказу или товару) | Полный список агрегируемых полей перечислен в таблице выше. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций: `[{ "field": "quantity", "function": "sum" }]`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без параметра — только `count` | | `filter` | object | нет | Фильтрация — те же поля, что в [`GET /v1/basket-items`](./list.md). [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5) | | `groupOrderBy` | array | нет | Сортировка групп: `[{ "field": "quantity:sum", "direction": "desc" }]` | | `groupLimit` | number | нет | Ограничение количества возвращаемых групп (1-1000) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/basket-items/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "quantity", "function": "sum" }, { "field": "price", "function": "avg" } ], "groupBy": "productId", "groupLimit": 5 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/basket-items/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "quantity", "function": "sum" }, { "field": "price", "function": "avg" } ], "groupBy": "productId", "groupLimit": 5 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'quantity', function: 'sum' }, { field: 'price', function: 'avg' }, ], groupBy: 'productId', groupLimit: 5, }), }) const { success, data } = await res.json() console.log('Топ-5 товаров по продажам:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'quantity', function: 'sum' }], groupBy: 'productId', }), }) const { success, data } = await res.json() ``` ## Другие сценарии Общее количество позиций без выгрузки записей: ```json {} ``` Общая стоимость всех позиций в заказе: ```json { "aggregate": [{ "field": "price", "function": "sum" }], "filter": { "orderId": 33 } } ``` Топ-3 товаров по сумме продаж: ```json { "aggregate": [{ "field": "quantity", "function": "sum" }], "groupBy": "productId", "groupOrderBy": [{ "field": "quantity:sum", "direction": "desc" }], "groupLimit": 3 } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество позиций, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций: `{ "quantity": { "sum": ... }, "price": { "avg": ... } }` | | `data.groups` | array | Группы (только при `groupBy`) | | `data.meta.totalRecords` | number | Общее количество записей | | `data.meta.recordsProcessed` | number | Количество обработанных записей (до 5000) | | `data.meta.truncated` | boolean | `true`, если записей больше 5000 | | `data.meta.groupTotal` | number | Количество групп до `groupLimit` | | `data.meta.groupsTruncated` | boolean | Был ли список групп обрезан `groupLimit` | ## Пример ответа ```json { "success": true, "data": { "count": 261, "aggregates": { "quantity": { "sum": 412 } }, "groups": [ { "productId": 119, "count": 23, "aggregates": { "quantity": { "sum": 47 } } }, { "productId": 245, "count": 18, "aggregates": { "quantity": { "sum": 36 } } }, { "productId": 87, "count": 14, "aggregates": { "quantity": { "sum": 21 } } } ], "meta": { "totalRecords": 261, "recordsProcessed": 261, "truncated": false, "groupTotal": 89, "groupsTruncated": true } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неизвестное поле в `groupBy`: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Unknown field 'foo'. Available: price, quantity, currency, orderId, productId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Неизвестная функция или несуществующее поле — сообщение содержит список допустимых полей | | 400 | `INVALID_PARAMS` | Передано больше 5 полей в `groupBy` | | 400 | `INVALID_PARAMS` | Зарезервированные ключевые слова в `groupBy`: `count`, `aggregates`, `meta`, `groups` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` против числовых функций.** `count` считается одним запросом в Битрикс24 — записи не выгружаются, ответ возвращается быстро на любом объёме. `sum` / `avg` / `min` / `max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод. При более чем 5000 записях `meta.truncated` будет `true`. **Учёт незавершённых корзин.** В выборку попадают и позиции с `orderId: null` (товары в незавершённых корзинах). Чтобы исключить их, добавьте `filter[orderId][!]=null`. ## Смотрите также - [Список позиций](./list.md) — `meta.total` даёт точное число записей - [Поиск позиций](./search.md) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Basket Items: Create ## Добавить позицию в корзину `POST /v1/basket-items` Добавляет новую товарную позицию в существующий заказ. Тело запроса плоское — без обёртки `fields`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `orderId` | number | да | Идентификатор заказа. Источник: [`GET /v1/orders`](../orders/list.md) | | `productId` | number | да | Идентификатор товара в каталоге. Источник: [`GET /v1/catalog-products`](/docs/entities/catalog-products). Передайте `0`, чтобы создать виртуальный товар без привязки к каталогу | | `name` | string | да | Название позиции. Если передан `productId > 0` — название лучше скопировать из карточки товара | | `price` | number | да | Цена за единицу (итоговая, с учётом скидки) | | `currency` | string | да | Валюта позиции. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `quantity` | number | да | Количество | | `basePrice` | number | нет | Базовая цена до скидки. По умолчанию равна `price` | | `discountPrice` | number | нет | Размер скидки за единицу. По умолчанию `0` | | `vatRate` | number | нет | Ставка НДС в долях единицы (`0.20` = 20%, `0.10` = 10%, `0` — без НДС) | | `vatIncluded` | boolean | нет | Включён ли НДС в цену. По умолчанию `true` | | `customPrice` | boolean | нет | Защита цены от автопересчёта при изменении товара в каталоге. По умолчанию `false` | | `weight` | number | нет | Вес в граммах | | `measureCode` | number | нет | Код единицы измерения (`796` = шт, `163` = г, `006` = м) | | `xmlId` | string | нет | Внешний идентификатор позиции | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/basket-items" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "orderId": 33, "productId": 119, "name": "Домашние Тапочки Любимый Спорт", "quantity": 2, "price": 470, "currency": "RUB", "vatRate": 0.20, "vatIncluded": true }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/basket-items" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "orderId": 33, "productId": 119, "name": "Домашние Тапочки Любимый Спорт", "quantity": 2, "price": 470, "currency": "RUB", "vatRate": 0.20, "vatIncluded": true }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ orderId: 33, productId: 119, name: 'Домашние Тапочки Любимый Спорт', quantity: 2, price: 470, currency: 'RUB', vatRate: 0.20, vatIncluded: true, }), }) const { success, data } = await res.json() console.log('Basket item ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ orderId: 33, productId: 119, name: 'Домашние Тапочки Любимый Спорт', quantity: 2, price: 470, currency: 'RUB', vatRate: 0.20, vatIncluded: true, }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданной позиции корзины. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор созданной позиции | | `name` | string | Название товара (заполнено из карточки `productId`, если не передано) | | `productXmlId` / `catalogXmlId` | string | Внешние идентификаторы товара и каталога (заполняются автоматически) | | `dateInsert` | datetime | Дата создания | ## Пример ответа ```json { "success": true, "data": { "id": 201, "orderId": 33, "productId": 119, "name": "Домашние Тапочки Любимый Спорт", "price": 470, "basePrice": 470, "discountPrice": 0, "currency": "RUB", "quantity": 2, "vatRate": 0.20, "vatIncluded": true, "customPrice": false, "canBuy": true, "weight": 0, "measureCode": 796, "measureName": "шт", "productXmlId": "1000000475", "catalogXmlId": "FUTURE-1C-CATALOG", "xmlId": "bx_61a23456789ab", "dateInsert": "2026-05-13T11:55:42.000Z", "dateUpdate": "2026-05-13T11:55:42.000Z" } } ``` ## Пример ответа при ошибке 400 — не передан обязательный `orderId`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Required fields: orderId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `BITRIX_ERROR` | Не переданы обязательные поля — сообщение содержит их список | | 400 | `BITRIX_ERROR` | Несуществующий `orderId` или `productId` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поля товара заполняются из каталога.** Если передать `productId`, Битрикс24 берёт `name`, `productXmlId`, `catalogXmlId`, `measureCode` и `measureName` из карточки товара. Чтобы переопределить название — передавайте его явно в `name`. **Несколько позиций для одного товара.** Можно добавить одну и ту же `productId` в заказ несколькими позициями — Битрикс24 не схлопывает их. Чтобы увеличить количество существующей позиции, используйте [`PATCH /v1/basket-items/:id`](./update.md) с `quantity`. **Цена не пересчитывается автоматически.** Передавайте согласованные `price` / `basePrice` / `discountPrice` — Вайбкод и Битрикс24 не пересчитывают их между собой. Если нужна защита цены от обновлений каталога — передавайте `customPrice: true`. ## Смотрите также - [Список позиций](./list.md) — позиции существующего заказа - [Получить позицию](./get.md) — полные данные после создания - [Обновить позицию](./update.md) — изменить количество или цену - [Заказ](../orders/get.md) — родительская сущность - [Товары каталога](/docs/entities/catalog-products) — источник `productId` - [Batch](/docs/batch) — массовое создание позиций - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Basket Items: Delete ## Удалить позицию корзины `DELETE /v1/basket-items/:id` Удаляет позицию корзины по идентификатору. Восстановить удалённую позицию через API нельзя — создавайте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор позиции | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/basket-items/9" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/basket-items/9" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/9', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Позиция удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/9', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Позиция удалена') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — позиция не найдена: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "basket item is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Позиция с таким ID не найдена или уже удалена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Заказ остаётся без изменений.** Удаление позиции не затрагивает родительский заказ — только пропадает одна строка корзины. Сумма заказа (`orders.price`) при этом не пересчитывается автоматически. ## Смотрите также - [Список позиций](./list.md) — найти ID позиции перед удалением - [Получить позицию](./get.md) — проверить состояние перед удалением - [Обновить позицию](./update.md) — изменить `quantity` вместо удаления - [Обновить заказ](../orders/update.md) — пересчитать `price` заказа после удаления позиций - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Basket Items: Get ## Получить позицию корзины `GET /v1/basket-items/:id` Возвращает одну позицию корзины по идентификатору со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор позиции | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/basket-items/9" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/basket-items/9" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/9', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Позиция:', data.name, '×', data.quantity, '=', data.price * data.quantity, data.currency) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/9', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор позиции | | `orderId` | number | Идентификатор заказа | | `productId` | number | Идентификатор товара в каталоге | | `name` | string | Название товара | | `price` | number | Цена за единицу | | `basePrice` | number | Базовая цена до скидки | | `discountPrice` | number | Размер скидки за единицу | | `currency` | string | Валюта | | `quantity` | number | Количество | | `weight` | number | Вес в граммах | | `vatRate` | number | Ставка НДС в долях единицы | | `vatIncluded` | boolean | Включён ли НДС в цену | | `customPrice` | boolean | Защита цены от автопересчёта при изменении товара в каталоге | | `canBuy` | boolean | Доступен ли товар к покупке | | `measureCode` | number | Код единицы измерения | | `measureName` | string | Название единицы измерения | | `dimensions` | string | Габариты в формате сериализации PHP | | `xmlId` | string | Внешний идентификатор позиции | | `productXmlId` | string | Внешний идентификатор товара в каталоге | | `catalogXmlId` | string | Внешний идентификатор каталога | | `dateInsert` | datetime | Дата создания | | `dateUpdate` | datetime | Дата последнего изменения | | `dateRefresh` | datetime | Дата последнего пересчёта цены | ## Пример ответа ```json { "success": true, "data": { "id": 9, "orderId": 33, "productId": 119, "name": "Домашние Тапочки Любимый Спорт", "price": 470, "basePrice": 470, "discountPrice": 0, "currency": "RUB", "quantity": 1, "weight": 0, "vatRate": 0, "vatIncluded": true, "customPrice": false, "canBuy": true, "barcodeMulti": false, "measureCode": 796, "measureName": "шт", "dimensions": "a:3:{s:5:\"WIDTH\";N;s:6:\"HEIGHT\";N;s:6:\"LENGTH\";N;}", "xmlId": "bx_5fc9f8c57fe6c", "productXmlId": "1000000475", "catalogXmlId": "FUTURE-1C-CATALOG", "type": null, "sort": 200, "properties": [ { "id": 17, "basketId": 9, "code": "CATALOG.XML_ID", "name": "Catalog XML_ID", "value": "FUTURE-1C-CATALOG", "sort": 100, "xmlId": "bx_5fc9f8c57ff3e" }, { "id": 19, "basketId": 9, "code": "PRODUCT.XML_ID", "name": "Product XML_ID", "value": "1000000475", "sort": 100, "xmlId": "bx_5fc9f8c57ffb2" } ], "reservations": [], "dateInsert": "2020-12-04T07:52:21.000Z", "dateUpdate": "2022-11-02T05:10:13.000Z" } } ``` ## Пример ответа при ошибке 422 — позиция не найдена: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "basket item is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Позиция с таким ID не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить позицию](./update.md) — изменение полей - [Удалить позицию](./delete.md) — удаление по ID - [Список позиций](./list.md) — все позиции заказа - [Заказ](../orders/get.md) — родительская сущность по `orderId` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Basket Items: List ## Список позиций корзины `GET /v1/basket-items` Возвращает список позиций корзины с поддержкой фильтрации и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `offset` | number | `0` | Пропустить N записей. При `offset ≥ 2500` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,orderId,name,quantity,price` | | `order` | object | — | Сортировка: `?order[id]=desc` | | `filter` | object | — | Фильтрация по ключевым полям позиции.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[orderId]=33` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/basket-items?limit=10&filter[orderId]=33" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/basket-items?limit=10&filter[orderId]=33" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items?limit=10&filter[orderId]=33', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Позиций в заказе: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items?limit=10&filter[orderId]=33', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив позиций корзины | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 9, "orderId": 33, "productId": 119, "name": "Домашние Тапочки Любимый Спорт", "price": 470, "basePrice": 470, "discountPrice": 0, "currency": "RUB", "quantity": 1, "weight": 0, "vatRate": 0, "vatIncluded": true, "measureCode": 796, "measureName": "шт", "xmlId": "bx_5fc9f8c57fe6c", "productXmlId": "1000000475", "catalogXmlId": "FUTURE-1C-CATALOG", "canBuy": true, "dateInsert": "2020-12-04T07:52:21.000Z", "dateUpdate": "2022-11-02T05:10:13.000Z" } ], "meta": { "total": 1, "hasMore": false } } ``` Показаны основные поля. Полный ответ позиции — см. [`GET /v1/basket-items/:id`](./get.md). ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'sale' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 и возвращает все записи в одном ответе. **Свободные позиции без заказа.** Часть позиций в `data[]` может иметь `orderId: null` — это позиции в незавершённых корзинах покупателей, ещё не оформленных в заказ. Чтобы исключить их, добавьте `filter[orderId][!]=null` или фильтр по конкретному `orderId`. ## Смотрите также - [Поиск позиций](./search.md) — POST-запрос для сложных фильтров - [Получить позицию](./get.md) — одна позиция по ID - [Добавить позицию](./create.md) — добавление товара в заказ - [Заказ](../orders/get.md) — родительская сущность (`filter[orderId]=:id`) - [Товары каталога](/docs/entities/catalog-products) — источник `productId` - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Basket Items: Search ## Поиск позиций корзины `POST /v1/basket-items/search` Поиск позиций корзины с фильтрацией и авто-пагинацией. Аналогичен [`GET /v1/basket-items`](./list.md), но через POST — удобнее для сложных запросов с большим количеством условий. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям позиции.
[Синтаксис фильтрации](/docs/filtering) | | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string[] | — | Выборка полей: `["id", "orderId", "name", "quantity", "price"]` | | `order` | object | — | Сортировка: `{ "id": "desc" }` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/basket-items/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "orderId": 33 }, "limit": 10, "select": ["id", "orderId", "name", "quantity", "price", "currency"] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/basket-items/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "orderId": 33 }, "limit": 10, "select": ["id", "orderId", "name", "quantity", "price", "currency"] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { orderId: 33 }, limit: 10, select: ['id', 'orderId', 'name', 'quantity', 'price', 'currency'], }), }) const { success, data, meta } = await res.json() console.log('Найдено:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { orderId: 33 }, limit: 10, select: ['id', 'orderId', 'name', 'quantity', 'price', 'currency'], }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив позиций корзины | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 9, "orderId": 33, "name": "Домашние Тапочки Любимый Спорт", "quantity": 1, "price": 470, "currency": "RUB" } ], "meta": { "total": 1, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown field 'foo'. Available: id, orderId, productId, name, price, ..." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`select` ограничивает поля в ответе.** Если передан `select`, в каждом элементе `data[]` будут только перечисленные поля. Без `select` возвращаются все поля позиции. **Поиск товара по всем заказам.** Фильтр `{"productId": 119}` без `orderId` найдёт все позиции с этим товаром по всему порталу — это даёт срез продаж конкретного товара. ## Смотрите также - [Список позиций](./list.md) — GET-запрос с query-параметрами (для простых фильтров) - [Получить позицию](./get.md) — данные одной позиции по ID - [Заказ](../orders/get.md) — родительская сущность - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Basket Items: Update ## Обновить позицию корзины `PATCH /v1/basket-items/:id` Обновляет поля существующей позиции корзины. Передавайте только изменяемые поля плоско в корне JSON — без обёртки `fields`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор позиции | ## Поля для обновления (body) | Параметр | Тип | Описание | |----------|-----|---------| | `quantity` | number | Количество | | `price` | number | Цена за единицу | | `basePrice` | number | Базовая цена до скидки | | `discountPrice` | number | Размер скидки за единицу | | `currency` | string | Валюта | | `name` | string | Переопределение названия товара | | `vatRate` | number | Ставка НДС в долях единицы | | `vatIncluded` | boolean | Включён ли НДС в цену | | `customPrice` | boolean | Защита цены от автопересчёта | | `weight` | number | Вес в граммах | | `measureCode` | number | Код единицы измерения | | `xmlId` | string | Внешний идентификатор | Редактируются все поля позиции, кроме служебных (`id`, `orderId`, `productId`, `productXmlId`, `catalogXmlId`, `dateInsert`, `dateUpdate`, `dateRefresh`). Полный набор доступных полей виден в ответе [`GET /v1/basket-items/:id`](./get.md). ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/basket-items/9" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "quantity": 3, "discountPrice": 50 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/basket-items/9" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "quantity": 3, "discountPrice": 50 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/9', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ quantity: 3, discountPrice: 50, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/basket-items/9', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ quantity: 3, discountPrice: 50, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект позиции со всеми полями | ## Пример ответа ```json { "success": true, "data": { "id": 9, "orderId": 33, "productId": 119, "name": "Домашние Тапочки Любимый Спорт", "price": 470, "basePrice": 470, "discountPrice": 50, "currency": "RUB", "quantity": 3, "vatRate": 0, "vatIncluded": true, "customPrice": false, "canBuy": true, "weight": 0, "measureCode": 796, "measureName": "шт", "dateUpdate": "2026-05-13T11:58:14.000Z" } } ``` ## Пример ответа при ошибке 422 — позиция не найдена: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "basket item is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Позиция с таким ID не найдена | | 400 | `BITRIX_ERROR` | Некорректное значение поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поля `id`, `orderId`, `productId`, `productXmlId`, `catalogXmlId`, `dateInsert` доступны только для чтения.** Битрикс24 проставляет их при создании; попытка изменить — игнорируется. Чтобы перенести позицию в другой заказ, удалите её через [`DELETE /v1/basket-items/:id`](./delete.md) и создайте новую через [`POST /v1/basket-items`](./create.md). **Защита цены через `customPrice`.** При `customPrice: true` цена позиции не будет пересчитана автоматически при изменении цены товара в каталоге. ## Смотрите также - [Получить позицию](./get.md) — текущие значения перед обновлением - [Список позиций](./list.md) — найти позицию по фильтру - [Удалить позицию](./delete.md) — необратимое удаление - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Bookings: Create ## Создать бронирование `POST /v1/bookings` Создаёт новое бронирование на портале. Поля передаются плоско в корне JSON. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `resourceIds` | number[] | да | Идентификаторы ресурсов, которые резервирует бронирование. Массив не может быть пустым. Получить список ресурсов через API Вайбкод нельзя — укажите известные идентификаторы | | `datePeriod` | object | да | Период бронирования. Структура: `from` и `to`, у каждого — `timestamp` (Unix-секунды) и `timezone` (часовой пояс в формате IANA, например `Europe/Moscow`) | | `name` | string | нет | Название бронирования. Может быть `null` | | `description` | string | нет | Описание бронирования. Может быть `null` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/bookings" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "resourceIds": [1], "datePeriod": { "from": { "timestamp": 1780132384, "timezone": "Europe/Moscow" }, "to": { "timestamp": 1780135984, "timezone": "Europe/Moscow" } }, "name": "Переговорная на демонстрацию", "description": "Бронь переговорной комнаты" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/bookings" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "resourceIds": [1], "datePeriod": { "from": { "timestamp": 1780132384, "timezone": "Europe/Moscow" }, "to": { "timestamp": 1780135984, "timezone": "Europe/Moscow" } }, "name": "Переговорная на демонстрацию", "description": "Бронь переговорной комнаты" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ resourceIds: [1], datePeriod: { from: { timestamp: 1780132384, timezone: 'Europe/Moscow' }, to: { timestamp: 1780135984, timezone: 'Europe/Moscow' }, }, name: 'Переговорная на демонстрацию', description: 'Бронь переговорной комнаты', }), }) const { success, data } = await res.json() console.log('ID бронирования:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ resourceIds: [1], datePeriod: { from: { timestamp: 1780132384, timezone: 'Europe/Moscow' }, to: { timestamp: 1780135984, timezone: 'Europe/Moscow' }, }, name: 'Переговорная на демонстрацию', description: 'Бронь переговорной комнаты', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданного бронирования. | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор созданного бронирования | | `data.name` | string \| null | Название бронирования | | `data.description` | string \| null | Описание бронирования | | `data.resourceIds` | number[] | Идентификаторы зарезервированных ресурсов | | `data.datePeriod` | object | Период бронирования: `from` и `to`, у каждого `timestamp` и `timezone` | ## Пример ответа ```json { "success": true, "data": { "id": 27, "name": "Переговорная на демонстрацию", "description": "Бронь переговорной комнаты", "resourceIds": [1], "datePeriod": { "from": { "timestamp": 1780132384, "timezone": "Europe/Moscow" }, "to": { "timestamp": 1780135984, "timezone": "Europe/Moscow" } } } } ``` ## Пример ответа при ошибке 422 — не переданы обязательные поля: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Required fields: resourceIds, datePeriod" } } ``` ## Ошибки | HTTP | Код | Описание | |------|--------------|---------| | 422 | `BITRIX_ERROR` | Не переданы обязательные поля `resourceIds` и/или `datePeriod`. Сообщение: `Required fields: resourceIds, datePeriod` | | 422 | `BITRIX_ERROR` | Передан пустой массив `resourceIds`. Сообщение: `Empty resource collection` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `booking` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Бронирования](/docs/entities/bookings) - [Обновить бронирование](/docs/entities/bookings/update) - [Получить бронирование](/docs/entities/bookings/get) - [Удалить бронирование](/docs/entities/bookings/delete) - [Batch](/docs/batch) --- # Bookings: Delete ## Удалить бронирование `DELETE /v1/bookings/:id` Удаляет бронирование по идентификатору. Восстановить удалённое бронирование через API нельзя — создавайте новое при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор бронирования | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/bookings/27" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/bookings/27" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/27', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Бронирование удалено') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/27', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Бронирование удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом. Признак успеха — код ответа, не содержимое. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — бронирование уже удалено или не существует: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "booking not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Бронирование с указанным `id` не найдено или уже удалено. Сообщение: `booking not found` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `booking` | | 401 | `MISSING_API_KEY` | Запрос отправлен без заголовка `X-Api-Key` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список бронирований](/docs/entities/bookings/list) - [Создать бронирование](/docs/entities/bookings/create) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Bookings: Get ## Получить бронирование `GET /v1/bookings/:id` Возвращает одно бронирование по идентификатору. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор бронирования | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/bookings/27" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/bookings/27" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/27', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Бронирование:', data.name, data.resourceIds) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/27', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект содержит 5 полей — все приведены в таблице ниже. | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор бронирования | | `data.name` | string \| null | Название бронирования. Может быть `null` | | `data.description` | string \| null | Описание бронирования. Может быть `null` | | `data.resourceIds` | number[] | Идентификаторы резервируемых ресурсов | | `data.datePeriod` | object | Период бронирования: `from` и `to`, у каждого `timestamp` (Unix-секунды) и `timezone` (IANA) | ## Пример ответа ```json { "success": true, "data": { "id": 27, "name": "Переговорная на демонстрацию", "description": "Бронь переговорной комнаты", "resourceIds": [1], "datePeriod": { "from": { "timestamp": 1780132384, "timezone": "Europe/Moscow" }, "to": { "timestamp": 1780135984, "timezone": "Europe/Moscow" } } } } ``` ## Пример ответа при ошибке 422 — бронирование не найдено: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Booking not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Бронирование с указанным `id` не найдено | | 422 | `BITRIX_ERROR` | `id` содержит нечисловое значение | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `booking` | | 401 | `MISSING_API_KEY` | Запрос отправлен без заголовка `X-Api-Key` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список бронирований](/docs/entities/bookings/list) - [Обновить бронирование](/docs/entities/bookings/update) - [Удалить бронирование](/docs/entities/bookings/delete) - [Лимиты и оптимизация](/docs/optimization) --- # Bookings: List ## Список бронирований `GET /v1/bookings` Возвращает бронирования за указанный диапазон дат. Начало и конец интервала обязательны — без них запрос вернётся с ошибкой. Записи вне переданного интервала в ответ не попадают. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `dateFrom` (query) | string \| number | да | — | Начало интервала. ISO 8601 (`"2026-05-01T00:00:00Z"`) или Unix-секунды (`1714521600`) | | `dateTo` (query) | string \| number | да | — | Конец интервала. ISO 8601 или Unix-секунды | | `limit` (query) | number | нет | `50` | Количество записей (от 1 до 5000). Отрицательное значение или ноль → `400 INVALID_PARAMS` | | `offset` (query) | number | нет | `0` | Смещение. Используйте с осторожностью — см. «Известные особенности» | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/bookings?dateFrom=2024-01-01T00:00:00Z&dateTo=2026-12-31T23:59:59Z&limit=10" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/bookings?dateFrom=2024-01-01T00:00:00Z&dateTo=2026-12-31T23:59:59Z&limit=10" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const params = new URLSearchParams({ dateFrom: '2024-01-01T00:00:00Z', dateTo: '2026-12-31T23:59:59Z', limit: '10', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/bookings?${params}`, { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Получено ${data.length} бронирований, hasMore: ${meta.hasMore}`) ``` ### JavaScript — OAuth-приложение ```javascript const params = new URLSearchParams({ dateFrom: '2024-01-01T00:00:00Z', dateTo: '2026-12-31T23:59:59Z', limit: '10', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/bookings?${params}`, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив бронирований (поля каждой записи — см. [Бронирования](/docs/entities/bookings)) | | `meta.total` | number | Всегда `0` — общее количество не вычисляется. Для определения наличия дополнительных записей используйте `meta.hasMore` | | `meta.hasMore` | boolean | `true`, если количество записей, подходящих под фильтр, превышает `limit` | ## Пример ответа ```json { "success": true, "data": [ { "datePeriod": { "from": { "timestamp": 1723446900, "timezone": "Europe/Moscow" }, "to": { "timestamp": 1723447800, "timezone": "Europe/Moscow" } }, "description": null, "id": 3, "name": null, "resourceIds": [1, 3] }, { "datePeriod": { "from": { "timestamp": 1741687200, "timezone": "Europe/Kaliningrad" }, "to": { "timestamp": 1741690800, "timezone": "Europe/Kaliningrad" } }, "description": null, "id": 1, "name": "Запись", "resourceIds": [1] }, { "datePeriod": { "from": { "timestamp": 1752570000, "timezone": "Europe/Kaliningrad" }, "to": { "timestamp": 1752571800, "timezone": "Europe/Kaliningrad" } }, "description": null, "id": 5, "name": null, "resourceIds": [1] } ], "meta": { "total": 0, "hasMore": true } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные параметры: ```json { "success": false, "error": { "code": "MISSING_REQUIRED_PARAMS", "message": "GET /v1/bookings requires dateFrom and dateTo query parameters (ISO 8601 datetime or Unix seconds). Example: ?dateFrom=2026-05-01T00:00:00Z&dateTo=2026-05-31T23:59:59Z." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_REQUIRED_PARAMS` | Не переданы `dateFrom` или `dateTo` | | 400 | `INVALID_DATE` | Значение `dateFrom` или `dateTo` не является ISO 8601 или Unix-секундами | | 400 | `INVALID_PARAMS` | `limit` меньше 1 или не является числом | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `booking` | | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`offset` работает ненадёжно на малых значениях.** Значения `offset` меньше размера страницы не гарантируют пропуск записей. Для выборки бронирований за стандартный рабочий период (день, неделя, месяц) все записи помещаются в одну страницу при достаточном `limit` — предпочтительнее одного запроса с большим `limit` вместо серии запросов с малым `offset`. ## Смотрите также - [Поиск бронирований](/docs/entities/bookings/search) - [Получить бронирование](/docs/entities/bookings/get) - [Создать бронирование](/docs/entities/bookings/create) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Bookings: Search ## Поиск бронирований `POST /v1/bookings/search` Возвращает бронирования за указанный диапазон дат. Начало и конец интервала обязательны. Подходит, когда параметры запроса удобнее передавать в теле, а не в строке запроса. ## Поля запроса (body) Принимает две равнозначные формы. Используйте любую из них. **Форма 1 — параметры на верхнем уровне:** | Поле | Тип | Обяз. | По умолч. | Описание | |------|-----|:-----:|-----------|---------| | `dateFrom` | string \| number | да | — | Начало интервала. ISO 8601 (`"2026-05-01T00:00:00Z"`) или Unix-секунды (`1714521600`) | | `dateTo` | string \| number | да | — | Конец интервала. ISO 8601 или Unix-секунды | | `limit` | number | нет | `50` | Количество записей (от 1 до 5000) | | `offset` | number | нет | `0` | Смещение | **Форма 2 — параметры во вложенном фильтре:** | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `filter.within.dateFrom` | string \| number | да | Начало интервала | | `filter.within.dateTo` | string \| number | да | Конец интервала | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/bookings/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "dateFrom": "2024-01-01T00:00:00Z", "dateTo": "2026-12-31T23:59:59Z", "limit": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/bookings/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "dateFrom": "2024-01-01T00:00:00Z", "dateTo": "2026-12-31T23:59:59Z", "limit": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ dateFrom: '2024-01-01T00:00:00Z', dateTo: '2026-12-31T23:59:59Z', limit: 10, }), }) const { success, data, meta } = await res.json() console.log(`Получено ${data.length} бронирований, hasMore: ${meta.hasMore}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ dateFrom: '2024-01-01T00:00:00Z', dateTo: '2026-12-31T23:59:59Z', limit: 10, }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив бронирований (поля каждой записи — см. [Бронирования](/docs/entities/bookings)) | | `meta.total` | number | Всегда `0` — общее количество не вычисляется. Для определения наличия дополнительных записей используйте `meta.hasMore` | | `meta.hasMore` | boolean | `true`, если количество записей, подходящих под условие, превышает `limit` | ## Пример ответа ```json { "success": true, "data": [ { "datePeriod": { "from": { "timestamp": 1723446900, "timezone": "Europe/Moscow" }, "to": { "timestamp": 1723447800, "timezone": "Europe/Moscow" } }, "description": null, "id": 3, "name": null, "resourceIds": [1, 3] }, { "datePeriod": { "from": { "timestamp": 1741687200, "timezone": "Europe/Kaliningrad" }, "to": { "timestamp": 1741690800, "timezone": "Europe/Kaliningrad" } }, "description": null, "id": 1, "name": "Запись", "resourceIds": [1] }, { "datePeriod": { "from": { "timestamp": 1752570000, "timezone": "Europe/Kaliningrad" }, "to": { "timestamp": 1752571800, "timezone": "Europe/Kaliningrad" } }, "description": null, "id": 5, "name": null, "resourceIds": [1] } ], "meta": { "total": 0, "hasMore": true } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные параметры: ```json { "success": false, "error": { "code": "MISSING_REQUIRED_PARAMS", "message": "POST /v1/bookings/search requires { dateFrom, dateTo } at the top level OR { filter: { within: { dateFrom, dateTo } } }. Values are ISO 8601 or Unix seconds." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_REQUIRED_PARAMS` | Не переданы `dateFrom` или `dateTo` ни в одной из допустимых форм | | 400 | `INVALID_DATE` | Значение `dateFrom` или `dateTo` не является ISO 8601 или Unix-секундами | | 400 | `INVALID_PARAMS` | `limit` меньше 1 или не является числом | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `booking` | | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список бронирований](/docs/entities/bookings/list) - [Получить бронирование](/docs/entities/bookings/get) - [Создать бронирование](/docs/entities/bookings/create) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Bookings: Update ## Обновить бронирование `PATCH /v1/bookings/:id` Обновляет поля существующего бронирования. Передавайте только изменяемые поля плоско в корне JSON. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор бронирования | ## Поля запроса (body) | Поле | Тип | Описание | |------|-----|---------| | `resourceIds` | number[] | Идентификаторы ресурсов, которые резервирует бронирование. Массив не может быть пустым. Получить список ресурсов через API Вайбкод нельзя — укажите известные идентификаторы | | `datePeriod` | object | Период бронирования. Структура: `from` и `to`, у каждого — `timestamp` (Unix-секунды) и `timezone` (часовой пояс в формате IANA, например `Europe/Moscow`) | | `name` | string | Название бронирования. Может быть `null` | | `description` | string | Описание бронирования. Может быть `null` | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/bookings/27" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Переговорная (обновлено)", "description": "Изменённое описание" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/bookings/27" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Переговорная (обновлено)", "description": "Изменённое описание" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/27', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Переговорная (обновлено)', description: 'Изменённое описание', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/bookings/27', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Переговорная (обновлено)', description: 'Изменённое описание', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект обновлённого бронирования. | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор бронирования | | `data.name` | string \| null | Название бронирования | | `data.description` | string \| null | Описание бронирования | | `data.resourceIds` | number[] | Идентификаторы зарезервированных ресурсов | | `data.datePeriod` | object | Период бронирования: `from` и `to`, у каждого `timestamp` и `timezone` | ## Пример ответа ```json { "success": true, "data": { "id": 27, "name": "Переговорная (обновлено)", "description": "Изменённое описание", "resourceIds": [1], "datePeriod": { "from": { "timestamp": 1780132384, "timezone": "Europe/Moscow" }, "to": { "timestamp": 1780135984, "timezone": "Europe/Moscow" } } } } ``` ## Пример ответа при ошибке 422 — бронирование не найдено: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Booking not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|--------------|---------| | 422 | `BITRIX_ERROR` | Бронирование с указанным `id` не существует. Сообщение: `Booking not found` | | 422 | `BITRIX_ERROR` | Передан пустой массив `resourceIds`. Сообщение: `Empty resource collection` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `booking` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Бронирования](/docs/entities/bookings) - [Создать бронирование](/docs/entities/bookings/create) - [Получить бронирование](/docs/entities/bookings/get) - [Удалить бронирование](/docs/entities/bookings/delete) - [Batch](/docs/batch) --- # Calendar Events: Create ## Создать событие `POST /v1/calendar-events` Создаёт новое событие в указанном календаре. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `type` | string | да | Тип календаря: `user`, `group`, `company_calendar` | | `ownerId` | number | да | ID владельца календаря: сотрудник (`GET /v1/users`) или рабочая группа | | `name` | string | да | Название события | | `from` | datetime | да | Начало события в ISO 8601. Принимается строка с явным смещением (`2026-06-10T10:00:00+03:00`), в UTC (`2026-06-10T07:00:00Z`) или без зоны (`2026-06-10T10:00:00`) | | `to` | datetime | да | Окончание события в ISO 8601. Принимается строка с явным смещением (`2026-06-10T11:00:00+03:00`), в UTC (`2026-06-10T08:00:00Z`) или без зоны (`2026-06-10T11:00:00`) | | `timezoneFrom` | string | нет | Часовой пояс начала события (IANA-имя: `Europe/Moscow`, `Asia/Almaty`, `UTC`). Без него используется часовой пояс сотрудника-владельца API-ключа | | `timezoneTo` | string | нет | Часовой пояс окончания события (IANA-имя) | | `description` | string | нет | Описание | | `sectionId` | number | нет | ID секции календаря. Если поле не передано — при каждом вызове создаётся новая секция. Чтобы события писались в одну секцию, передавайте `sectionId` существующей секции. ID существующей секции возвращает [`GET /v1/calendar-events`](./list.md) в поле `sectionId` любого ранее созданного события | | `skipTime` | boolean | нет | Событие на весь день. При `true` время в `from`/`to` игнорируется, длительность фиксируется в 24 часа | | `importance` | string | нет | `high`, `normal`, `low` | | `accessibility` | string | нет | Занятость: `busy`, `quest` (под вопросом), `free`, `absent` | | `location` | string | нет | Место проведения | | `color` | string | нет | Цвет события (HEX, `#RRGGBB`) | | `attendees` | number[] | нет | Массив ID приглашённых сотрудников. Список: `GET /v1/users`. **Только для записи** — в ответе участники возвращаются в полях `attendeeList`, `attendeesCodes`, `attendeesEntityList`. См. [Поля события](./fields.md) | | `remind` | array | нет | Настройки напоминаний. Каждый элемент: `{type: 'min' \| 'hour' \| 'day', count: <число>}` | | `rrule` | object | нет | Расписание повторения регулярного события. Структура полей и пример — секция [Регулярное событие](#регулярное-событие) ниже | | `isPrivate` | boolean | нет | Приватное событие — детали скрыты от других пользователей | | `isMeeting` | boolean | нет | Событие-встреча с приглашениями | Полный список полей: [`GET /v1/calendar-events/fields`](./fields.md). ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/calendar-events" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1, "name": "Созвон с командой", "from": "2026-06-10T10:00:00", "to": "2026-06-10T11:00:00", "timezoneFrom": "Europe/Moscow", "timezoneTo": "Europe/Moscow", "description": "Еженедельная синхронизация", "accessibility": "busy", "sectionId": 3 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/calendar-events" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1, "name": "Созвон с командой", "from": "2026-06-10T10:00:00", "to": "2026-06-10T11:00:00", "timezoneFrom": "Europe/Moscow", "timezoneTo": "Europe/Moscow", "description": "Еженедельная синхронизация", "accessibility": "busy", "sectionId": 3 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'user', ownerId: 1, name: 'Созвон с командой', from: '2026-06-10T10:00:00', to: '2026-06-10T11:00:00', timezoneFrom: 'Europe/Moscow', timezoneTo: 'Europe/Moscow', description: 'Еженедельная синхронизация', accessibility: 'busy', sectionId: 3, }), }) const { success, data } = await res.json() console.log('ID события:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'user', ownerId: 1, name: 'Созвон с командой', from: '2026-06-10T10:00:00', to: '2026-06-10T11:00:00', timezoneFrom: 'Europe/Moscow', timezoneTo: 'Europe/Moscow', description: 'Еженедельная синхронизация', accessibility: 'busy', sectionId: 3, }), }) const { success, data } = await res.json() ``` ## Регулярное событие Чтобы создать повторяющееся событие, передайте поле `rrule` как объект. Запрос: ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/calendar-events" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1, "name": "Созвон команды", "from": "2026-07-13T10:00:00", "to": "2026-07-13T11:00:00", "timezoneFrom": "Europe/Moscow", "timezoneTo": "Europe/Moscow", "rrule": { "FREQ": "WEEKLY", "INTERVAL": 1, "BYDAY": ["MO", "WE"], "UNTIL": "2026-09-30" } }' ``` Создаётся одно событие с одним `id` — список (`GET /v1/calendar-events`) вернёт по элементу на каждое вхождение серии, все они будут иметь общий `parentId`. Удаление события (`DELETE /v1/calendar-events/:id`) убирает всю серию. Поля `rrule`: | Поле | Тип | Описание | |------|-----|---------| | `FREQ` | string | Периодичность: `DAILY`, `WEEKLY`, `MONTHLY`, `YEARLY` | | `INTERVAL` | number | Интервал. `1` — каждый цикл, `2` — через один и т. д. | | `BYDAY` | string[] | Дни недели для `WEEKLY`: `SU`, `MO`, `TU`, `WE`, `TH`, `FR`, `SA` | | `UNTIL` | date | Дата окончания серии в формате `YYYY-MM-DD`. Альтернатива — `COUNT` | | `COUNT` | number | Количество повторений. Альтернатива — `UNTIL` | ## Поля ответа Объект созданного события со всеми полями — см. [Поля события](./fields.md). URL карточки события в Битрикс24 зависит от типа календаря: | `type` | URL | |---|---| | `user` | `https://.bitrix24.ru/company/personal/user//calendar/?EVENT_ID=&EVENT_DATE=` | | `group` | `https://.bitrix24.ru/workgroups/group//calendar/?EVENT_ID=&EVENT_DATE=` | | `company_calendar` | `https://.bitrix24.ru/calendar/?EVENT_ID=&EVENT_DATE=` | `` — дата начала события (поле `from`) в формате «день.месяц.год» через точку. `` — домен вашего портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 7773, "parentId": 7773, "deleted": false, "type": "user", "ownerId": 1, "name": "Созвон с командой", "from": "2026-06-10T10:00:00+03:00", "to": "2026-06-10T11:00:00+03:00", "skipTime": false, "durationSeconds": 3600, "createdBy": 1, "dateCreate": "06/05/2026 09:12:00 am", "updatedAt": "06/05/2026 09:12:00 am", "description": "Еженедельная синхронизация", "accessibility": "busy", "importance": "normal", "isMeeting": false, "meetingStatus": "H", "meetingHost": 1, "sectionId": 3, "attendeeList": [ { "id": 1, "entryId": "7773", "status": "H" } ] } } ``` ## Пример ответа при ошибке 422 — не передано обязательное поле: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Не задан обязательный параметр \"name\" для метода \"calendar.event.add\"" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Не передано обязательное поле (`type`, `ownerId`, `name`, `from`, `to`) | | 400 | `READONLY_FIELD` | В теле запроса передано read-only поле (`id`, `createdBy`, `dateCreate`, `updatedAt`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Накопление секций при создании без `sectionId`.** Если поле `sectionId` не передано, при каждом вызове создаётся новая секция календаря. На серии вызовов без `sectionId` в календаре сотрудника копятся пустые секции, видимые в веб-интерфейсе Битрикс24. Чтобы все события писались в одну секцию, передавайте `sectionId` существующей секции — её ID можно взять из ответа [`GET /v1/calendar-events`](./list.md). ## Смотрите также - [Поля события](./fields.md) - [Обновить событие](./update.md) - [Удалить событие](./delete.md) - [Список событий](./list.md) --- # Calendar Events: Delete ## Удалить событие `DELETE /v1/calendar-events/:id` Удаляет событие календаря по идентификатору. Восстановить удалённое событие через API нельзя — создавайте новое при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID события | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/calendar-events/7773" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/calendar-events/7773" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/7773', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Событие удалено') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/7773', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом. Признак успеха — код ответа, не содержимое. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — событие уже удалено или не существовало: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "При удалении события произошла ошибка" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Событие с указанным `id` не существует или уже удалено | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Регулярные события.** Удаление события с правилом повторения (`rrule`) удаляет всю серию — все вхождения с одним `parentId`. Точечно убрать одно вхождение из серии через API нельзя. ## Смотрите также - [Список событий](./list.md) - [Batch](/docs/batch) — массовое удаление --- # Calendar Events: Fields ## Поля события `GET /v1/calendar-events/fields` Возвращает схему полей события: тип, признак readonly, доступные batch-операции. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-events/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-events/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | ID события | | `parentId` | number | да | ID родительского события (для повторяющихся событий совпадает с `id` исходного) | | `active` | boolean | да | Активность события | | `deleted` | boolean | да | Признак удаления | | `name` | string | | Название | | `description` | string | | Описание | | `type` | string | | Тип календаря: `user`, `group`, `company_calendar` | | `ownerId` | number | | ID владельца календаря. Сотрудник: `GET /v1/users` | | `from` | datetime | | Начало (ISO 8601) | | `to` | datetime | | Окончание (ISO 8601) | | `skipTime` | boolean | | Событие на весь день. При `true` длительность фиксируется в 24 часа | | `durationSeconds` | number | да | Продолжительность события в секундах | | `importance` | string | | Важность: `high`, `normal`, `low` | | `accessibility` | string | | Занятость: `busy`, `quest`, `free`, `absent` | | `location` | string | | Место проведения | | `color` | string | | Цвет события (HEX) | | `sectionId` | number | | ID секции календаря | | `isPrivate` | boolean | | Приватное событие | | `isMeeting` | boolean | | Событие-встреча с приглашениями | | `attendees` | number[] | | Массив ID приглашённых сотрудников для записи. **Только для записи** — в ответах событий это поле не возвращается, участники доступны в `attendeeList`, `attendeesCodes`, `attendeesEntityList` | | `attendeesCodes` | string[] | да | Внутренние коды участников Битрикс24 (формат `U`) | | `attendeeList` | array | да | Расширенный список участников: `{ id, entryId, status }`, где `status` — `Y` (принято), `H` (хост), `Q` (под вопросом), `N` (отклонено) | | `attendeesEntityList` | array | да | Короткий список участников с типом сущности: `{ entityId, id }`. Возвращается в `GET /v1/calendar-events/:id`, `POST` и `PATCH`, но не в `GET /v1/calendar-events` | | `remind` | array | | Настройки напоминаний | | `rrule` | object | | Расписание повторения регулярного события: периодичность (`FREQ`), интервал (`INTERVAL`), дни недели (`BYDAY`), граница серии (`UNTIL` или `COUNT`) | | `createdBy` | number | да | ID создателя события. Поиск: `GET /v1/users` | | `dateCreate` | string | да | Дата создания (формат Битрикс24 `"MM/DD/YYYY hh:mm:ss am/pm"`) | | `updatedAt` | string | да | Дата последнего изменения (формат Битрикс24) | | `meetingStatus` | string | да | Статус участия владельца календаря: `Y` (принято), `H` (хост), `Q` (под вопросом), `N` (отклонено) | | `meetingHost` | number | да | ID организатора встречи. Поиск: `GET /v1/users` | | `eventType` | string | да | Технический тип события (для системных событий) | | `syncStatus` | string | да | Статус синхронизации с внешними календарями | | `recurrenceId` | number | да | ID серии повторяющихся событий | | `collabId` | number | да | ID коллабораций (при участии внешних пользователей) | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false }, "type": { "type": "string", "readonly": false }, "ownerId": { "type": "number", "readonly": false }, "from": { "type": "datetime", "readonly": false }, "to": { "type": "datetime", "readonly": false }, "skipTime": { "type": "boolean", "readonly": false }, "durationSeconds": { "type": "number", "readonly": true }, "importance": { "type": "string", "readonly": false }, "accessibility": { "type": "string", "readonly": false }, "sectionId": { "type": "number", "readonly": false }, "attendees": { "type": "array", "readonly": false }, "dateCreate": { "type": "string", "readonly": true }, "updatedAt": { "type": "string", "readonly": true } }, "batch": ["create", "update", "delete"] } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'calendar' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать событие](./create.md) - [Обновить событие](./update.md) - [Список событий](./list.md) --- # Calendar Events: Get ## Получить событие `GET /v1/calendar-events/:id` Возвращает одно событие календаря по идентификатору. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID события | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-events/7773" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-events/7773" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/7773', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log(data.name, '—', data.from) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/7773', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект события со всеми полями — см. [Поля события](./fields.md). ## Пример ответа ```json { "success": true, "data": { "id": 7773, "parentId": 7773, "deleted": false, "type": "user", "ownerId": 1, "name": "Созвон с командой", "from": "2026-06-10T10:00:00+03:00", "to": "2026-06-10T11:00:00+03:00", "skipTime": false, "durationSeconds": 3600, "createdBy": 1, "dateCreate": "06/05/2026 09:12:00 am", "updatedAt": "06/05/2026 09:12:00 am", "description": "Еженедельная синхронизация", "accessibility": "busy", "importance": "normal", "isMeeting": false, "meetingStatus": "H", "meetingHost": 1, "sectionId": 3, "attendeeList": [ { "id": 1, "entryId": "7773", "status": "H" } ], "attendeesEntityList": [ { "entityId": "user", "id": 1 } ] } } ``` ## Пример ответа при ошибке 404 — событие не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "calendarEvent 99999999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Событие с указанным `id` не существует | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Поля события](./fields.md) - [Обновить событие](./update.md) - [Список событий](./list.md) --- # Calendar Events: List ## Список событий `GET /v1/calendar-events` Возвращает события календаря за фиксированный период вокруг текущей даты: с месяца назад по три месяца вперёд. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `type` (query) | string | да | — | Тип календаря: `user`, `group`, `company_calendar` | | `ownerId` (query) | number | да | — | ID владельца календаря: сотрудник (`GET /v1/users`) или рабочая группа | | `limit` (query) | number | нет | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `offset` (query) | number | нет | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-events?type=user&ownerId=1&limit=10" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-events?type=user&ownerId=1&limit=10" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const params = new URLSearchParams({ type: 'user', ownerId: '1', limit: '10' }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/calendar-events?${params}`, { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} событий`) ``` ### JavaScript — OAuth-приложение ```javascript const params = new URLSearchParams({ type: 'user', ownerId: '1', limit: '10' }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/calendar-events?${params}`, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив событий (все поля — см. [Поля события](./fields.md)) | | `meta.total` | number | Общее количество событий в выборке | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | URL карточки любого события из массива `data` зависит от типа календаря: | `type` | URL | |---|---| | `user` | `https://.bitrix24.ru/company/personal/user//calendar/?EVENT_ID=&EVENT_DATE=` | | `group` | `https://.bitrix24.ru/workgroups/group//calendar/?EVENT_ID=&EVENT_DATE=` | | `company_calendar` | `https://.bitrix24.ru/calendar/?EVENT_ID=&EVENT_DATE=` | `` — дата начала события (поле `from`) в формате «день.месяц.год» через точку. `` — домен вашего портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 7773, "parentId": 7773, "active": true, "deleted": false, "type": "user", "ownerId": 1, "name": "Созвон с командой", "from": "2026-06-10T10:00:00+03:00", "to": "2026-06-10T11:00:00+03:00", "skipTime": false, "durationSeconds": 3600, "createdBy": 1, "dateCreate": "06/05/2026 09:12:00 am", "updatedAt": "06/05/2026 09:12:00 am", "description": "Еженедельная синхронизация", "accessibility": "busy", "importance": "normal", "isMeeting": false, "meetingStatus": "H", "meetingHost": 1, "sectionId": 3, "attendeeList": [ { "id": 1, "entryId": "7773", "status": "H" } ] } ], "meta": { "total": 1, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные `type` и `ownerId`: ```json { "success": false, "error": { "code": "MISSING_REQUIRED_PARAMS", "message": "GET /v1/calendar-events requires query parameters: type, ownerId. Example: GET /v1/calendar-events?type=...&ownerId=..." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_REQUIRED_PARAMS` | Не переданы `type` и (или) `ownerId` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация.** При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 и собирает их в один ответ. Если общее количество событий больше `limit`, в `meta.hasMore` придёт `true`. **Регулярные события.** Событие с полем `rrule` в списке возвращается отдельным элементом на каждое вхождение серии, попадающее в окно выборки. У всех элементов общий `id` и `parentId`, отличаются только `from` / `to`. ## Смотрите также - [Создать событие](./create.md) - [Получить событие](./get.md) - [Поля события](./fields.md) --- # Calendar Events: Update ## Обновить событие `PATCH /v1/calendar-events/:id` Обновляет поля существующего события. Передавайте только изменяемые поля — Вайбкод автоматически дочитывает текущее событие и подставляет `type`, `ownerId`, `name`, которые Битрикс24 требует при каждом обновлении. ## Часто обновляемые поля | Поле | Тип | Описание | |------|-----|---------| | `name` | string | Название события | | `to` | datetime | Перенос окончания (ISO 8601). Передавайте вместе с `timezoneTo` | | `timezoneTo` | string | Часовой пояс окончания (IANA-имя, `Europe/Moscow`) | | `location` | string | Место проведения | | `description` | string | Описание | | `accessibility` | string | Занятость: `busy`, `quest`, `free`, `absent` | | `importance` | string | Важность: `high`, `normal`, `low` | | `attendees` | number[] | Массив ID приглашённых сотрудников | Полный список изменяемых полей: [`GET /v1/calendar-events/fields`](./fields.md). ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/calendar-events/7773" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Созвон с командой — расширенная встреча", "to": "2026-06-10T12:00:00", "timezoneTo": "Europe/Moscow", "location": "Переговорная №3" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/calendar-events/7773" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Созвон с командой — расширенная встреча", "to": "2026-06-10T12:00:00", "timezoneTo": "Europe/Moscow", "location": "Переговорная №3" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/7773', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Созвон с командой — расширенная встреча', to: '2026-06-10T12:00:00', timezoneTo: 'Europe/Moscow', location: 'Переговорная №3', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-events/7773', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Созвон с командой — расширенная встреча', to: '2026-06-10T12:00:00', timezoneTo: 'Europe/Moscow', location: 'Переговорная №3', }), }) const { success, data } = await res.json() ``` ## Поля ответа Обновлённый объект события со всеми полями — см. [Поля события](./fields.md). ## Пример ответа ```json { "success": true, "data": { "id": 7773, "parentId": 7773, "type": "user", "ownerId": 1, "name": "Созвон с командой — расширенная встреча", "from": "2026-06-10T10:00:00+03:00", "to": "2026-06-10T12:00:00+03:00", "skipTime": false, "durationSeconds": 7200, "updatedAt": "06/05/2026 11:30:00 am", "accessibility": "busy", "importance": "normal", "sectionId": 3, "location": "Переговорная №3" } } ``` ## Пример ответа при ошибке 404 — событие не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "calendarEvent 99999999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Событие с указанным `id` не существует | | 400 | `READONLY_FIELD` | В теле запроса передано read-only поле — полный список в [Поля события](./fields.md) с пометкой «да» в колонке RO | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Перенос начала события через `PATCH` сейчас не работает.** Поле `from` принимается, но новое значение в Битрикс24 не записывается. Поле `to` обновляется корректно. Чтобы перенести начало события — удалите старое и создайте новое через [`POST /v1/calendar-events`](./create.md). ## Смотрите также - [Получить событие](./get.md) - [Поля события](./fields.md) - [Создать событие](./create.md) - [Удалить событие](./delete.md) --- # Calendar Sections: Create > Эндпоинт развёрнут на стадии. Примеры верифицируются после деплоя в продакшен. ## Создать секцию `POST /v1/calendar-sections` Создаёт новую секцию (календарь) для сотрудника, группы или компании. Битрикс24 создаёт секцию от имени сотрудника, чьи токены привязаны к API-ключу. Администратор портала может создавать секции для других сотрудников. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `type` | string | да | Тип календаря: `user`, `group` | | `ownerId` | number | да | Идентификатор владельца календаря: сотрудник (`GET /v1/users`) или рабочая группа | | `name` | string | да | Название секции | | `description` | string | нет | Описание | | `color` | string | нет | Цвет секции (`#RRGGBB`) | | `textColor` | string | нет | Цвет текста (`#RRGGBB`) | | `export` | object | нет | Параметры экспорта в формате iCal: `{ "ALLOW": boolean, "SET": "all" \| "3_9" \| "6_12" }`. Ключи внутри объекта — в верхнем регистре. `SET` задаёт период экспорта: `all` — за всё время, `3_9` — 3 месяца назад и 9 вперёд, `6_12` — 6 месяцев назад и 12 вперёд | Поля только на чтение (`id`, `access`, `perm`, `isCollab`, `createdBy`, `dateCreate`, `updatedAt`) в теле запроса передавать нельзя — API Вайбкода вернёт `400 READONLY_FIELD`. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/calendar-sections" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1, "name": "Командные встречи", "description": "Календарь для регулярных созвонов", "color": "#9cbeee", "textColor": "#283000", "export": { "ALLOW": true, "SET": "3_9" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/calendar-sections" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1, "name": "Командные встречи", "description": "Календарь для регулярных созвонов", "color": "#9cbeee", "textColor": "#283000", "export": { "ALLOW": true, "SET": "3_9" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-sections', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'user', ownerId: 1, name: 'Командные встречи', description: 'Календарь для регулярных созвонов', color: '#9cbeee', textColor: '#283000', export: { ALLOW: true, SET: '3_9', }, }), }) const { success, data } = await res.json() console.log('Идентификатор секции:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-sections', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'user', ownerId: 1, name: 'Командные встречи', description: 'Календарь для регулярных созвонов', color: '#9cbeee', textColor: '#283000', export: { ALLOW: true, SET: '3_9', }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор созданной секции — единственное поле, которое возвращает Битрикс24 после создания | Чтобы получить остальные поля созданной секции (`color`, `access`, `perm` и т. д.), запросите [`GET /v1/calendar-sections?type=<...>&ownerId=<...>`](./list.md) и найдите запись по `id`. ## Пример ответа ```json { "success": true, "data": { "id": 99 } } ``` ## Пример ответа при ошибке 400 — передано поле только на чтение: ```json { "success": false, "error": { "code": "READONLY_FIELD", "message": "Field 'access' is read-only and cannot be set" } } ``` 422 — пропущено обязательное поле: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "The required parameter \"name\" for the method \"calendar.section.add\" is not set." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Пропущено обязательное поле (`type`, `ownerId`, `name`) или некорректное значение поля | | 400 | `READONLY_FIELD` | В теле запроса передано поле только на чтение (`id`, `access`, `perm`, `isCollab`, `createdBy`, `dateCreate`, `updatedAt`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 403 | `WRITE_BLOCKED_READONLY_KEY` | API-ключ в режиме «только чтение» — запись запрещена | | 401 | `TOKEN_MISSING` | У API-ключа нет настроенных токенов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 временно недоступен — повторите запрос позже | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Битрикс24 возвращает после создания только `id`.** Это формат метода `calendar.section.add` — он отдаёт идентификатор новой секции и не включает остальные поля. Чтобы получить созданную секцию полностью (с присвоенными правами `access` и `perm`) — сделайте отдельный запрос к [`GET /v1/calendar-sections`](./list.md). **Поле `export` сохраняет регистр.** Передавайте именно `{ "ALLOW": true, "SET": "3_9" }` — ключи в верхнем регистре. API Вайбкода не преобразует ключи внутри `export` к camelCase. Если ключи передать в нижнем регистре, Битрикс24 их проигнорирует. ## Смотрите также - [Список секций](./list.md) - [Обновить секцию](./update.md) - [Удалить секцию](./delete.md) - [События календаря](/docs/entities/calendar-events) — события привязываются к секции через `sectionId` --- # Calendar Sections: Delete > Эндпоинт развёрнут на стадии. Примеры верифицируются после деплоя в продакшен. ## Удалить секцию `DELETE /v1/calendar-sections/:id` Удаляет секцию (календарь) по идентификатору. Восстановить удалённую секцию через API нельзя — повторите [`POST /v1/calendar-sections`](./create.md), если потребуется снова. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор секции | | `type` (query или body) | string | да | Тип календаря: `user`, `group`. Битрикс24 не умеет находить секцию по одному `id` — нужно явно указать пару `type` + `ownerId` | | `ownerId` (query или body) | number | да | Идентификатор владельца календаря | Параметры `type` и `ownerId` принимаются и в строке запроса, и в теле — если переданы оба, **приоритет у строки запроса**. Если параметр опущен и там, и там — API Вайбкода возвращает `400 MISSING_REQUIRED_PARAMS` до вызова Битрикс24. ## Примеры ### curl — личный ключ (параметры в строке запроса) ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/calendar-sections/42?type=user&ownerId=1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — личный ключ (параметры в теле запроса) ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/calendar-sections/42" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1 }' ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/calendar-sections/42?type=user&ownerId=1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const params = new URLSearchParams({ type: 'user', ownerId: '1' }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/calendar-sections/42?${params}`, { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Секция удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const params = new URLSearchParams({ type: 'user', ownerId: '1' }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/calendar-sections/42?${params}`, { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом. Признак успеха — код ответа, не содержимое. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 400 — пропущены `type` и `ownerId`: ```json { "success": false, "error": { "code": "MISSING_REQUIRED_PARAMS", "message": "DELETE /v1/calendar-sections/:id requires type, ownerId (query or body). Example: DELETE /v1/calendar-sections/:id?type=...&ownerId=...", "missing": ["type", "ownerId"] } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_REQUIRED_PARAMS` | Не переданы `type` и (или) `ownerId` — ни в строке запроса, ни в теле. Поле `missing` в ответе перечисляет конкретные пропущенные ключи | | 422 | `BITRIX_ERROR` | Секция с указанным `id` не существует или уже удалена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 403 | `WRITE_BLOCKED_READONLY_KEY` | API-ключ в режиме «только чтение» — запись запрещена | | 401 | `TOKEN_MISSING` | У API-ключа нет настроенных токенов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 временно недоступен — повторите запрос позже | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Подтверждения нет.** Запрос выполняется без интерактивного подтверждения и без отмены — операция необратима. Перед удалением убедитесь, что секция вам больше не нужна (например, перенесите события в другую секцию через [`PATCH /v1/calendar-events/:id`](/docs/entities/calendar-events/update) с новым `sectionId`). **Приоритет строки запроса над телом.** Если `type` и `ownerId` переданы и в `?type=...&ownerId=...`, и в JSON-теле — берутся значения из строки запроса. Тело используется только как запасной источник, когда параметров в строке нет. ## Смотрите также - [Список секций](./list.md) - [События календаря](/docs/entities/calendar-events) — события привязываются к секции через `sectionId` - [Batch](/docs/batch) — массовое удаление --- # Calendar Sections: List > Эндпоинт развёрнут на стадии. Примеры верифицируются после деплоя в продакшен. ## Список секций `GET /v1/calendar-sections` Возвращает все секции календаря для пары `type` + `ownerId`. У одного сотрудника может быть несколько секций — например, «Работа», «Личное», «Командные встречи». ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `type` (query) | string | да | — | Тип календаря: `user` (личный), `group` (групповой), `company_calendar` (компании), `location` (переговорная) | | `ownerId` (query) | number | да | — | Идентификатор владельца календаря: сотрудник (`GET /v1/users`), рабочая группа или `0` для `type=location` | | `limit` (query) | number | нет | `50` | Количество записей (до 5000). При `limit > 50` API Вайбкода автоматически запрашивает несколько страниц у Битрикс24 | | `offset` (query) | number | нет | `0` | Пропустить N записей | На стороне Битрикс24 метод `calendar.section.get` не поддерживает фильтрацию через `filter[...]`. Любая попытка передать `filter[name]=...` или другой ключ возвращает `400 UNSUPPORTED_FILTER` — без вызова Битрикс24. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-sections?type=user&ownerId=1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/calendar-sections?type=user&ownerId=1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const params = new URLSearchParams({ type: 'user', ownerId: '1' }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/calendar-sections?${params}`, { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} секций`) ``` ### JavaScript — OAuth-приложение ```javascript const params = new URLSearchParams({ type: 'user', ownerId: '1' }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/calendar-sections?${params}`, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив секций | | `meta.total` | number | Общее количество секций в выборке | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | Поля одной секции в массиве `data`: | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | Идентификатор секции | | `name` | string | нет | Название | | `description` | string | нет | Описание | | `type` | string | нет | Тип календаря: `user`, `group`, `company_calendar`, `location` | | `ownerId` | number | нет | Идентификатор владельца календаря | | `color` | string | нет | Цвет секции (`#RRGGBB`) | | `textColor` | string | нет | Цвет текста (`#RRGGBB`) | | `export` | object | нет | Параметры экспорта в формате iCal: `{ "ALLOW": boolean, "SET": "all" \| "3_9" \| "6_12" }`. Ключи внутри объекта — в верхнем регистре, формат сохраняется на запись и чтение без преобразований | | `access` | object | да | Карта прав доступа: ключ — идентификатор права доступа, значение — числовой идентификатор разрешения | | `perm` | object | да | Карта разрешений текущего сотрудника: `view_time`, `view_title`, `view_full`, `add`, `edit`, `edit_section`, `access` | | `isCollab` | boolean | да | Принадлежность к коллабе | | `createdBy` | number | да | Идентификатор создателя секции | | `dateCreate` | datetime | да | Дата создания | | `updatedAt` | datetime | да | Дата последнего изменения | «RO» (read-only) — поле доступно только на чтение, передавать в `POST` / `PATCH` нельзя (Вайбкод вернёт `400 READONLY_FIELD`). ## Пример ответа ```json { "success": true, "data": [ { "id": 42, "name": "Работа", "description": "Основной рабочий календарь", "type": "user", "ownerId": 1, "color": "#9cbeee", "textColor": "#283000", "export": { "ALLOW": true, "SET": "3_9" }, "access": { "U1": "calendar_owner", "G2": 13 }, "perm": { "view_time": true, "view_title": true, "view_full": true, "add": true, "edit": true, "edit_section": true, "access": true }, "isCollab": false, "createdBy": 1, "dateCreate": "2026-05-15T09:34:33+03:00", "updatedAt": "2026-05-15T09:34:33+03:00" } ], "meta": { "total": 1, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные `type` и (или) `ownerId`: ```json { "success": false, "error": { "code": "MISSING_REQUIRED_PARAMS", "message": "GET /v1/calendar-sections requires query parameters: type, ownerId. Example: GET /v1/calendar-sections?type=...&ownerId=..." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_REQUIRED_PARAMS` | Не переданы `type` и (или) `ownerId` | | 400 | `UNSUPPORTED_FILTER` | Передан ключ `filter[...]` — метод `calendar.section.get` не поддерживает фильтрацию. Допустимы только `type`, `ownerId`, `limit`, `offset` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 401 | `TOKEN_MISSING` | У API-ключа нет настроенных токенов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 временно недоступен — повторите запрос позже | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`limit` и `offset` принимаются, но фильтрации на стороне Битрикс24 нет.** Метод `calendar.section.get` всегда возвращает все секции для указанной пары `type` + `ownerId`. API Вайбкода применяет `limit` / `offset` к полученному массиву уже после ответа Битрикс24. **Поле `export` сохраняет регистр Битрикс24.** Ключи внутри `export` остаются `ALLOW` и `SET` в верхнем регистре — не преобразуются к camelCase. То же при отправке через [`POST /v1/calendar-sections`](./create.md): передавайте именно `{ "ALLOW": true, "SET": "3_9" }`. **Получить секцию по одному `id` через API нельзя.** Эндпоинт `GET /v1/calendar-sections/:id` не реализован, потому что у Битрикс24 нет соответствующего метода. Чтобы найти одну секцию по `id` — получите список и отфильтруйте на стороне клиента: `data.find(s => s.id === 42)`. ## Смотрите также - [Создать секцию](./create.md) - [Обновить секцию](./update.md) - [Удалить секцию](./delete.md) - [События календаря](/docs/entities/calendar-events) — события привязываются к секции через `sectionId` --- # Calendar Sections: Update > Эндпоинт развёрнут на стадии. Примеры верифицируются после деплоя в продакшен. ## Обновить секцию `PATCH /v1/calendar-sections/:id` Обновляет поля существующей секции. **Битрикс24 требует `type`, `ownerId` и `name` в каждом вызове `calendar.section.update`** — поэтому эти три поля обязательны в теле запроса, даже если меняется только цвет или описание. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор секции | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `type` | string | да | Тип календаря: `user`, `group`. Должен соответствовать `type` существующей секции — иначе Битрикс24 вернёт ошибку доступа | | `ownerId` | number | да | Идентификатор владельца календаря. Должен соответствовать `ownerId` существующей секции | | `name` | string | да | Название секции. Битрикс24 требует поле даже при изменении других полей — передавайте текущее значение, если переименование не нужно | | `description` | string | нет | Описание | | `color` | string | нет | Цвет секции (`#RRGGBB`) | | `textColor` | string | нет | Цвет текста (`#RRGGBB`) | | `export` | object | нет | Параметры экспорта в формате iCal: `{ "ALLOW": boolean, "SET": "all" \| "3_9" \| "6_12" }`. Ключи внутри объекта — в верхнем регистре | Поля только на чтение (`id`, `access`, `perm`, `isCollab`, `createdBy`, `dateCreate`, `updatedAt`) в теле запроса передавать нельзя. ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/calendar-sections/42" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1, "name": "Командные встречи", "color": "#FF5733", "description": "Обновлённое описание" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/calendar-sections/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "user", "ownerId": 1, "name": "Командные встречи", "color": "#FF5733", "description": "Обновлённое описание" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-sections/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'user', ownerId: 1, name: 'Командные встречи', color: '#FF5733', description: 'Обновлённое описание', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calendar-sections/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'user', ownerId: 1, name: 'Командные встречи', color: '#FF5733', description: 'Обновлённое описание', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор обновлённой секции — единственное поле, которое возвращает Битрикс24 | Чтобы получить актуальные значения остальных полей — запросите [`GET /v1/calendar-sections?type=<...>&ownerId=<...>`](./list.md). ## Пример ответа ```json { "success": true, "data": { "id": 42 } } ``` ## Пример ответа при ошибке 422 — пропущено обязательное поле `name`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Не задан обязательный параметр \"name\" для метода \"calendar.section.update\"" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Пропущено обязательное поле (`type`, `ownerId`, `name`), некорректное значение или секция с указанным `id` не существует | | 400 | `READONLY_FIELD` | В теле запроса передано поле только на чтение | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `calendar` | | 403 | `WRITE_BLOCKED_READONLY_KEY` | API-ключ в режиме «только чтение» — запись запрещена | | 401 | `TOKEN_MISSING` | У API-ключа нет настроенных токенов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 временно недоступен — повторите запрос позже | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`type`, `ownerId`, `name` обязательны в каждом вызове.** Битрикс24 не реализует частичное обновление для секций — метод `calendar.section.update` требует все три поля, даже если меняется только цвет. Если переименование не нужно — передайте текущее `name` (можно получить через [`GET /v1/calendar-sections`](./list.md)). **Битрикс24 возвращает только `id` после обновления.** Чтобы увидеть обновлённую секцию полностью — сделайте отдельный запрос к [`GET /v1/calendar-sections`](./list.md). ## Смотрите также - [Список секций](./list.md) - [Создать секцию](./create.md) - [Удалить секцию](./delete.md) --- # Catalog Prices: Create ## Создать цену `POST /v1/catalog-prices` Создаёт цену товара. Поля передаются плоско в корне JSON. У одного товара может быть по одной цене на каждый тип цены (`catalogGroupId`). ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `productId` | number | да | ID товара, к которому относится цена. Список: `GET /v1/catalog-products?filter[iblockId]=` (значение `iblockId` — из `GET /v1/catalogs`) | | `catalogGroupId` | number | да | Тип цены. Базовая цена — `1`. Какие типы заведены на портале, видно по значениям `catalogGroupId` в [списке цен](/docs/entities/catalog-prices/list) | | `price` | number | да | Значение цены | | `currency` | string | да | Валюта цены, например `RUB`. Список: `GET /v1/currencies` | | `quantityFrom` | number | нет | Нижняя граница количественного диапазона | | `quantityTo` | number | нет | Верхняя граница количественного диапазона | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/catalog-prices" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "productId": 104, "catalogGroupId": 1, "price": 1500, "currency": "RUB" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/catalog-prices" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productId": 104, "catalogGroupId": 1, "price": 1500, "currency": "RUB" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 104, catalogGroupId: 1, price: 1500, currency: 'RUB', }), }) const { success, data } = await res.json() console.log('Price ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 104, catalogGroupId: 1, price: 1500, currency: 'RUB', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданной цены. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор созданной цены | | `productId` | number | ID товара | | `catalogGroupId` | number | Тип цены | | `price` | number | Значение цены | | `currency` | string | Валюта цены | | `quantityFrom` | number \| null | Нижняя граница количественного диапазона | | `quantityTo` | number \| null | Верхняя граница количественного диапазона | | `priceScale` | number | Цена в базовой валюте портала. При создании равна `price` | | `extraId` | number \| null | Дополнительный идентификатор | | `timestampX` | string | Дата изменения (ISO 8601 с указанием часового пояса) | ## Пример ответа ```json { "success": true, "data": { "catalogGroupId": 1, "currency": "RUB", "extraId": null, "id": 5104, "price": 1500, "priceScale": 1500, "productId": 104, "quantityFrom": null, "quantityTo": null, "timestampX": "2026-06-08T14:58:52+03:00" } } ``` ## Пример ответа при ошибке 422 — не передано обязательное поле: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Required fields: currency" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|----------| | 422 | `BITRIX_ERROR` | Не передано обязательное поле — сообщение перечисляет недостающие (`Required fields: <имя>`) | | 400 | `READONLY_FIELD` | В теле передан `id` — это поле заполняется системой и не принимается при создании | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `catalog` | | 401 | `TOKEN_MISSING` | Не передан `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список цен](/docs/entities/catalog-prices/list) - [Получить цену](/docs/entities/catalog-prices/get) - [Обновить цену](/docs/entities/catalog-prices/update) - [Удалить цену](/docs/entities/catalog-prices/delete) - [Товары каталога](/docs/entities/catalog-products) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Catalog Prices: Delete ## Удалить цену `DELETE /v1/catalog-prices/:id` Удаляет цену по идентификатору. Восстановить удалённую цену через API нельзя — при необходимости создайте новую. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор цены | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/catalog-prices/5104" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/catalog-prices/5104" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/5104', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Цена удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/5104', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Цена удалена') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — цена с указанным `id` не существует: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "price does not exist." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|----------| | 422 | `BITRIX_ERROR` | Цена с указанным `id` не существует (`price does not exist.`) | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `catalog` | | 401 | `TOKEN_MISSING` | Не передан `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать цену](/docs/entities/catalog-prices/create) - [Список цен](/docs/entities/catalog-prices/list) - [Получить цену](/docs/entities/catalog-prices/get) - [Обновить цену](/docs/entities/catalog-prices/update) - [Товары каталога](/docs/entities/catalog-products) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Catalog Prices: Fields ## Поля цены `GET /v1/catalog-prices/fields` Возвращает справочник полей цены товара с типами и признаком «только для чтения», а также список операций, доступных в пакетном запросе. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/catalog-prices/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/catalog-prices/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа `data.fields` — объект, ключ которого совпадает с именем поля, а значение содержит `type` (тип поля) и `readonly` (можно ли передать поле при создании и обновлении). `data.batch` — список операций, которые принимает [пакетный запрос](/docs/batch). | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | Идентификатор записи цены | | `catalogGroupId` | number | нет | Тип цены. Базовая цена — `1`. Какие типы заведены на портале, видно по значениям `catalogGroupId` в [списке цен](./list.md) | | `currency` | string | нет | Валюта цены, например `RUB`. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `price` | number | нет | Значение цены | | `productId` | number | нет | ID товара, к которому относится цена. Список: [`GET /v1/catalog-products`](/docs/entities/catalog-products) | | `quantityFrom` | number | нет | Нижняя граница количественного диапазона | | `quantityTo` | number | нет | Верхняя граница количественного диапазона | | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.fields.<имя>.type` | string | Тип поля: `number`, `string` | | `data.fields.<имя>.readonly` | boolean | `true` — поле заполняется системой и не принимается при создании и обновлении | | `data.batch` | string[] | Операции цены, доступные в [пакетном запросе](/docs/batch): `create`, `update`, `delete` | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "catalogGroupId": { "type": "number", "readonly": false }, "currency": { "type": "string", "readonly": false }, "price": { "type": "number", "readonly": false }, "productId": { "type": "number", "readonly": false }, "quantityFrom": { "type": "number", "readonly": false }, "quantityTo": { "type": "number", "readonly": false } }, "batch": ["create", "update", "delete"] } } ``` В ответе цены приходят и другие поля — `extraId`, `priceScale`, `timestampX`, — но они заполняются системой, недоступны для записи и фильтрации, поэтому в справочнике полей не перечислены. ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'catalog' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `TOKEN_MISSING` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список цен](/docs/entities/catalog-prices/list) - [Создать цену](/docs/entities/catalog-prices/create) - [Поиск цен](/docs/entities/catalog-prices/search) - [Товары каталога](/docs/entities/catalog-products) - [Справочник сущностей](/docs/entities-index) --- # Catalog Prices: Get ## Получить цену `GET /v1/catalog-prices/:id` Возвращает одну запись цены товара по идентификатору. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор записи цены | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/catalog-prices/5001" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/catalog-prices/5001" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/5001', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Цена:', data.price, data.currency) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/5001', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор записи цены | | `data.catalogGroupId` | number | Тип цены. Базовая цена — `1` | | `data.currency` | string | Валюта цены, например `RUB` | | `data.price` | number | Значение цены | | `data.productId` | number | Идентификатор товара, к которому относится цена | | `data.quantityFrom` | number \| null | Нижняя граница количественного диапазона. `null`, если цена не зависит от количества | | `data.quantityTo` | number \| null | Верхняя граница количественного диапазона. `null`, если цена не зависит от количества | | `data.extraId` | number \| null | Дополнительный идентификатор записи | | `data.priceScale` | number | Цена в базовой валюте портала | | `data.timestampX` | string | Дата последнего изменения (ISO 8601) | ## Пример ответа ```json { "success": true, "data": { "catalogGroupId": 2, "currency": "RUB", "extraId": null, "id": 5001, "price": 50, "priceScale": 50, "productId": 101, "quantityFrom": null, "quantityTo": null, "timestampX": "2024-06-17T16:53:24+03:00" } } ``` ## Пример ответа при ошибке 422 — записи с таким `id` нет: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "price does not exist." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Записи цены с указанным `id` не существует | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `TOKEN_MISSING` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать цену](/docs/entities/catalog-prices/create) - [Обновить цену](/docs/entities/catalog-prices/update) - [Удалить цену](/docs/entities/catalog-prices/delete) - [Список цен](/docs/entities/catalog-prices/list) - [Товары каталога](/docs/entities/catalog-products) - [Справочник сущностей](/docs/entities-index) --- # Catalog Prices: List ## Список цен `GET /v1/catalog-prices` Возвращает список цен товаров с поддержкой фильтрации, сортировки, выборки полей и пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям записи цены.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[productId]=101` | | `select` | string | — | Выборка полей: `?select=id,productId,price`. Возвращаются только перечисленные поля | | `sort` | string | — | Поле сортировки. Префикс `-` — по убыванию: `?sort=-price` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Смещение от начала выборки | Для `limit > 50` ответ автоматически собирается из нескольких страниц на стороне сервера. Максимум — 5000 записей за вызов. Если под фильтр попадает больше записей, чем возвращено, в `meta.hasMore` придёт `true`. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/catalog-prices" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/catalog-prices" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Цен: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив цен | | `data[].id` | number | Идентификатор записи цены | | `data[].catalogGroupId` | number | Тип цены. Базовая цена — `1` | | `data[].currency` | string | Валюта цены, например `RUB` | | `data[].price` | number | Значение цены | | `data[].productId` | number | Идентификатор товара, к которому относится цена | | `data[].quantityFrom` | number \| null | Нижняя граница количественного диапазона. `null`, если цена не зависит от количества | | `data[].quantityTo` | number \| null | Верхняя граница количественного диапазона. `null`, если цена не зависит от количества | | `data[].extraId` | number \| null | Дополнительный идентификатор записи | | `data[].priceScale` | number | Цена в базовой валюте портала | | `data[].timestampX` | string | Дата последнего изменения (ISO 8601) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "catalogGroupId": 2, "currency": "RUB", "extraId": null, "id": 5001, "price": 50, "priceScale": 50, "productId": 101, "quantityFrom": null, "quantityTo": null, "timestampX": "2024-06-17T16:53:24+03:00" }, { "catalogGroupId": 1, "currency": "RUB", "extraId": null, "id": 5002, "price": 10, "priceScale": 10, "productId": 102, "quantityFrom": null, "quantityTo": null, "timestampX": "2021-09-27T16:32:20+03:00" }, { "catalogGroupId": 1, "currency": "RUB", "extraId": null, "id": 5003, "price": 32999, "priceScale": 32999, "productId": 103, "quantityFrom": null, "quantityTo": null, "timestampX": "2025-01-10T14:49:59+03:00" } ], "meta": { "total": 85, "hasMore": true } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'bogusField' for entity 'catalog-prices'. Available: id, catalogGroupId, currency, price, productId, quantityFrom, quantityTo" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет у записи цены. Сообщение содержит список доступных полей | | 400 | `UNKNOWN_SORT_FIELD` | Сортировка по полю, которого нет у записи цены. Сообщение содержит список доступных полей | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `TOKEN_MISSING` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поля `extraId`, `priceScale` и `timestampX` недоступны для фильтра и сортировки.** Они приходят в ответе, но в `filter` или `sort` отвечают ошибкой. Какие поля доступны — на странице [Цены каталога](/docs/entities/catalog-prices). ## Смотрите также - [Создать цену](/docs/entities/catalog-prices/create) - [Получить цену](/docs/entities/catalog-prices/get) - [Обновить цену](/docs/entities/catalog-prices/update) - [Удалить цену](/docs/entities/catalog-prices/delete) - [Товары каталога](/docs/entities/catalog-products) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Catalog Prices: Search ## Поиск цен `POST /v1/catalog-prices/search` Поиск цен товаров по условиям, переданным в теле запроса. В отличие от [`GET /v1/catalog-prices`](./list.md), параметры `filter`, `select`, `sort`, `limit` и `offset` передаются в JSON-теле, а не в строке адреса — это удобнее для условий по нескольким полям. Формат ответа тот же, что у списка. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям записи цены.
[Синтаксис фильтрации](/docs/filtering). Пример: `{ "catalogGroupId": 1 }` | | `select` | string[] | — | Выборка полей: `["id", "productId", "price"]`. Возвращаются только перечисленные поля | | `sort` | string | — | Поле сортировки. Префикс `-` — по убыванию: `"-price"` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Смещение от начала выборки | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/catalog-prices/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "catalogGroupId": 1 }, "limit": 2 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/catalog-prices/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "catalogGroupId": 1 }, "limit": 2 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { catalogGroupId: 1 }, limit: 2, }), }) const { success, data, meta } = await res.json() console.log(`Найдено: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { catalogGroupId: 1 }, limit: 2, }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив цен | | `data[].id` | number | Идентификатор записи цены | | `data[].catalogGroupId` | number | Тип цены. Базовая цена — `1` | | `data[].currency` | string | Валюта цены, например `RUB` | | `data[].price` | number | Значение цены | | `data[].productId` | number | Идентификатор товара, к которому относится цена | | `data[].quantityFrom` | number \| null | Нижняя граница количественного диапазона. `null`, если цена не зависит от количества | | `data[].quantityTo` | number \| null | Верхняя граница количественного диапазона. `null`, если цена не зависит от количества | | `data[].extraId` | number \| null | Дополнительный идентификатор записи | | `data[].priceScale` | number | Цена в базовой валюте портала | | `data[].timestampX` | string | Дата последнего изменения (ISO 8601) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | | `meta.durationMs` | number | Время выполнения запроса в миллисекундах | ## Пример ответа ```json { "success": true, "data": [ { "catalogGroupId": 1, "currency": "RUB", "extraId": null, "id": 5002, "price": 10, "priceScale": 10, "productId": 102, "quantityFrom": null, "quantityTo": null, "timestampX": "2021-09-27T16:32:20+03:00" }, { "catalogGroupId": 1, "currency": "RUB", "extraId": null, "id": 5003, "price": 32999, "priceScale": 32999, "productId": 103, "quantityFrom": null, "quantityTo": null, "timestampX": "2025-01-10T14:49:59+03:00" } ], "meta": { "total": 22, "hasMore": true, "durationMs": 487 } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'bogus' for entity 'catalog-prices'. Available: id, catalogGroupId, currency, price, productId, quantityFrom, quantityTo" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет у записи цены. Сообщение содержит список доступных полей | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `TOKEN_MISSING` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список цен](/docs/entities/catalog-prices/list) - [Создать цену](/docs/entities/catalog-prices/create) - [Получить цену](/docs/entities/catalog-prices/get) - [Поля цены](/docs/entities/catalog-prices/fields) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Catalog Prices: Update ## Обновить цену `PATCH /v1/catalog-prices/:id` Изменяет существующую цену. Поля передаются плоско в корне JSON. Передавайте только изменяемые поля — остальные сохраняют текущие значения. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор цены | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `productId` | number | нет | ID товара, к которому относится цена. Список: `GET /v1/catalog-products?filter[iblockId]=` (значение `iblockId` — из `GET /v1/catalogs`) | | `catalogGroupId` | number | нет | Тип цены. Базовая цена — `1`. Какие типы заведены на портале, видно по значениям `catalogGroupId` в [списке цен](/docs/entities/catalog-prices/list) | | `price` | number | нет | Значение цены | | `currency` | string | нет | Валюта цены, например `RUB`. Список: `GET /v1/currencies` | | `quantityFrom` | number | нет | Нижняя граница количественного диапазона | | `quantityTo` | number | нет | Верхняя граница количественного диапазона | `id` передаётся в пути (`/v1/catalog-prices/:id`), в теле его передавать нельзя — он только для чтения. ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/catalog-prices/5104" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price": 1750 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/catalog-prices/5104" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "price": 1750 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/5104', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 1750, }), }) const { success, data } = await res.json() console.log('Новая цена:', data.price) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-prices/5104', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 1750, }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный обновлённый объект цены. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор цены | | `productId` | number | ID товара | | `catalogGroupId` | number | Тип цены | | `price` | number | Значение цены | | `currency` | string | Валюта цены | | `quantityFrom` | number \| null | Нижняя граница количественного диапазона | | `quantityTo` | number \| null | Верхняя граница количественного диапазона | | `priceScale` | number | Цена в базовой валюте портала | | `extraId` | number \| null | Дополнительный идентификатор | | `timestampX` | string | Дата изменения (ISO 8601 с указанием часового пояса) | ## Пример ответа ```json { "success": true, "data": { "catalogGroupId": 1, "currency": "RUB", "extraId": null, "id": 5104, "price": 1750, "priceScale": 1500, "productId": 104, "quantityFrom": null, "quantityTo": null, "timestampX": "2026-06-08T14:59:07+03:00" } } ``` ## Пример ответа при ошибке 422 — цена с указанным `id` не существует: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Price is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|----------| | 422 | `BITRIX_ERROR` | Цена с указанным `id` не существует (`Price is not exists`) | | 400 | `READONLY_FIELD` | В теле передан `id` — это поле заполняется системой и не принимается при обновлении | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `catalog` | | 401 | `TOKEN_MISSING` | Не передан `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`priceScale` не пересчитывается при изменении `price`.** При создании `priceScale` совпадает с `price`. Если обновить только `price`, в ответе `priceScale` сохранит прежнее значение. ## Смотрите также - [Создать цену](/docs/entities/catalog-prices/create) - [Список цен](/docs/entities/catalog-prices/list) - [Получить цену](/docs/entities/catalog-prices/get) - [Удалить цену](/docs/entities/catalog-prices/delete) - [Товары каталога](/docs/entities/catalog-products) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Catalog Products: Aggregate ## Агрегация продуктов каталога `POST /v1/catalog-products/aggregate` Агрегация данных: подсчёт количества, сумма, среднее, минимум, максимум. Поддерживает фильтрацию и группировку по любому полю из списка `aggregatable`. **Поля, доступные для агрегации:** - `purchasingPrice` - `quantity` - `iblockSectionId` ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `filter` | object | нет | Фильтрация — те же поля, что в `GET /v1/catalog-products`. [Синтаксис фильтрации](/docs/filtering) | | `aggregate` | array | нет | Агрегации: `[{ "field": "purchasingPrice", "function": "sum" }]`. Функции: `sum`, `avg`, `min`, `max`, `count`. Без параметра — только count | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (max 5). Допустимые значения из списка выше | ## Примеры ### curl — без группировки ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/catalog-products/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "purchasingPrice", "function": "sum" }, { "field": "purchasingPrice", "function": "avg" } ] }' ``` ### JavaScript ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalog-products/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'purchasingPrice', function: 'sum' }], }), }) const { success, data } = await res.json() console.log('Всего:', data.count) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `count` | number | Общее количество записей, соответствующих фильтру | | `aggregates` | object | Результаты агрегаций: `{ "purchasingPrice": { "sum": 0 } }` | | `meta.totalRecords` | number | Общее количество записей | | `meta.recordsProcessed` | number | Количество обработанных записей (max 5000) | | `meta.truncated` | boolean | `true`, если записей больше 5000 — агрегация по выборке | ## Пример ответа — без группировки ```json { "success": true, "data": { "count": 41, "aggregates": { "purchasingPrice": { "sum": 100000, "avg": 2439 } }, "meta": { "totalRecords": 41, "recordsProcessed": 41, "truncated": false } } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'catalog' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Неизвестное поле агрегации или недопустимая функция | | 400 | `INVALID_PARAMS` | Передано более 5 полей в `groupBy` (максимум 5) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Без `aggregate` — только count.** Если не передать массив `aggregate`, метод вернёт только `count` записей с учётом фильтра. **`groupBy` принимает строку или массив.** Для группировки по одному полю передайте строку: `"groupBy": "purchasingPrice"`. Для нескольких — массив: `"groupBy": ["purchasingPrice", "quantity"]`. Максимум 5 полей. **Плоская структура групп.** Поля группировки выводятся как прямые ключи в каждом элементе `groups`, не вложены: `{ "purchasingPrice": "...", "count": N, "aggregates": {...} }`. **Ограничение 5000 записей.** Если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true` — агрегация и подсчёт групп выполняются по первым 5000 записям выборки. ## Смотрите также - [Список каталог-продуктов](/docs/entities/catalog-products/list) — получить записи с фильтрацией - [Поиск каталог-продуктов](/docs/entities/catalog-products/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Catalogs: Fields ## Поля каталога `GET /v1/catalogs/fields` Возвращает справочник полей торгового каталога с типами. Все поля доступны только для чтения. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/catalogs/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/catalogs/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | Идентификатор каталога. Совпадает с `iblockId` | | `iblockId` | number | да | ID информационного блока каталога. По нему фильтруются [`GET /v1/catalog-products`](/docs/entities/catalog-products), [`GET /v1/catalog-sections`](/docs/entities/catalog-sections), [`GET /v1/catalog-prices`](/docs/entities/catalog-prices) | | `iblockTypeId` | string | да | Тип информационного блока, например `CRM_PRODUCT_CATALOG` | | `lid` | string | да | ID сайта, к которому привязан каталог | | `name` | string | да | Название каталога | | `originatorId` | string | да | Идентификатор внешнего источника. Заполняется для импортированных каталогов | | `productIblockId` | number | да | У каталога предложений — `iblockId` связанного каталога товаров. У базового каталога товаров — `null` | | `skuPropertyId` | number | да | У каталога предложений — ID свойства связи предложения с товаром. У базового каталога — `null` | | `subscription` | string | да | Признак каталога подписок: `Y` или `N` | | `vatId` | number | да | ID ставки НДС по умолчанию для товаров каталога | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "iblockId": { "type": "number", "readonly": true }, "iblockTypeId": { "type": "string", "readonly": true }, "lid": { "type": "string", "readonly": true }, "name": { "type": "string", "readonly": true }, "originatorId": { "type": "string", "readonly": true }, "productIblockId": { "type": "number", "readonly": true }, "skuPropertyId": { "type": "number", "readonly": true }, "subscription": { "type": "string", "readonly": true }, "vatId": { "type": "number", "readonly": true } } } } ``` Все поля помечены `readonly: true` — изменить каталог через API нельзя. ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'catalog' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список каталогов](/docs/entities/catalogs/list) - [Получить каталог](/docs/entities/catalogs/get) - [Товары каталога](/docs/entities/catalog-products) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Catalogs: Get ## Получить каталог `GET /v1/catalogs/:id` Возвращает один торговый каталог по идентификатору со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID каталога | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/catalogs/25" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/catalogs/25" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs/25', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Каталог:', data.name, '— iblockId', data.iblockId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs/25', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект каталога со всеми полями — см. [Поля каталога](/docs/entities/catalogs/fields). ## Пример ответа ```json { "success": true, "data": { "id": 25, "iblockId": 25, "iblockTypeId": "CRM_PRODUCT_CATALOG", "lid": "s1", "name": "Товарный каталог CRM", "productIblockId": null, "skuPropertyId": null, "subscription": "N", "vatId": 1 } } ``` ## Пример ответа при ошибке 422 — каталог не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "catalog does not exist." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Каталога с таким `id` нет — в сообщении «catalog does not exist.». Тот же ответ возвращается для нечислового `id` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Каталог товаров или каталог предложений.** Тип каталога видно по полям `productIblockId` и `skuPropertyId`: у базового каталога товаров оба `null`; у каталога предложений они заполнены, причём `productIblockId` — это `iblockId` связанного каталога товаров. ## Смотрите также - [Поля каталога](/docs/entities/catalogs/fields) - [Список каталогов](/docs/entities/catalogs/list) - [Товары каталога](/docs/entities/catalog-products) - [Справочник сущностей](/docs/entities-index) --- # Catalogs: List ## Список каталогов `GET /v1/catalogs` Возвращает список торговых каталогов портала с поддержкой фильтрации, сортировки и выборки полей. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` ответ автоматически собирается из нескольких страниц Битрикс24 | | `select` | string | — | Выборка полей: `?select=id,name`. Возвращаются только перечисленные поля | | `sort` | string | — | Поле сортировки. Префикс `-` — по убыванию: `?sort=-id` | | `filter` | object | — | Фильтрация по полям `GET /v1/catalogs/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[iblockTypeId]=CRM_PRODUCT_CATALOG` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/catalogs" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/catalogs" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Каталогов: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив каталогов (все поля — см. [Поля каталога](/docs/entities/catalogs/fields)) | | `meta.total` | number | Общее количество каталогов, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 25, "iblockId": 25, "iblockTypeId": "CRM_PRODUCT_CATALOG", "lid": "s1", "name": "Товарный каталог CRM", "productIblockId": null, "skuPropertyId": null, "subscription": "N", "vatId": 1 }, { "id": 27, "iblockId": 27, "iblockTypeId": "CRM_PRODUCT_CATALOG", "lid": "s1", "name": "Товарный каталог CRM (предложения)", "productIblockId": 25, "skuPropertyId": 101, "subscription": "N", "vatId": 1 } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'nonExistentField' for entity 'catalogs'. Available: id, iblockId, iblockTypeId, lid, name, originatorId, productIblockId, skuPropertyId, subscription, vatId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет у каталога. Сообщение содержит список доступных полей | | 400 | `UNKNOWN_SORT_FIELD` | Сортировка по полю, которого нет у каталога | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Каталог товаров или каталог предложений.** Тип каталога в выдаче видно по полям `productIblockId` и `skuPropertyId`: у базового каталога товаров оба `null`; у каталога предложений они заполнены, причём `productIblockId` — это `iblockId` связанного каталога товаров. **Когда использовать search вместо list:** для условий по нескольким полям удобнее [`POST /v1/catalogs/search`](./search.md) — фильтр передаётся в теле запроса. ## Смотрите также - [Получить каталог](/docs/entities/catalogs/get) - [Поиск каталогов](/docs/entities/catalogs/search) - [Поля каталога](/docs/entities/catalogs/fields) - [Товары каталога](/docs/entities/catalog-products) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Catalogs: Search ## Поиск каталогов `POST /v1/catalogs/search` Поиск торговых каталогов с фильтрами. Аналог [`GET /v1/catalogs`](./list.md) с фильтрами, но через POST — удобнее для условий по нескольким полям. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/catalogs/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `{ "iblockTypeId": "CRM_PRODUCT_CATALOG" }` | | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string[] | — | Выборка полей: `["id", "name"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/catalogs/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "iblockTypeId": "CRM_PRODUCT_CATALOG" }, "limit": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/catalogs/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "iblockTypeId": "CRM_PRODUCT_CATALOG" }, "limit": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { iblockTypeId: 'CRM_PRODUCT_CATALOG' }, limit: 10, }), }) const { success, data, meta } = await res.json() console.log('Найдено:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/catalogs/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { iblockTypeId: 'CRM_PRODUCT_CATALOG' }, limit: 10, }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив каталогов (все поля — см. [Поля каталога](/docs/entities/catalogs/fields)) | | `meta.total` | number | Общее количество каталогов, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 25, "iblockId": 25, "iblockTypeId": "CRM_PRODUCT_CATALOG", "lid": "s1", "name": "Товарный каталог CRM", "productIblockId": null, "skuPropertyId": null, "subscription": "N", "vatId": 1 }, { "id": 27, "iblockId": 27, "iblockTypeId": "CRM_PRODUCT_CATALOG", "lid": "s1", "name": "Товарный каталог CRM (предложения)", "productIblockId": 25, "skuPropertyId": 101, "subscription": "N", "vatId": 1 } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'nonExistentField' for entity 'catalogs'. Available: id, iblockId, iblockTypeId, lid, name, originatorId, productIblockId, skuPropertyId, subscription, vatId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет у каталога. Сообщение содержит список доступных полей | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Каталог товаров или каталог предложений.** Тип каталога в выдаче видно по полям `productIblockId` и `skuPropertyId`: у базового каталога товаров оба `null`; у каталога предложений они заполнены, причём `productIblockId` — это `iblockId` связанного каталога товаров. **Когда использовать list вместо search:** для одного простого условия проще [`GET /v1/catalogs`](./list.md) с query-параметром `filter`. ## Смотрите также - [Список каталогов](/docs/entities/catalogs/list) - [Получить каталог](/docs/entities/catalogs/get) - [Поля каталога](/docs/entities/catalogs/fields) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entities-index) --- # Companies: Aggregate ## Агрегация компаний `POST /v1/companies/aggregate` Подсчёт количества, сумма, среднее, минимум и максимум по компаниям с фильтрацией и группировкой. **Стандартные поля:** - `revenue` — годовая выручка (числовое агрегирование имеет смысл) - `companyType` — тип компании (для `groupBy`) - `industry` — отрасль (для `groupBy`) - `assignedById` — ответственный (для `groupBy`) - `sourceId` — источник (для `groupBy`) **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "revenue", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/companies/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/companies/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "revenue", "function": "sum" }, { "field": "revenue", "function": "avg" } ], "filter": { "companyType": "CUSTOMER" }, "groupBy": "industry" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/companies/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "revenue", "function": "sum" }, { "field": "revenue", "function": "avg" } ], "filter": { "companyType": "CUSTOMER" }, "groupBy": "industry" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'revenue', function: 'sum' }, { field: 'revenue', function: 'avg' }, ], filter: { companyType: 'CUSTOMER' }, groupBy: 'industry', }), }) const { success, data } = await res.json() console.log('Всего компаний:', data.count) console.log('По отраслям:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'revenue', function: 'sum' }, { field: 'revenue', function: 'avg' }, ], filter: { companyType: 'CUSTOMER' }, groupBy: 'industry', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["industry", "companyType"]` (максимум 5). ## Другие сценарии Только `count` — самый быстрый запрос, без выгрузки записей: ```json { "filter": { "companyType": "CUSTOMER" } } ``` Работа с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF: ```json { "aggregate": [{ "field": "UF_CRM_BUDGET", "function": "sum" }], "groupBy": "UF_CRM_SEGMENT" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций: `{ "revenue": { "sum": 3000000, "avg": 50000 } }` | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей обработано для числовых агрегаций (максимум 5000) | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (агрегации + `groupBy: "industry"`): ```json { "success": true, "data": { "count": 60, "aggregates": { "revenue": { "sum": 3000000, "avg": 50000 } }, "groups": [ { "industry": "IT", "count": 35, "aggregates": { "revenue": { "sum": 2000000 } } }, { "industry": "RETAIL", "count": 25, "aggregates": { "revenue": { "sum": 1000000 } } } ], "meta": { "totalRecords": 60, "recordsProcessed": 60, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неверное имя функции, несуществующее поле или `groupBy` по неаггрегируемому полю: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Field 'foo' not found. Available numeric fields: companyType, industry, revenue, assignedById, sourceId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Невалидное имя функции, несуществующее поле, нечисловое поле в `sum`/`avg`/`min`/`max`, `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` vs числовые функции.** `count` считается одним вызовом в Битрикс24 на любом объёме данных. Функции `sum`/`avg`/`min`/`max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод — если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true`, агрегация выполнится по первым 5000. Для точных счётчиков на больших выборках используйте `count` или сужайте фильтр. **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "ufCrm_1234": "value" } }` вернёт количество компаний с этим значением UF. ## Смотрите также - [Список компаний](/docs/entities/companies/list) — получить записи с фильтрацией - [Поиск компаний](/docs/entities/companies/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Companies: Create ## Создать компанию `POST /v1/companies` Создаёт новую компанию в CRM. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название компании | | `companyType` | string | Тип: `CUSTOMER`, `SUPPLIER`, `COMPETITOR`. Список: `GET /v1/statuses?filter[entityId]=COMPANY_TYPE` | | `industry` | string | Отрасль: `IT`, `TELECOM`, `MANUFACTURING` и др. Список: `GET /v1/statuses?filter[entityId]=INDUSTRY` | | `revenue` | number | Годовой оборот | | `currencyId` | string | Валюта оборота. Список: `GET /v1/currencies` | | `phone` | string \| string[] \| object[] | Телефон. Принимает три формы: строка `"+7..."`, массив строк `["+7...", "+7..."]`, или массив объектов `[{ "value": "+7...", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MOBILE \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `email` | string \| string[] \| object[] | Email. Принимает три формы: строка `"a@b.com"`, массив строк `["a@b.com", "b@c.com"]`, или массив объектов `[{ "value": "a@b.com", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MAILING \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `web` | string \| string[] \| object[] | Веб-сайт. Принимает три формы: строка `"https://acme.com"`, массив строк, или массив объектов `[{ "value": "https://...", "typeId": "WORK" }]`. `typeId`: `WORK \| HOME \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `comments` | string | Комментарий | | `sourceId` | string | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | string | Описание источника | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `opened` | boolean | Доступна для всех | | `leadId` | number | ID лида, из которого создана компания | Полный список полей: [GET /v1/companies/fields](/docs/entities/companies/fields). ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/companies \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "ООО Ромашка", "companyType": "CUSTOMER", "industry": "IT", "phone": "+74951234567", "email": "info@romashka.ru", "web": "https://romashka.ru" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/companies \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "ООО Ромашка", "companyType": "CUSTOMER", "industry": "IT", "phone": "+74951234567", "email": "info@romashka.ru", "web": "https://romashka.ru" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'ООО Ромашка', companyType: 'CUSTOMER', industry: 'IT', phone: '+74951234567', email: 'info@romashka.ru', web: 'https://romashka.ru', }), }) const { success, data } = await res.json() console.log('Company ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'ООО Ромашка', companyType: 'CUSTOMER', industry: 'IT', phone: '+74951234567', email: 'info@romashka.ru', web: 'https://romashka.ru', }), }) const { success, data } = await res.json() ``` ### Альтернативная форма — массив объектов с явным `typeId` Если нужно указать несколько значений или явный тип (`HOME`, `OTHER`): ```json { "phone": [ { "value": "+74951234567", "typeId": "WORK" }, { "value": "+74951112233", "typeId": "OTHER" } ], "email": [ { "value": "info@romashka.ru", "typeId": "WORK" }, { "value": "sales@romashka.ru", "typeId": "MAILING" } ], "web": [ { "value": "https://romashka.ru", "typeId": "WORK" }, { "value": "https://shop.romashka.ru", "typeId": "OTHER" } ] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданной компании | | `title` | string | Название | | `typeId` | string | Тип компании | | `industry` | string | Отрасль | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdTime` | datetime | Дата создания | | `updatedTime` | datetime | Дата изменения | Ответ содержит все поля компании, включая пользовательские (`ufCrm_*`). URL карточки компании в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/crm/company/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 2923, "title": "ООО Ромашка", "typeId": "CUSTOMER", "industry": "IT", "revenue": 0, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T12:53:59+03:00", "updatedTime": "2026-04-15T12:53:59+03:00", "opened": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список компаний](/docs/entities/companies/list) — получение с фильтрами - [Поля компании](/docs/entities/companies/fields) — полный список полей - [Контакты](/docs/entities/contacts) — привязка через `companyId` - [Сделки](/docs/entities/deals) — привязка через `companyId` - [Entity API](/docs/entity-api) — общие принципы - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Companies: Delete ## Удалить компанию `DELETE /v1/companies/:id` Удаляет компанию по ID. Восстановить удалённую компанию через API нельзя — создавайте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID компании | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/companies/2923" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/companies/2923" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/2923', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Компания удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/2923', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — компания не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Компания не найдена | | 403 | `ACCESS_DENIED` | Нет доступа | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список компаний](/docs/entities/companies/list) — найти перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Companies: Fields ## Поля компании `GET /v1/companies/fields` Возвращает полный список доступных полей, включая пользовательские (`ufCrm_*`). ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/companies/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/companies/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | ID компании | | `title` | string | | Название | | `companyType` | string | | Тип. Список: `GET /v1/statuses?filter[entityId]=COMPANY_TYPE` | | `industry` | string | | Отрасль. Список: `GET /v1/statuses?filter[entityId]=INDUSTRY` | | `revenue` | number | | Годовой оборот | | `currencyId` | string | | Валюта. Список: `GET /v1/currencies` | | `phone` | multifield | | Телефон. На вход (POST/PATCH) принимает `string \| string[] \| object[]`; на выходе — алиасы `phone`/`phoneWork`/`phoneMobile`/… плюс полный `fm[]`. ⚠ PATCH **только добавляет** новые записи — старые `phone` не удаляются (особенность B24 `crm.item.update`). См. [Обновить компанию](/docs/entities/companies/update). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]`. | | `email` | multifield | | Email. На вход принимает `string \| string[] \| object[]`; на выходе — алиасы `email`/`emailWork`/`emailHome`/`emailMailing` плюс полный `fm[]`. ⚠ PATCH **только добавляет** новые записи — старые `email` не удаляются (особенность B24 `crm.item.update`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]`. | | `web` | multifield | | Сайт. На вход принимает `string \| string[] \| object[]`; на выходе — алиасы `web`/`webWork`/… плюс полный `fm[]`. ⚠ PATCH **только добавляет** новые записи — старые `web` не удаляются (особенность B24 `crm.item.update`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]`. | | `comments` | string | | Комментарий | | `sourceId` | string | | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | string | | Описание источника | | `assignedById` | number | | Ответственный. Список: `GET /v1/users` | | `createdBy` | number | да | Создатель. Поиск: `GET /v1/users` | | `updatedBy` | number | да | Кто изменил. Поиск: `GET /v1/users` | | `createdTime` | datetime | да | Дата создания | | `updatedTime` | datetime | да | Дата изменения | | `opened` | boolean | | Доступна для всех | | `leadId` | number | | ID лида-источника | **Пользовательские поля** (`ufCrm_*`) также возвращаются и принимаются. ## Доступные include Эндпоинт `GET /v1/companies/fields` возвращает список доступных include: `requisite`. Пример использования: [Получить companies](/docs/entities/companies/get#связанные-данные). Подробнее об include: [Связанные данные](/docs/includes). ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "assignedById": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Ответственный" } } } } ``` Показаны 3 из множества полей. Полный список в таблице выше. ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать компанию](/docs/entities/companies/create) — какие поля передавать - [Пользовательские поля](/docs/userfields) — `ufCrm_*` - [Entity API](/docs/entity-api) — select для выборки - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Companies: Get ## Получить компанию `GET /v1/companies/:id` Возвращает компанию по ID. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID компании | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/companies/1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/companies/1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/1', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Компания:', data.title) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/1', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` Подробнее об include: [Связанные данные](/docs/includes). ## Поля ответа Объект компании со всеми полями — см. [Поля компании](/docs/entities/companies/fields). ## Связанные данные (include) ``` GET /v1/companies/1?include=requisite ``` Доступные include: `requisite`. Результат в поле `_included`. ## Пример ответа ```json { "success": true, "data": { "id": 1, "title": "ЗАО Ложки", "industry": "IT", "companyType": "CUSTOMER", "assignedById": 1, "createdTime": "2020-05-08T10:48:20+03:00", "updatedTime": "2025-08-22T13:01:31+03:00" } } ``` ## Пример ответа при ошибке 404 — компания не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Компания не найдена | | 403 | `ACCESS_DENIED` | Нет доступа | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить компанию](/docs/entities/companies/update) — изменение полей - [Поля компании](/docs/entities/companies/fields) — описание полей - [Контакты](/docs/entities/contacts) — привязаны через `companyId` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Companies: List ## Список компаний `GET /v1/companies` Возвращает список компаний с фильтрацией, сортировкой и авто-пагинацией. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `select` | string | — | Выборка полей: `?select=id,title,phone,industry` | | `order` | object | — | Сортировка: `?order[title]=asc` | | `filter` | object | — | Фильтрация по полям `GET /v1/companies/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[industry]=IT` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/companies?limit=10&filter[industry]=IT&select=id,title,phone" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/companies?limit=10&filter[industry]=IT&select=id,title,phone" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies?limit=10&filter[industry]=IT', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} компаний`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies?limit=10&filter[industry]=IT', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив компаний (поля — см. [Поля](/docs/entities/companies/fields)) | | `meta.total` | number | Общее количество записей | | `meta.hasMore` | boolean | Есть ещё записи | URL карточки любой компании из массива `data` — её `id`: ``` https://.bitrix24.ru/crm/company/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 1, "title": "ЗАО \"Ложки\"", "phone": "+15555555555", "email": "info@lozzka.ru", "assignedById": 1, "industry": "IT" } ], "meta": { "total": 1430, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Когда использовать search:** для сложных фильтров удобнее `POST /v1/companies/search`. См. [Поиск компаний](/docs/entities/companies/search). ## Смотрите также - [Поиск компаний](/docs/entities/companies/search) — POST для сложных фильтров - [Создать компанию](/docs/entities/companies/create) — создание новой - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Companies: Search ## Поиск компаний `POST /v1/companies/search` Поиск компаний с фильтрами через POST. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/companies/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[industry]=IT` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "title": "asc" }` | | `select` | string[] | — | Выборка полей | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/companies/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "industry": "IT" }, "limit": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/companies/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "industry": "IT" }, "limit": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { industry: 'IT' }, limit: 10, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { industry: 'IT' }, limit: 10, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив компаний (поля — см. [Поля](/docs/entities/companies/fields)) | URL карточки любой компании из массива `data` — её `id`: ``` https://.bitrix24.ru/crm/company/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 1, "title": "ЗАО \"Ложки\"", "industry": "IT", "assignedById": 1 } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список компаний](/docs/entities/companies/list) — GET для простых фильтров - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Companies: Update ## Обновить компанию `PATCH /v1/companies/:id` Обновляет поля компании. Передайте только изменяемые поля. Полный список в [справочнике полей](/docs/entities/companies/fields), включая пользовательские (`ufCrm_*`). > ⚠ **Важно про `email` / `phone` / `web` (multifield):** Bitrix24 в `crm.item.update` **только добавляет** новые multifield-записи. PATCH `{"email": "new@y.com"}` к компании, у которой уже есть email, **не заменит** старый — у компании станет два email. Это особенность B24, не Вайбкод. Чтобы заменить или удалить email/phone/web — отредактируйте компанию через UI Битрикс24. ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название | | `phone` | string \| string[] \| object[] | Телефон. Принимает три формы: строка `"+7..."`, массив строк `["+7...", "+7..."]`, или массив объектов `[{ "value": "+7...", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MOBILE \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `email` | string \| string[] \| object[] | Email. Принимает три формы: строка `"a@b.com"`, массив строк `["a@b.com", "b@c.com"]`, или массив объектов `[{ "value": "a@b.com", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MAILING \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `web` | string \| string[] \| object[] | Веб-сайт. Принимает три формы: строка `"https://acme.com"`, массив строк, или массив объектов `[{ "value": "https://...", "typeId": "WORK" }]`. `typeId`: `WORK \| HOME \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `industry` | string | Отрасль. Список: `GET /v1/statuses?filter[entityId]=INDUSTRY` | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/companies/1" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "ЗАО Ложки (обновлено)", "industry": "MANUFACTURING" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/companies/1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "ЗАО Ложки (обновлено)", "industry": "MANUFACTURING" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/1', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'ЗАО Ложки (обновлено)', industry: 'MANUFACTURING' }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/companies/1', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'ЗАО Ложки (обновлено)', industry: 'MANUFACTURING' }), }) const { success, data } = await res.json() ``` ### Альтернативная форма — массив объектов с явным `typeId` Если нужно указать несколько значений или явный тип (`HOME`, `OTHER`): ```json { "phone": [ { "value": "+74951234567", "typeId": "WORK" }, { "value": "+74951112233", "typeId": "OTHER" } ], "email": [ { "value": "info@romashka.ru", "typeId": "WORK" }, { "value": "sales@romashka.ru", "typeId": "MAILING" } ], "web": [ { "value": "https://romashka.ru", "typeId": "WORK" }, { "value": "https://shop.romashka.ru", "typeId": "OTHER" } ] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект компании со всеми полями — см. [Поля](/docs/entities/companies/fields) | Обновлённый объект компании — см. [Поля компании](/docs/entities/companies/fields). ## Пример ответа ```json { "success": true, "data": { "id": 1, "title": "ЗАО Ложки (обновлено)", "industry": "MANUFACTURING", "assignedById": 1, "createdTime": "2020-05-08T10:48:20+03:00", "updatedTime": "2026-04-15T12:00:00+03:00" } } ``` ## Пример ответа при ошибке 404 — компания не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Компания не найдена | | 403 | `ACCESS_DENIED` | Нет доступа | | 400 | `INVALID_REQUEST` | Невалидные поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить компанию](/docs/entities/companies/get) — текущие значения - [Поля компании](/docs/entities/companies/fields) — все поля - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: Aggregate ## Агрегация контактов `POST /v1/contacts/aggregate` Подсчёт количества контактов с фильтрацией и группировкой. **Стандартные поля:** - `typeId` — тип контакта (для `groupBy`) - `sourceId` — источник (для `groupBy`) - `assignedById` — ответственный (для `groupBy`) Все поля в `aggregatable` — категориальные идентификаторы, поэтому по стандартным полям работают `count` и `groupBy`. Для числовых функций (`sum`/`avg`/`min`/`max`) используйте пользовательские поля. **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "*", "function": "count" }`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/contacts/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/contacts/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "assignedById": 1 }, "groupBy": "typeId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/contacts/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "assignedById": 1 }, "groupBy": "typeId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { assignedById: 1 }, groupBy: 'typeId', }), }) const { success, data } = await res.json() console.log('Всего контактов:', data.count) console.log('По типам:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { assignedById: 1 }, groupBy: 'typeId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["typeId", "sourceId"]` (максимум 5). ## Другие сценарии Общее количество контактов в портале — самый быстрый запрос, без выгрузки записей: ```json {} ``` Работа с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF: ```json { "aggregate": [{ "field": "UF_CRM_LTV", "function": "sum" }], "groupBy": "UF_CRM_SEGMENT" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций (для контактов обычно пустой) | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей обработано (для `count` — `0`, записи не выгружаются) | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (`groupBy: "typeId"`): ```json { "success": true, "data": { "count": 1200, "aggregates": {}, "groups": [ { "typeId": "CLIENT", "count": 800 }, { "typeId": "SUPPLIER", "count": 300 }, { "typeId": "PARTNER", "count": 100 } ], "meta": { "totalRecords": 1200, "recordsProcessed": 1200, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — `groupBy` по неаггрегируемому полю или несуществующему полю: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "groupBy field 'name' is not aggregatable on this entity. Available: typeId, sourceId, assignedById" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "ufCrm_1234": "value" } }` вернёт количество контактов с этим значением UF. ## Смотрите также - [Список контактов](/docs/entities/contacts/list) — получить записи с фильтрацией - [Поиск контактов](/docs/entities/contacts/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: Create ## Создать контакт `POST /v1/contacts` Создаёт новый контакт в CRM. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `name` | string | Имя | | `lastName` | string | Фамилия | | `secondName` | string | Отчество | | `phone` | string \| string[] \| object[] | Телефон. Принимает три формы: строка `"+7..."`, массив строк `["+7...", "+7..."]`, или массив объектов `[{ "value": "+7...", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MOBILE \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `email` | string \| string[] \| object[] | Email. Принимает три формы: строка `"a@b.com"`, массив строк `["a@b.com", "b@c.com"]`, или массив объектов `[{ "value": "a@b.com", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MAILING \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `companyId` | number | ID компании. Поиск: `GET /v1/companies` | | `post` | string | Должность | | `comments` | string | Комментарий | | `typeId` | string | Тип контакта. Список: `GET /v1/statuses?filter[entityId]=CONTACT_TYPE` | | `sourceId` | string | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | string | Описание источника | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `opened` | boolean | Доступен для всех | | `leadId` | number | ID лида, из которого создан контакт | Полный список полей: [GET /v1/contacts/fields](/docs/entities/contacts/fields). Пользовательские поля (`ufCrm_*`) также принимаются. ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/contacts \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Иван", "lastName": "Петров", "phone": "+79161234567", "email": "ivan@company.ru", "companyId": 15, "post": "Менеджер", "typeId": "CLIENT" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/contacts \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Иван", "lastName": "Петров", "phone": "+79161234567", "email": "ivan@company.ru", "companyId": 15, "post": "Менеджер", "typeId": "CLIENT" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Иван', lastName: 'Петров', phone: '+79161234567', email: 'ivan@company.ru', companyId: 15, post: 'Менеджер', typeId: 'CLIENT', }), }) const { success, data } = await res.json() console.log('Contact ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Иван', lastName: 'Петров', phone: '+79161234567', email: 'ivan@company.ru', companyId: 15, post: 'Менеджер', typeId: 'CLIENT', }), }) const { success, data } = await res.json() ``` ### Альтернативная форма — массив объектов с явным `typeId` Если нужно указать несколько значений или явный тип (`HOME`, `MOBILE`): ```json { "phone": [ { "value": "+79161234567", "typeId": "WORK" }, { "value": "+79161112233", "typeId": "MOBILE" } ], "email": [ { "value": "work@company.ru", "typeId": "WORK" }, { "value": "personal@me.ru", "typeId": "HOME" } ] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного контакта | | `name` | string | Имя | | `lastName` | string | Фамилия | | `companyId` | number | ID компании | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdTime` | datetime | Дата создания | | `updatedTime` | datetime | Дата изменения | | `typeId` | string | Тип контакта | | `sourceId` | string | Источник | Ответ содержит все поля контакта, включая пользовательские (`ufCrm_*`). URL карточки контакта в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/crm/contact/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 2457, "name": "Иван", "lastName": "Петров", "secondName": null, "companyId": 15, "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T12:26:17+03:00", "updatedTime": "2026-04-15T12:26:17+03:00", "opened": true, "typeId": "CLIENT", "sourceId": "CALL", "post": "Менеджер" } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список контактов](/docs/entities/contacts/list) — получение с фильтрами - [Поля контакта](/docs/entities/contacts/fields) — полный список полей - [Компании](/docs/entities/companies) — привязка через `companyId` - [Сделки](/docs/entities/deals) — контакт привязывается к сделкам через `contactId` - [Entity API](/docs/entity-api) — общие принципы - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: Delete ## Удалить контакт `DELETE /v1/contacts/:id` Удаляет контакт по ID. Восстановить удалённый контакт через API нельзя — создавайте новый при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID контакта | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/contacts/2457" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/contacts/2457" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/2457', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Контакт удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/2457', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — контакт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Контакт не найден | | 403 | `ACCESS_DENIED` | Нет доступа | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список контактов](/docs/entities/contacts/list) — найти перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: Fields ## Поля контакта `GET /v1/contacts/fields` Возвращает полный список доступных полей, включая пользовательские (`ufCrm_*`). ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/contacts/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/contacts/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | ID контакта | | `name` | string | | Имя | | `lastName` | string | | Фамилия | | `secondName` | string | | Отчество | | `phone` | multifield | | Телефон. На вход (POST/PATCH) принимает `string \| string[] \| object[]`; на выходе — алиасы `phone`/`phoneWork`/`phoneMobile`/… плюс полный `fm[]`. ⚠ PATCH **только добавляет** новые записи — старые `phone` не удаляются (особенность B24 `crm.item.update`). См. [Обновить контакт](/docs/entities/contacts/update). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]`. | | `email` | multifield | | Email. На вход принимает `string \| string[] \| object[]`; на выходе — алиасы `email`/`emailWork`/`emailHome`/`emailMailing` плюс полный `fm[]`. ⚠ PATCH **только добавляет** новые записи — старые `email` не удаляются (особенность B24 `crm.item.update`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]`. | | `companyId` | number | | ID компании. Поиск: `GET /v1/companies` | | `post` | string | | Должность | | `comments` | string | | Комментарий | | `typeId` | string | | Тип контакта. Список: `GET /v1/statuses?filter[entityId]=CONTACT_TYPE` | | `sourceId` | string | | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | string | | Описание источника | | `assignedById` | number | | Ответственный. Список: `GET /v1/users` | | `createdBy` | number | да | Создатель. Поиск: `GET /v1/users` | | `updatedBy` | number | да | Кто изменил. Поиск: `GET /v1/users` | | `createdTime` | datetime | да | Дата создания | | `updatedTime` | datetime | да | Дата изменения | | `opened` | boolean | | Доступен для всех | | `export` | boolean | | Разрешён экспорт | | `leadId` | number | | ID лида-источника | | `honorific` | string | | Обращение. Список: `GET /v1/statuses?filter[entityId]=HONORIFIC` | **Пользовательские поля** (`ufCrm_*`) также возвращаются в ответах и принимаются при создании/обновлении. ## Доступные include Эндпоинт `GET /v1/contacts/fields` возвращает список доступных include: `company`, `requisite`. Пример использования: [Получить contacts](/docs/entities/contacts/get#связанные-данные). Подробнее об include: [Связанные данные](/docs/includes). ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "assignedById": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Ответственный" } } } } ``` Показаны 3 из множества полей. Полный список в таблице выше. ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать контакт](/docs/entities/contacts/create) — какие поля передавать - [Пользовательские поля](/docs/userfields) — создание и управление `ufCrm_*` - [Entity API](/docs/entity-api) — select для выборки полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: Get ## Получить контакт `GET /v1/contacts/:id` Возвращает контакт по ID со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID контакта | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/contacts/71" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/contacts/71" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/71', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Контакт:', data.name, data.lastName) console.log('Получено:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/71', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` Подробнее об include: [Связанные данные](/docs/includes). ## Поля ответа Объект контакта со всеми полями — см. [Поля контакта](/docs/entities/contacts/fields). ## Связанные данные (include) Получить связанные сущности вместе с контактом — параметр `include` в GET-запросе: ``` GET /v1/contacts/71?include=company ``` Доступные include: `company`, `requisite`. Результат в поле `_included`. ## Пример ответа ```json { "success": true, "data": { "id": 71, "name": "Иван", "lastName": "Петров", "companyId": 1, "assignedById": 1, "sourceId": "WEB", "typeId": "CLIENT", "createdTime": "2020-05-08T10:48:20+03:00", "updatedTime": "2025-08-22T13:01:31+03:00" } } ``` ## Пример ответа при ошибке 404 — контакт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Контакт не найден | | 403 | `ACCESS_DENIED` | Нет доступа к контакту | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить контакт](/docs/entities/contacts/update) — изменение полей - [Поля контакта](/docs/entities/contacts/fields) — описание всех полей - [Компании](/docs/entities/companies) — связанная через `companyId` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: List ## Список контактов `GET /v1/contacts` Возвращает список контактов с поддержкой фильтрации, сортировки и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` авто-пагинация | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,name,lastName,phone` | | `order` | object | — | Сортировка: `?order[lastName]=asc` | | `filter` | object | — | Фильтрация по полям `GET /v1/contacts/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[companyId]=15` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/contacts?limit=10&filter[companyId]=15&select=id,name,lastName,phone" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/contacts?limit=10&filter[companyId]=15&select=id,name,lastName,phone" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts?limit=10&filter[companyId]=15&select=id,name,lastName,phone', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} контактов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts?limit=10&filter[companyId]=15&select=id,name,lastName,phone', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив контактов (поля — см. [Поля](/docs/entities/contacts/fields)) | | `meta.total` | number | Общее количество записей | | `meta.hasMore` | boolean | Есть ещё записи | URL карточки любого контакта из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/contact/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 17, "name": "Иван", "lastName": "Петров", "phone": "74955553546", "email": "ivan@company.ru", "companyId": 1, "assignedById": 1, "sourceId": "EMAIL", "typeId": "CLIENT" } ], "meta": { "total": 1167, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц. **Когда использовать search:** для сложных фильтров удобнее `POST /v1/contacts/search` — параметры в body. См. [Поиск контактов](/docs/entities/contacts/search). ## Смотрите также - [Поиск контактов](/docs/entities/contacts/search) — POST-запрос для сложных фильтров - [Создать контакт](/docs/entities/contacts/create) — создание нового - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: Search ## Поиск контактов `POST /v1/contacts/search` Поиск контактов с фильтрами через POST — удобнее для сложных запросов. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/contacts/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[companyId]=15` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "lastName": "asc" }` | | `select` | string[] | — | Выборка полей: `["id", "name", "lastName", "phone"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/contacts/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "companyId": 15 }, "limit": 10, "order": { "lastName": "asc" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/contacts/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "companyId": 15 }, "limit": 10, "order": { "lastName": "asc" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { companyId: 15 }, limit: 10, order: { lastName: 'asc' }, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { companyId: 15 }, limit: 10, order: { lastName: 'asc' }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив контактов (поля — см. [Поля](/docs/entities/contacts/fields)) | URL карточки любого контакта из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/contact/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 71, "name": "Иван", "lastName": "Петров", "phone": "74955553546", "companyId": 15, "assignedById": 1, "typeId": "CLIENT" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список контактов](/docs/entities/contacts/list) — GET-запрос для простых фильтров - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Contacts: Update ## Обновить контакт `PATCH /v1/contacts/:id` Обновляет поля существующего контакта. Передайте только изменяемые поля. Полный список в [справочнике полей](/docs/entities/contacts/fields), включая пользовательские (`ufCrm_*`). > ⚠ **Важно про `email` / `phone` (multifield):** Bitrix24 в `crm.item.update` **только добавляет** новые multifield-записи. PATCH `{"email": "new@y.com"}` к контакту, у которого уже есть email, **не заменит** старый — у контакта станет два email. Это особенность B24, не Вайбкод. Чтобы заменить или удалить email/phone — отредактируйте контакт через UI Битрикс24. ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `phone` | string \| string[] \| object[] | Телефон. Принимает три формы: строка `"+7..."`, массив строк `["+7...", "+7..."]`, или массив объектов `[{ "value": "+7...", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MOBILE \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `email` | string \| string[] \| object[] | Email. Принимает три формы: строка `"a@b.com"`, массив строк `["a@b.com", "b@c.com"]`, или массив объектов `[{ "value": "a@b.com", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MAILING \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `companyId` | number | ID компании. Поиск: `GET /v1/companies` | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `post` | string | Должность | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/contacts/71" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone": "+79169876543", "post": "Директор" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/contacts/71" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "phone": "+79169876543", "post": "Директор" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/71', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ phone: '+79169876543', post: 'Директор', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/contacts/71', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ phone: '+79169876543', post: 'Директор', }), }) const { success, data } = await res.json() ``` ### Альтернативная форма — массив объектов с явным `typeId` Если нужно указать несколько значений или явный тип (`HOME`, `MOBILE`): ```json { "phone": [ { "value": "+79161234567", "typeId": "WORK" }, { "value": "+79161112233", "typeId": "MOBILE" } ], "email": [ { "value": "work@company.ru", "typeId": "WORK" }, { "value": "personal@me.ru", "typeId": "HOME" } ] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект контакта со всеми полями — см. [Поля](/docs/entities/contacts/fields) | Обновлённый объект контакта — см. [Поля контакта](/docs/entities/contacts/fields). ## Пример ответа ```json { "success": true, "data": { "id": 71, "name": "Иван", "lastName": "Петров", "companyId": 15, "assignedById": 1, "createdTime": "2020-05-08T10:48:20+03:00", "updatedTime": "2026-04-15T12:00:00+03:00" } } ``` ## Пример ответа при ошибке 404 — контакт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Контакт не найден | | 403 | `ACCESS_DENIED` | Нет доступа | | 400 | `INVALID_REQUEST` | Невалидные поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить контакт](/docs/entities/contacts/get) — текущие значения - [Поля контакта](/docs/entities/contacts/fields) — все доступные поля - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Currencies: Create ## Создать валюту `POST /v1/currencies` Создаёт новую валюту в CRM. Код валюты задаётся в поле `id` (трёхбуквенный код ISO 4217). ## Параметры тела запроса | Параметр | Тип | Обязат. | Описание | |----------|-----|:-------:|---------| | `id` | string | да | Код валюты (RUB, USD, EUR) | | `amount` | number | да | Курс обмена относительно базовой валюты | | `amountCnt` | number | да | Номинал (обычно 1; для JPY обычно 100) | | `sort` | number | | Порядок сортировки | | `LANG` | object | | Локализация: название и формат отображения валюты (см. ниже) | > **Локализуемые поля пишутся только через `LANG`.** Поля `fullName`, `formatString`, `decimals`, `decPoint`, `thousandsSep` в Битрикс24 хранятся в структуре локализации и при плоской записи **молча игнорируются** (запрос вернёт успех, значения не сохранятся). Передавайте их через объект `LANG`: > > ```json > { "LANG": { "ru": { "FULL_NAME": "Китайский юань", "FORMAT_STRING": "# ¥", "DECIMALS": 2, "DEC_POINT": ".", "THOUSANDS_SEP": " " } } } > ``` > > На чтении API уплощает локализацию текущего языка обратно в `fullName` / `formatString` / `decimals` / `decPoint` / `thousandsSep`. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/currencies" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"id": "CNY", "amount": 12.7, "amountCnt": 1, "sort": 300, "LANG": {"ru": {"FULL_NAME": "Китайский юань"}}}' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/currencies" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"id": "CNY", "amount": 12.7, "amountCnt": 1, "sort": 300, "LANG": {"ru": {"FULL_NAME": "Китайский юань"}}}' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'CNY', amount: 12.7, amountCnt: 1, sort: 300, LANG: { ru: { FULL_NAME: 'Китайский юань' } } }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ id: 'CNY', amount: 12.7, amountCnt: 1, sort: 300, LANG: { ru: { FULL_NAME: 'Китайский юань' } } }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | string | Код валюты (RUB, USD, EUR) | | `amountCnt` | number | Количество единиц для курса | | `amount` | number | Курс обмена | | `sort` | number | Сортировка | | `base` | boolean | Базовая валюта | | `fullName` | string | Название (руб., $) | | `LID` | string | Язык | | `formatString` | string | Формат отображения | | `decPoint` | string | Разделитель дробной части | | `thousandsSep` | string | Разделитель тысяч | | `decimals` | number | Знаков после запятой | ## Пример ответа ```json { "success": true, "data": { "id": "CNY" } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Currency already exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `BITRIX_ERROR` | Ошибка Bitrix24 (дубликат кода и др.) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список валют](/docs/entities/currencies/list) — проверить существующие валюты - [Описание полей](/docs/entities/currencies/fields) — все доступные поля - [Валюты](/docs/entities/currencies) — обзор сущности --- # Currencies: Delete ## Удалить валюту `DELETE /v1/currencies/:id` Удаляет валюту из CRM по коду. Базовую валюту портала удалить нельзя. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | string | да | Код валюты (например `CNY`, `USD`) | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/currencies/CNY" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/currencies/CNY" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/CNY', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) if (res.status === 204) { console.log('Валюта удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/CNY', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — попытка удалить базовую валюту: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Нельзя удалить базовую валюту." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Невозможно удалить (базовая валюта или валюта не найдена) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список валют](/docs/entities/currencies/list) — найти валюты перед удалением - [Валюты](/docs/entities/currencies) — обзор сущности --- # Currencies: Fields ## Поля валюты `GET /v1/currencies/fields` Возвращает описание всех полей сущности с типами и атрибутами. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/currencies/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/currencies/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | string | да | Код валюты (RUB, USD, EUR) | | `amount` | number | | Курс обмена | | `amountCnt` | number | | Количество единиц для курса | | `base` | boolean | | Базовая валюта | | `sort` | number | | Сортировка | | `fullName` | string | | Название (руб., $) | | `formatString` | string | | Формат отображения | | `decPoint` | string | | Разделитель дробной части | | `thousandsSep` | string | | Разделитель тысяч | | `decimals` | number | | Знаков после запятой | ## Пример ответа ```json { "success": true, "data": { "CURRENCY": { "type": "string", "isRequired": true, "isReadOnly": true }, "AMOUNT": { "type": "double", "isRequired": true, "isReadOnly": false }, "AMOUNT_CNT": { "type": "integer", "isRequired": true, "isReadOnly": false }, "BASE": { "type": "char", "isRequired": false, "isReadOnly": false }, "SORT": { "type": "integer", "isRequired": false, "isReadOnly": false }, "FORMAT_STRING": { "type": "string", "isRequired": false, "isReadOnly": false }, "FULL_NAME": { "type": "string", "isRequired": false, "isReadOnly": false }, "DECIMALS": { "type": "integer", "isRequired": false, "isReadOnly": false }, "DEC_POINT": { "type": "string", "isRequired": false, "isReadOnly": false }, "THOUSANDS_SEP": { "type": "string", "isRequired": false, "isReadOnly": false } } } ``` ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Валюты](/docs/entities/currencies) — обзор сущности - [Список валют](/docs/entities/currencies/list) — получить валюты --- # Currencies: Get ## Получить валюту `GET /v1/currencies/:id` Возвращает валюту по коду (RUB, USD, EUR). ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | string | Код валюты (RUB, USD, EUR) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/currencies/USD" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/currencies/USD" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/USD', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/USD', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | string | Код валюты (RUB, USD, EUR) | | `amountCnt` | number | Количество единиц для курса | | `amount` | number | Курс обмена | | `sort` | number | Сортировка | | `base` | boolean | Базовая валюта | | `fullName` | string | Название (руб., $) | | `LID` | string | Язык | | `formatString` | string | Формат отображения | | `decPoint` | string | Разделитель дробной части | | `thousandsSep` | string | Разделитель тысяч | | `decimals` | number | Знаков после запятой | ## Пример ответа ```json { "success": true, "data": { "id": "USD", "fullName": "Доллар США", "amount": 92.5, "amountCnt": 1, "base": false, "sort": 200, "formatString": "$#", "decimals": 2, "decPoint": ".", "thousandsSep": "," } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Currency not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Валюта не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список валют](/docs/entities/currencies/list) — все валюты портала - [Обновить валюту](/docs/entities/currencies/update) — изменение курса - [Валюты](/docs/entities/currencies) — обзор сущности --- # Currencies: List ## Список валют `GET /v1/currencies` Возвращает список валют портала с курсами обмена. Обычно содержит менее 10 записей. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей | | `offset` | number | `0` | Пропустить N записей | | `select` | string | — | Выборка полей: `?select=id,fullName,amount` | | `order` | object | — | Сортировка: `?order[sort]=asc` | | `filter` | object | — | Фильтрация по полям `GET /v1/currencies/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[base]=true` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/currencies?select=id,fullName,amount,base" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/currencies?select=id,fullName,amount,base" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies?select=id,fullName,amount,base', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data, meta } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies?select=id,fullName,amount,base', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data[].id` | string | Код валюты (RUB, USD, EUR) | | `data[].amountCnt` | number | Количество единиц для курса | | `data[].amount` | number | Курс обмена | | `data[].sort` | number | Сортировка | | `data[].base` | boolean | Базовая валюта | | `data[].fullName` | string | Название (руб., $) | | `data[].LID` | string | Язык | | `data[].formatString` | string | Формат отображения | | `data[].decPoint` | string | Разделитель дробной части | | `data[].thousandsSep` | string | Разделитель тысяч | | `data[].decimals` | number | Знаков после запятой | ## Пример ответа ```json { "success": true, "data": [ { "id": "RUB", "fullName": "Российский рубль", "amount": 1, "amountCnt": 1, "base": true, "sort": 100, "formatString": "# руб.", "decimals": 2, "decPoint": ".", "thousandsSep": " " }, { "id": "USD", "fullName": "Доллар США", "amount": 92.5, "amountCnt": 1, "base": false, "sort": 200 } ], "meta": { "total": 3, "hasMore": false } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Валюты](/docs/entities/currencies) — обзор сущности - [Создать валюту](/docs/entities/currencies/create) — добавление новой валюты - [Batch](/docs/batch) — объединение запросов --- # Currencies: Update ## Обновить валюту `PATCH /v1/currencies/:id` Обновляет поля валюты по коду. Используйте для обновления курса обмена. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | string | Код валюты (RUB, USD, EUR) | ## Параметры тела запроса | Параметр | Тип | Описание | |----------|-----|---------| | `amount` | number | Курс обмена | | `amountCnt` | number | Номинал для курса | | `sort` | number | Порядок сортировки | | `LANG` | object | Локализация: название и формат отображения валюты (см. ниже) | > **Локализуемые поля пишутся только через `LANG`.** Поля `fullName`, `formatString`, `decimals`, `decPoint`, `thousandsSep` в Битрикс24 хранятся в структуре локализации и при плоской записи **молча игнорируются** (запрос вернёт успех, значения не сохранятся). Передавайте их через объект `LANG`: > > ```json > { "LANG": { "ru": { "FULL_NAME": "Китайский юань", "FORMAT_STRING": "# ¥", "DECIMALS": 2, "DEC_POINT": ".", "THOUSANDS_SEP": " " } } } > ``` > > На чтении API уплощает локализацию текущего языка обратно в `fullName` / `formatString` / `decimals` / `decPoint` / `thousandsSep`. ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/currencies/USD" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"amount": 94.2}' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/currencies/USD" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"amount": 94.2}' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/USD', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: 94.2 }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/currencies/USD', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: 94.2 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | boolean | `true` при успешном выполнении | ## Пример ответа ```json { "success": true, "data": true } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Currency not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Валюта не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Получить валюту](/docs/entities/currencies/get) — проверить текущий курс - [Описание полей](/docs/entities/currencies/fields) — все доступные поля - [Валюты](/docs/entities/currencies) — обзор сущности --- # Deal Categories: Create ## Создать воронку `POST /v1/deal-categories` Создаёт новую воронку сделок. После создания добавьте стадии через [справочники](/docs/entities/statuses) с `entityId = DEAL_STAGE_{id}`. ## Параметры тела запроса | Параметр | Тип | Обязат. | Описание | |----------|-----|:-------:|---------| | `name` | string | да | Название воронки | | `sort` | number | | Порядок сортировки | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deal-categories" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Корпоративные продажи", "sort": 200}' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deal-categories" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Корпоративные продажи", "sort": 200}' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Корпоративные продажи', sort: 200 }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Корпоративные продажи', sort: 200 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID воронки | | `name` | string | Название | | `sort` | number | Сортировка | | `isLocked` | string | Заблокирована (Y/N) | | `createdAt` | datetime | Дата создания | ## Пример ответа ```json { "success": true, "data": { "id": 5, "createdAt": "2026-06-01T10:00:00+03:00", "name": "Оптовые продажи", "sort": 200, "isLocked": false } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "NAME is required" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `BITRIX_ERROR` | Ошибка Bitrix24 | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Справочники CRM](/docs/entities/statuses) — создание стадий для новой воронки - [Описание полей](/docs/entities/deal-categories/fields) — все доступные поля - [Воронки сделок](/docs/entities/deal-categories) — обзор сущности --- # Deal Categories: Delete ## Удалить воронку `DELETE /v1/deal-categories/:id` Удаляет воронку сделок по ID. Основную воронку (ID 0) удалить нельзя. При удалении все сделки переносятся в основную воронку. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID воронки | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/deal-categories/3" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/deal-categories/3" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/3', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) if (res.status === 204) { console.log('Воронка удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/3', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — воронка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Not found." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Воронка не найдена | | 422 | `BITRIX_ERROR` | ID невалиден или попытка удалить основную воронку (ID 0) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список воронок](/docs/entities/deal-categories/list) — найти воронки - [Сделки](/docs/entities/deals) — сделки перенесутся в основную воронку - [Воронки сделок](/docs/entities/deal-categories) — обзор сущности --- # Deal Categories: Fields ## Поля воронки `GET /v1/deal-categories/fields` Возвращает описание всех полей воронки с типами и атрибутами. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deal-categories/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deal-categories/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | ID воронки | | `name` | string | | Название | | `sort` | number | | Сортировка | | `isLocked` | string | да | Заблокирована (Y/N) | | `createdAt` | datetime | да | Дата создания | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false }, "sort": { "type": "number", "readonly": false }, "isLocked": { "type": "string", "readonly": true }, "createdAt": { "type": "datetime", "readonly": true } }, "batch": ["create", "update", "delete"] } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Воронки сделок](/docs/entities/deal-categories) — обзор сущности - [Список воронок](/docs/entities/deal-categories/list) — получить воронки - [Сделки](/docs/entities/deals) — используют categoryId --- # Deal Categories: Get ## Получить воронку `GET /v1/deal-categories/:id` Возвращает воронку сделок по ID. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | ID воронки (0 = основная) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deal-categories/3" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deal-categories/3" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/3', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/3', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID воронки | | `name` | string | Название | | `sort` | number | Сортировка | | `isLocked` | string | Заблокирована (Y/N) | | `createdAt` | datetime | Дата создания | ## Пример ответа ```json { "success": true, "data": { "id": 3, "name": "Корпоративные продажи", "sort": 200, "isLocked": "N", "createdAt": "2025-06-01T14:00:00+03:00" } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Воронка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список воронок](/docs/entities/deal-categories/list) — все воронки - [Обновить воронку](/docs/entities/deal-categories/update) — изменение названия - [Воронки сделок](/docs/entities/deal-categories) — обзор сущности --- # Deal Categories: List ## Список воронок `GET /v1/deal-categories` Возвращает список воронок сделок. Обычно содержит менее 10 записей. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей | | `offset` | number | `0` | Пропустить N записей | | `select` | string | — | Выборка полей: `?select=id,name,sort` | | `order` | object | — | Сортировка: `?order[sort]=asc` | | `filter` | object | — | Фильтрация по полям `GET /v1/deal-categories/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[name]=Newest` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deal-categories?order[sort]=asc" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deal-categories?order[sort]=asc" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories?order[sort]=asc', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data, meta } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories?order[sort]=asc', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data[].id` | number | ID воронки | | `data[].name` | string | Название | | `data[].sort` | number | Сортировка | | `data[].isLocked` | string | Заблокирована (Y/N) | | `data[].createdAt` | datetime | Дата создания | ## Пример ответа ```json { "success": true, "data": [ { "id": 0, "name": "Общая", "sort": 100, "isLocked": "N", "createdAt": "2025-01-15T10:30:00+03:00" }, { "id": 3, "name": "Корпоративные продажи", "sort": 200, "isLocked": "N", "createdAt": "2025-06-01T14:00:00+03:00" } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Воронки сделок](/docs/entities/deal-categories) — обзор сущности - [Создать воронку](/docs/entities/deal-categories/create) — добавление воронки - [Сделки](/docs/entities/deals) — сущность, использующая воронки - [Batch](/docs/batch) — объединение запросов --- # Deal Categories: Update ## Обновить воронку `PATCH /v1/deal-categories/:id` Обновляет поля воронки сделок по ID. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | ID воронки | ## Параметры тела запроса | Параметр | Тип | Описание | |----------|-----|---------| | `name` | string | Название воронки | | `sort` | number | Порядок сортировки | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/deal-categories/3" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Корпоративные продажи B2B"}' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/deal-categories/3" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Корпоративные продажи B2B"}' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/3', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Корпоративные продажи B2B' }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deal-categories/3', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Корпоративные продажи B2B' }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Полный объект воронки после обновления | ## Пример ответа ```json { "success": true, "data": { "id": 5, "createdAt": "2026-06-01T10:00:00+03:00", "name": "Оптовые продажи", "sort": 200, "isLocked": false } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Not found." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Воронка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Получить воронку](/docs/entities/deal-categories/get) — текущие значения - [Описание полей](/docs/entities/deal-categories/fields) — все доступные поля - [Воронки сделок](/docs/entities/deal-categories) — обзор сущности --- # Deals: Aggregate ## Агрегация сделок `POST /v1/deals/aggregate` Подсчёт количества, сумма, среднее, минимум и максимум по сделкам с фильтрацией и группировкой. **Стандартные поля:** - `amount` — сумма сделки (числовое агрегирование имеет смысл) - `stageId` — стадия (для `groupBy`) - `categoryId` — воронка (для `groupBy`) - `assignedById` — ответственный (для `groupBy`) - `sourceId` — источник (для `groupBy`) **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "amount", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/deals/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deals/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "categoryId": 0 }, "groupBy": "stageId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deals/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "categoryId": 0 }, "groupBy": "stageId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'amount', function: 'sum' }, { field: 'amount', function: 'avg' }, ], filter: { categoryId: 0 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() console.log('Всего сделок в воронке:', data.count) console.log('По стадиям:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'amount', function: 'sum' }, { field: 'amount', function: 'avg' }, ], filter: { categoryId: 0 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["stageId", "sourceId"]` (максимум 5). ## Другие сценарии Только `count` — самый быстрый запрос, без выгрузки записей: ```json { "filter": { "stageId": "NEW" } } ``` Работа с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF: ```json { "aggregate": [{ "field": "UF_CRM_BUDGET", "function": "sum" }], "groupBy": "UF_CRM_PRIORITY" } ``` Сводка по воронке — один запрос с группировкой по стадии и суммой даёт разбивку, из которой на стороне приложения считается конверсия в выигранные: ```json { "aggregate": [{ "field": "amount", "function": "sum" }], "filter": { "categoryId": 0 }, "groupBy": "stageId" } ``` В ответе `data.count` — всего сделок в воронке, `data.groups` — разбивка по стадиям с суммой и количеством. Идентификаторы стадий зависят от воронки — получить их можно из [Поля](/docs/entities/deals/fields). Конверсия считается из групп без отдельного запроса: ```javascript const total = data.count const won = data.groups.find(g => g.stageId === 'WON')?.count ?? 0 const conversion = total ? Math.round((won / total) * 100) : 0 console.log(`Сделок в воронке: ${total}, выиграно: ${won}, конверсия: ${conversion}%`) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций: `{ "amount": { "sum": 100000, "avg": 2439 } }` | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей обработано для числовых агрегаций (максимум 5000) | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (агрегации + `groupBy: "stageId"`): ```json { "success": true, "data": { "count": 41, "aggregates": { "amount": { "sum": 100000, "avg": 2439 } }, "groups": [ { "stageId": "NEW", "count": 25, "aggregates": { "amount": { "sum": 60000 } } }, { "stageId": "WON", "count": 16, "aggregates": { "amount": { "sum": 40000 } } } ], "meta": { "totalRecords": 41, "recordsProcessed": 41, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неверное имя функции, несуществующее поле или `groupBy` по неаггрегируемому полю: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Field 'foo' not found. Available numeric fields: amount, stageId, categoryId, assignedById, sourceId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Невалидное имя функции, несуществующее поле, нечисловое поле в `sum`/`avg`/`min`/`max`, `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` vs числовые функции.** `count` считается одним вызовом в Битрикс24 на любом объёме данных. Функции `sum`/`avg`/`min`/`max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод — если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true`, агрегация выполнится по первым 5000. Для точных счётчиков на больших выборках используйте `count` или сужайте фильтр. **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "ufCrm_1234": "value" } }` вернёт количество сделок с этим значением UF. ## Смотрите также - [Список сделок](/docs/entities/deals/list) — получить записи с фильтрацией - [Поиск сделок](/docs/entities/deals/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Create ## Создать сделку `POST /v1/deals` Создаёт новую сделку в CRM. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название сделки | | `amount` | number | Сумма | | `currency` | string | Валюта. Список: `GET /v1/currencies` | | `stageId` | string | Стадия воронки. Стандартные: `NEW`, `PREPARATION`, `PREPAYMENT_INVOICE`, `EXECUTING`, `FINAL_INVOICE`, `WON`, `LOSE`. Портал может иметь свои — список: `GET /v1/statuses?filter[entityId]=DEAL_STAGE` | | `categoryId` | number | ID воронки (0 = основная). Список: `GET /v1/deal-categories` | | `companyId` | number | ID компании. Поиск: `GET /v1/companies` | | `contactId` | number | ID основного контакта. Поиск: `GET /v1/contacts` | | `assignedById` | number | ID ответственного. Список сотрудников: `GET /v1/users` | | `sourceId` | string | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | string | Описание источника | | `comments` | string | Комментарий | | `opened` | boolean | Доступна для всех | | `closedAt` | datetime | Дата закрытия | | `probability` | number | Вероятность успеха (%) | | `observers` | number[] | Массив ID наблюдателей. Список сотрудников: `GET /v1/users` | Полный список полей: [GET /v1/deals/fields](/docs/entities/deals/fields). Пользовательские поля (`ufCrm_*`) также принимаются. ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/deals \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Поставка оборудования", "amount": 50000, "currency": "RUB", "stageId": "NEW", "categoryId": 0, "assignedById": 1 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/deals \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Поставка оборудования", "amount": 50000, "currency": "RUB", "stageId": "NEW", "categoryId": 0, "assignedById": 1 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Поставка оборудования', amount: 50000, currency: 'RUB', stageId: 'NEW', categoryId: 0, assignedById: 1, }), }) const { success, data } = await res.json() console.log('Deal ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Поставка оборудования', amount: 50000, currency: 'RUB', stageId: 'NEW', categoryId: 0, assignedById: 1, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданной сделки | | `title` | string | Название | | `amount` | number | Сумма | | `currency` | string | Валюта | | `stageId` | string | Стадия | | `categoryId` | number | ID воронки | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdAt` | datetime | Дата создания | | `updatedAt` | datetime | Дата изменения | | `entityTypeId` | number | Тип сущности (2 = сделки) | Ответ содержит все поля сделки, включая пользовательские (`ufCrm_*`). Выше показаны основные. URL карточки сделки в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/crm/deal/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 7689, "title": "Поставка оборудования", "amount": 50000, "currency": "RUB", "stageId": "NEW", "categoryId": 0, "assignedById": 1, "createdBy": 1, "createdAt": "2026-04-14T08:43:59.000Z", "updatedAt": "2026-04-14T08:43:59.000Z", "companyId": 0, "contactId": 0, "opened": true, "closed": "N", "typeId": "SALE", "observers": [], "contactIds": [], "entityTypeId": 2 } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список сделок](/docs/entities/deals/list) — получение с фильтрами - [Поля сделки](/docs/entities/deals/fields) — полный список полей - [Entity API](/docs/entity-api) — общие принципы (пагинация, select, order) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение операций - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Delete ## Удалить сделку `DELETE /v1/deals/:id` Удаляет сделку по ID. Восстановить удалённую сделку через API нельзя — создавайте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/deals/7689" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/deals/7689" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/7689', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Сделка удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/7689', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — сделка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка не найдена | | 403 | `ACCESS_DENIED` | Нет доступа к сделке | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список сделок](/docs/entities/deals/list) — найти сделку перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Fields ## Поля сделки `GET /v1/deals/fields` Возвращает полный список доступных полей, включая пользовательские (`ufCrm_*`). ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deals/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deals/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `id` | number | да | ID сделки | | `title` | `title` | string | | Название | | `amount` | `opportunity` | number | | Сумма | | `currency` | `currencyId` | string | | Валюта. Список: `GET /v1/currencies` | | `stageId` | `stageId` | string | | Стадия воронки. Набор стадий и их идентификаторы настраиваются на стороне портала и отличаются между воронками. Актуальный список — `GET /v1/statuses?filter[entityId]=DEAL_STAGE` для основной воронки, `GET /v1/statuses?filter[entityId]=DEAL_STAGE_{N}` для воронки с `categoryId={N}` (значение `categoryId` берётся из `GET /v1/deal-categories`) | | `categoryId` | `categoryId` | number | | ID воронки (0 = основная). Список: `GET /v1/deal-categories` | | `companyId` | `companyId` | number | | ID компании. Поиск: `GET /v1/companies` | | `contactId` | `contactId` | number | | ID основного контакта. Поиск: `GET /v1/contacts` | | `contactIds` | `contactIds` | number[] | да | Все привязанные контакты. Поиск: `GET /v1/contacts` | | `assignedById` | `assignedById` | number | | Ответственный. Список: `GET /v1/users` | | `createdBy` | `createdBy` | number | да | Создатель. Поиск: `GET /v1/users` | | `updatedBy` | `updatedBy` | number | да | Кто изменил. Поиск: `GET /v1/users` | | `createdAt` | `createdTime` | datetime | да | Дата создания | | `updatedAt` | `updatedTime` | datetime | да | Дата изменения | | `closedAt` | `closedate` | datetime | | Дата закрытия | | `sourceId` | `sourceId` | string | | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | `sourceDescription` | string | | Описание источника | | `probability` | `probability` | number | | Вероятность успеха (%) | | `opened` | `opened` | boolean | | Доступна для всех | | `comments` | `comments` | string | | Комментарий | | `observers` | `observers` | number[] | | Наблюдатели. Список: `GET /v1/users` | | `typeId` | `typeId` | string | | Тип записи. Список: `GET /v1/statuses?filter[entityId]=DEAL_TYPE` | | `isReturning` | `isReturnCustomer` | boolean | | Повторная сделка | **Пользовательские поля** (`ufCrm_*`) также возвращаются в ответах и принимаются при создании/обновлении. ## Доступные include Эндпоинт `GET /v1/deals/fields` возвращает список доступных include: `contact`, `company`, `quote`. Пример использования: [Получить deals](/docs/entities/deals/get#связанные-данные). Подробнее об include: [Связанные данные](/docs/includes). ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "assignedById": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Ответственный" } } } } ``` Показаны 3 из множества полей. Полный список в таблице выше. ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать сделку](/docs/entities/deals/create) — какие поля передавать - [Пользовательские поля](/docs/userfields) — создание и управление `ufCrm_*` - [Entity API](/docs/entity-api) — select для выборки нужных полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Get ## Получить сделку `GET /v1/deals/:id` Возвращает сделку по ID со всеми полями, включая пользовательские (`ufCrm_*`). ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deals/741" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deals/741" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Сделка:', data.title, '—', data.amount, data.currency) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` Подробнее об include: [Связанные данные](/docs/includes). ## Поля ответа Объект сделки со всеми полями — см. [Поля сделки](/docs/entities/deals/fields). ## Связанные данные Получить связанные сущности вместе со сделкой — параметр `include` в GET-запросе: ``` GET /v1/deals/741?include=contact,company ``` Доступные include: `contact`, `company`, `quote`. Результат в поле `_included`: ```json { "success": true, "data": { "id": 741, "title": "Поставка оборудования", "_included": { "contacts": [{ "id": 71, "name": "Иван Петров", ... }], "company": { "id": 15, "title": "ООО Ромашка", ... } } } } ``` ## Пример ответа ```json { "success": true, "data": { "id": 741, "title": "Поставка оборудования", "amount": 50000, "currency": "RUB", "stageId": "EXECUTING", "categoryId": 0, "assignedById": 29, "createdBy": 1, "createdAt": "2020-09-25T13:08:24.000Z", "updatedAt": "2025-08-22T13:01:31.000Z", "contactId": 71, "companyId": 0, "opened": true, "observers": [], "contactIds": [], "entityTypeId": 2 } } ``` ## Пример ответа при ошибке 404 — сделка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка с таким ID не найдена | | 403 | `ACCESS_DENIED` | Нет доступа к сделке | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Поля сделки](/docs/entities/deals/fields) — все поля - [Обновить сделку](/docs/entities/deals/update) — изменение полей - [Список сделок](/docs/entities/deals/list) — поиск с фильтрами - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: List ## Список сделок `GET /v1/deals` Возвращает список сделок с поддержкой фильтрации, сортировки и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у B24 | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,title,amount` | | `order` | object | — | Сортировка: `?order[createdAt]=desc` | | `filter` | object | — | Фильтрация по полям `GET /v1/deals/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[stageId]=NEW` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deals?limit=10&order[amount]=desc&filter[stageId]=NEW" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deals?limit=10&order[amount]=desc&filter[stageId]=NEW" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals?limit=10&order[amount]=desc&filter[stageId]=NEW', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, total } = await res.json() console.log(`Найдено ${total} сделок`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals?limit=10&order[amount]=desc&filter[stageId]=NEW', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, total } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив сделок (каждая содержит все поля — см. [Поля](/docs/entities/deals/fields)) | | `total` | number | Общее количество записей, соответствующих фильтру | | `page` | number | Текущая страница | | `limit` | number | Размер страницы | URL карточки любой сделки из массива `data` — её `id`: ``` https://.bitrix24.ru/crm/deal/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 741, "title": "Поставка оборудования", "amount": 50000, "currency": "RUB", "stageId": "NEW", "categoryId": 0, "assignedById": 1, "createdAt": "2026-04-14T08:43:59.000Z", "contactId": 71, "companyId": 0, "opened": true } ], "total": 156, "page": 1, "limit": 10 } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Bitrix24 и возвращает все записи в одном ответе. **Ограничение offset:** при `offset ≥ 2500` Bitrix24 может вернуть `INTERNAL_ERROR`. Используйте `limit ≤ 500` при больших offset. **Когда использовать search вместо list:** для сложных фильтров с множеством условий удобнее `POST /v1/deals/search` — параметры передаются в body, а не в query-строке. Также search поддерживает [оконный поиск по датам](/docs/batch) для больших выборок. См. [Поиск сделок](/docs/entities/deals/search). ## Смотрите также - [Поиск сделок](/docs/entities/deals/search) — POST-запрос для сложных фильтров - [Создать сделку](/docs/entities/deals/create) — создание новой - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Products Add ## Добавить товар в сделку `POST /v1/deals/:id/products` Добавляет одну товарную позицию в сделку. В отличие от `PUT /v1/deals/:id/products`, не заменяет существующие позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | | `productId` | number | нет | ID товара из каталога. Если задан без `productName`, имя подставляется из каталога. Каталог: `GET /v1/products` | | `productName` | string | нет | Название товарной позиции — для произвольной строки без товара из каталога. Укажите хотя бы одно из `productId` / `productName`. | | `price` | number | нет | Цена за единицу | | `quantity` | number | нет | Количество | | `discount` | number | нет | Сумма скидки | | `taxRate` | number | нет | Ставка налога (%) | | `taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deals/741/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deals/741/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() console.log('ID строки:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID созданной товарной строки | ## Пример ответа ```json { "success": true, "data": { "id": 1465 } } ``` ## Пример ответа при ошибке 404 — сделка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/deals/products-get) — получить текущий список - [Установить товары](/docs/entities/deals/products-set) — заменить все позиции - [Удалить товар](/docs/entities/deals/products-delete) — удалить одну позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Deals: Products Delete ## Удалить товар из сделки `DELETE /v1/deals/:id/products/:rowId` Удаляет одну товарную позицию из сделки по ID строки. Восстановить удалённую позицию через API нельзя — добавляйте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/deals/741/products/1465" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/deals/741/products/1465" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Товар удалён из сделки') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — сделка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка или товарная строка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/deals/products-get) — получить текущий список - [Добавить товар](/docs/entities/deals/products-add) — добавить позицию - [Установить товары](/docs/entities/deals/products-set) — заменить все позиции - [Товары каталога](/docs/entities/products) — справочник товаров --- # Deals: Products Fields ## Поля товаров сделки `GET /v1/deals/:id/products/fields` Возвращает описание полей товарных позиций сделки: названия, типы, доступность для чтения и записи. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deals/741/products/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deals/741/products/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Обяз. | Описание | |------|-----|:--:|:-----:|---------| | `id` | integer | да | | ID позиции | | `productId` | integer | | да | ID товара. Каталог: `GET /v1/products` | | `productName` | string | | | Название товара | | `price` | double | | | Цена | | `quantity` | double | | | Количество | | `discountSum` | double | | | Сумма скидки | | `discountRate` | double | | | Величина скидки (%) | | `discountTypeId` | integer | | | Тип скидки | | `taxRate` | double | | | Налог (%) | | `taxIncluded` | char | | | Налог включён в цену (`Y`/`N`) | | `priceExclusive` | double | да | | Цена без налога со скидкой | | `priceNetto` | double | да | | Цена нетто | | `priceBrutto` | double | да | | Цена брутто | | `measureCode` | integer | | | Код единицы измерения | | `measureName` | string | | | Единица измерения | | `customized` | char | | | Изменён (`Y`/`N`) | | `sort` | integer | | | Сортировка | | `type` | integer | да | | Тип | | `storeId` | integer | да | | ID склада | | `ownerId` | integer | | да | ID владельца (сделки) | | `ownerType` | string | | да | Тип владельца | ## Пример ответа ```json { "success": true, "data": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "ownerId": { "type": "integer", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "ID владельца" }, "ownerType": { "type": "string", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "Тип владельца" }, "productId": { "type": "integer", "isRequired": true, "isReadOnly": false, "title": "Товар" }, "productName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название товара" }, "price": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Цена" }, "priceExclusive": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "Цена без налога со скидкой" }, "priceNetto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_NETTO" }, "priceBrutto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_BRUTTO" }, "quantity": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Количество" }, "discountTypeId": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Тип скидки" }, "discountRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Величина скидки" }, "discountSum": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Сумма скидки" }, "taxRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Налог" }, "taxIncluded": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Налог включен в цену" }, "customized": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Изменен" }, "measureCode": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Код единицы измерения" }, "measureName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Единица измерения" }, "sort": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Сортировка" }, "type": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "TYPE" }, "storeId": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "STORE_ID" } } } ``` ## Пример ответа при ошибке 404 — сделка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/deals/products-get) — получить товары сделки - [Добавить товар](/docs/entities/deals/products-add) — добавить позицию - [Установить товары](/docs/entities/deals/products-set) — заменить все позиции - [Поля сделки](/docs/entities/deals/fields) — описание полей самой сделки --- # Deals: Products Get ## Товарные позиции сделки `GET /v1/deals/:id/products` Возвращает список товарных позиций, привязанных к сделке. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/deals/741/products" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/deals/741/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Товаров:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив товарных позиций | | `data[].productId` | number | ID товара. Каталог: `GET /v1/products` | | `data[].productName` | string | Название товара | | `data[].price` | number | Цена за единицу | | `data[].quantity` | number | Количество | | `data[].discount` | number | Сумма скидки | | `data[].taxRate` | number/null | Ставка налога (%) | | `data[].taxIncluded` | boolean | Налог включён в цену | Показаны основные поля. Полный список (20 полей, включая priceAccount, measureCode и др.): [Поля товаров](/docs/entities/deals/products-fields). ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 1000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 404 — сделка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Установить товары](/docs/entities/deals/products-set) — заменить товарные позиции - [Получить сделку](/docs/entities/deals/get) — основные данные сделки - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Products Get Single ## Получить товар из сделки `GET /v1/deals/:id/products/:rowId` Возвращает одну товарную позицию сделки по ID строки. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/deals/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/deals/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Цена:', data.price) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID товарной строки | | `data.productId` | number | ID товара из каталога | | `data.productName` | string | Название товара | | `data.price` | number | Цена за единицу | | `data.quantity` | number | Количество | | `data.discount` | number | Сумма скидки | | `data.discountRate` | number | Процент скидки | | `data.discountTypeId` | number | Тип скидки (1 — сумма, 2 — процент) | | `data.taxRate` | number \| null | Ставка налога (%) | | `data.taxIncluded` | boolean | Налог включён в цену | | `data.priceExclusive` | number | Цена без скидки | | `data.priceNetto` | number | Цена нетто | | `data.priceBrutto` | number | Цена брутто | | `data.priceAccount` | number | Цена в валюте учёта | | `data.measureCode` | number | Код единицы измерения | | `data.measureName` | string | Название единицы измерения | | `data.sort` | number | Сортировка | ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "День добрый!", "price": 5000, "priceAccount": 5000, "priceExclusive": 5000, "priceNetto": 5000, "priceBrutto": 5000, "quantity": 3, "discountTypeId": 2, "discountRate": 0, "discount": 0, "taxRate": null, "taxIncluded": false, "customized": "Y", "measureCode": 796, "measureName": "шт", "sort": 0, "xmlId": "sale_basket_995", "type": 1 } } ``` ## Пример ответа при ошибке 404 — сделка или товарная строка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка или товарная строка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/deals/products-get) — получить все позиции - [Обновить товар](/docs/entities/deals/products-update) — обновить позицию - [Добавить товар](/docs/entities/deals/products-add) — добавить позицию - [Удалить товар](/docs/entities/deals/products-delete) — удалить позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Deals: Products Set ## Установить товары сделки `PUT /v1/deals/:id/products` Устанавливает товарные позиции сделки. Полностью заменяет текущий список — передайте все нужные позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `items` | array | да | Массив товарных позиций | | `items[].productId` | number | да | ID товара. Каталог: `GET /v1/products` | | `items[].price` | number | да | Цена за единицу | | `items[].quantity` | number | да | Количество | | `items[].discount` | number | нет | Сумма скидки | | `items[].taxRate` | number | нет | Ставка налога (%) | | `items[].taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/deals/741/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### curl — OAuth-приложение ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/deals/741/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив установленных позиций с полями productId, productName, price, quantity, discount, taxRate, taxIncluded | Массив установленных позиций с полями `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 25000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false }, { "productId": 5, "productName": "Установка и настройка", "price": 5000, "quantity": 1, "discount": 500, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 400 — неверный формат: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "items must be an array" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `items` не является массивом | | 404 | `ENTITY_NOT_FOUND` | Сделка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Полная замена:** PUT заменяет весь список товаров. Чтобы добавить позицию — сначала получите текущие (`GET`), добавьте новую в массив, отправьте всё (`PUT`). ## Смотрите также - [Товарные позиции](/docs/entities/deals/products-get) — получить текущий список - [Получить сделку](/docs/entities/deals/get) — основные данные сделки - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Products Update ## Обновить товар сделки `PATCH /v1/deals/:id/products/:rowId` Обновляет товарную позицию сделки. Передайте только изменяемые поля. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сделки | | `rowId` (path) | number | да | ID товарной позиции (из ответа list или add, не productId из каталога) | ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `price` | number | Цена за единицу | | `quantity` | number | Количество | | `productId` | number | ID товара. Каталог: `GET /v1/products` | | `discount` | number | Сумма скидки | | `taxRate` | number | Ставка налога (%) | | `taxIncluded` | boolean | Налог включён в цену | | `sort` | number | Сортировка | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/deals/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/deals/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() console.log('Обновлено:', data.price, 'x', data.quantity) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() ``` ## Поля ответа Обновлённый объект товарной позиции: `id`, `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "Серверное оборудование", "price": 9999, "quantity": 10, "discount": 0, "taxRate": null, "taxIncluded": false } } ``` ## Пример ответа при ошибке 404 — позиция не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Позиция не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить товар](/docs/entities/deals/products-get-single) — получение одной позиции - [Получить товары](/docs/entities/deals/products-get) — список всех позиций - [Добавить товар](/docs/entities/deals/products-add) — добавление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Search ## Поиск сделок `POST /v1/deals/search` Поиск сделок с фильтрами и авто-пагинацией. Аналогичен `GET /v1/deals` с фильтрами, но через POST — удобнее для сложных запросов с большим количеством условий. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/deals/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[stageId]=NEW` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "createdAt": "desc" }` | | `select` | string[] | — | Выборка полей: `["id", "title", "amount"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deals/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "stageId": "NEW" }, "limit": 10, "order": { "amount": "desc" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/deals/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "stageId": "NEW" }, "limit": 10, "order": { "amount": "desc" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { stageId: 'NEW' }, limit: 10, order: { amount: 'desc' }, }), }) const { success, data } = await res.json() console.log('Найдено:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { stageId: 'NEW' }, limit: 10, order: { amount: 'desc' }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив сделок (все поля — см. [Поля](/docs/entities/deals/fields)) | URL карточки любой сделки из массива `data` — её `id`: ``` https://.bitrix24.ru/crm/deal/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 3865, "title": "Шаблончик", "amount": 0, "currency": "RUB", "stageId": "NEW", "categoryId": 0, "assignedById": 29, "createdAt": "2021-01-13T13:52:44.000Z" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Отчёты по закрытым сделкам фильтруются по `closedAt`.** Дата закрытия сделки — поле `closedAt` (ISO 8601 с учётом часового пояса портала), заполняется при переходе сделки в финальную стадию. Имя поля именно `closedAt` — не `closedDate`. Для отчёта «выиграно/проиграно за период» отбирайте по диапазону `closedAt`: ```json { "filter": { "closedAt": { "$gte": "2026-01-01", "$lte": "2026-01-31T23:59:59" } } } ``` Чтобы разделить выигранные и проигранные, добавьте к фильтру стадию (`stageId`); идентификаторы финальных стадий воронки — `GET /v1/statuses?filter[entityId]=DEAL_STAGE`. ## Смотрите также - [Список сделок](/docs/entities/deals/list) — GET-запрос с query-параметрами (для простых фильтров) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Deals: Update ## Обновить сделку `PATCH /v1/deals/:id` Обновляет поля существующей сделки. Передайте только изменяемые поля. Полный список в [справочнике полей](/docs/entities/deals/fields), включая пользовательские (`ufCrm_*`). ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `stageId` | string | Стадия воронки. Список: `GET /v1/statuses?filter[entityId]=DEAL_STAGE` | | `amount` | number | Сумма сделки | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `title` | string | Название | | `closedAt` | datetime | Дата закрытия | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/deals/741" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stageId": "WON", "amount": 75000 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/deals/741" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "stageId": "WON", "amount": 75000 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'WON', amount: 75000, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/deals/741', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'WON', amount: 75000, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект сделки со всеми полями — см. [Поля](/docs/entities/deals/fields) | Обновлённый объект сделки со всеми полями — см. [Поля сделки](/docs/entities/deals/fields). ## Пример ответа ```json { "success": true, "data": { "id": 741, "title": "Поставка оборудования", "amount": 75000, "currency": "RUB", "stageId": "WON", "categoryId": 0, "assignedById": 1, "updatedAt": "2026-04-14T09:15:00.000Z", "entityTypeId": 2 } } ``` ## Пример ответа при ошибке 404 — сделка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сделка не найдена | | 403 | `ACCESS_DENIED` | Нет доступа к сделке | | 400 | `INVALID_REQUEST` | Невалидные поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить сделку](/docs/entities/deals/get) — текущие значения полей - [Поля сделки](/docs/entities/deals/fields) — какие поля можно изменять - [Batch](/docs/batch) — массовое обновление сделок - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Departments: Create ## Создать отдел `POST /v1/departments` Создаёт новый отдел в дереве организационной структуры портала. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `name` | string | да | Название отдела | | `parentId` | number | да | ID родительского отдела. Список родителей: [`GET /v1/departments`](./list.md). Для отдела верхнего уровня используйте `parentId: 1` | | `headId` | number | | ID руководителя отдела. Источник: [`GET /v1/users`](/docs/entities/users) | | `sort` | number | | Порядок отдела среди соседей (меньшее значение — выше в списке). По умолчанию `500` | Создать второй отдел верхнего уровня (без `parentId` или с `parentId: 0`) нельзя — портал поддерживает только один корневой отдел. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/departments" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Коммерческий отдел", "parentId": 1, "headId": 99, "sort": 500 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/departments" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Коммерческий отдел", "parentId": 1, "headId": 99, "sort": 500 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Коммерческий отдел', parentId: 1, headId: 99, sort: 500, }), }) const { success, data } = await res.json() console.log('Department ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Коммерческий отдел', parentId: 1, headId: 99, sort: 500, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного отдела | | `name` | string | Название | | `parentId` | number | ID родительского отдела | | `headId` | number | ID руководителя (если указан при создании) | | `sort` | number | Порядок сортировки | ## Пример ответа ```json { "success": true, "data": { "id": 189, "name": "Коммерческий отдел", "sort": 500, "parentId": 1, "headId": 99 } } ``` ## Пример ответа при ошибке 422 — не указано обязательное поле `name`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Не введено название раздела." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Не указан `name`, либо попытка создать второй корневой отдел, либо `headId` ссылается на несуществующего сотрудника | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `department` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список отделов](/docs/entities/departments/list) — посмотреть текущее дерево перед созданием - [Поля отдела](/docs/entities/departments/fields) — какие поля можно передавать - [Сотрудники](/docs/entities/users) — найти руководителя - [Batch](/docs/batch) — массовое создание отделов --- # Departments: Delete ## Удалить отдел `DELETE /v1/departments/:id` Удаляет отдел по ID. Отдел с дочерними отделами или закреплёнными сотрудниками удалить нельзя — `DELETE` вернёт HTTP 422 `BITRIX_ERROR`. Перед удалением такого отдела перенесите дочерние отделы и сотрудников. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID отдела | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/departments/189" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/departments/189" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/189', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Отдел удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/189', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — отдел не найден или содержит дочерние отделы/сотрудников: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Department not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Отдел не найден или удаление запрещено: внутри есть дочерние отделы либо закреплённые сотрудники | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `department` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Перед удалением нужно очистить отдел.** Отдел с дочерними отделами или закреплёнными сотрудниками `DELETE` не удаляет — возвращает HTTP 422 `BITRIX_ERROR`. Порядок действий: перенести или удалить дочерние отделы через [`PATCH /v1/departments/:id`](./update.md) либо [`DELETE /v1/departments/:id`](./delete.md), затем переназначить сотрудников через [`PATCH /v1/users/:id`](/docs/entities/users) с указанием нового `departmentId` (массив ID отделов), и только после этого вызвать `DELETE` для пустого отдела. ## Смотрите также - [Список отделов](/docs/entities/departments/list) — посмотреть дочерние отделы перед удалением - [Обновить отдел](/docs/entities/departments/update) — перенос дочерних отделов - [Сотрудники](/docs/entities/users) — переназначение сотрудников - [Batch](/docs/batch) — массовое удаление --- # Departments: Fields ## Поля отдела `GET /v1/departments/fields` Возвращает справочник полей отдела с типами и признаком «только для чтения», а также список операций, доступных в [`POST /v1/batch`](/docs/batch). ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/departments/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/departments/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) console.log('Доступные batch-операции:', data.batch) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | Идентификатор отдела | | `name` | string | | Название отдела | | `parentId` | number | | ID родительского отдела. Для отдела верхнего уровня указывается `1` (виртуальный корень дерева). Источник: [`GET /v1/departments`](./list.md) | | `headId` | number | | ID руководителя отдела. Источник: [`GET /v1/users`](/docs/entities/users) | | `sort` | number | | Порядок отдела среди соседей (целое число, по возрастанию) | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false }, "parentId": { "type": "number", "readonly": false }, "headId": { "type": "number", "readonly": false }, "sort": { "type": "number", "readonly": false } }, "batch": ["create", "update", "delete"] } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'department' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `department` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать отдел](/docs/entities/departments/create) — какие поля передавать - [Обновить отдел](/docs/entities/departments/update) — какие поля можно изменять - [Список отделов](/docs/entities/departments/list) — фильтрация по этим полям - [Batch](/docs/batch) — массовые операции `create`, `update`, `delete` - [Entity API](/docs/entity-api) — select для выборки нужных полей --- # Departments: Get ## Получить отдел `GET /v1/departments/:id` Возвращает один отдел по идентификатору со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID отдела | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/departments/47" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/departments/47" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/47', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Отдел:', data.name, '— руководитель ID', data.headId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/47', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект отдела со всеми полями — см. [Поля отдела](/docs/entities/departments/fields). ## Пример ответа ```json { "success": true, "data": { "id": 47, "name": "Коммерческий отдел", "sort": 500, "parentId": 1, "headId": 99 } } ``` ## Пример ответа при ошибке 404 — отдел не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "department 9999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Отдел с таким ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `department` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Поля отдела](/docs/entities/departments/fields) — все поля - [Обновить отдел](/docs/entities/departments/update) — изменение полей - [Список отделов](/docs/entities/departments/list) — поиск с фильтрами - [Сотрудники](/docs/entities/users) — найти руководителя или сотрудников отдела --- # Departments: List ## Список отделов `GET /v1/departments` Возвращает список отделов портала с поддержкой фильтрации и выборки полей. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Vibe автоматически собирает несколько страниц у Битрикс24 | | `select` | string | — | Выборка полей: `?select=id,name`. Возвращаются только перечисленные поля | | `filter` | object | — | Фильтрация по полям `GET /v1/departments/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[parentId]=1` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/departments?filter[parentId]=1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/departments?filter[parentId]=1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments?filter[parentId]=1', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} отделов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments?filter[parentId]=1', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив отделов (см. [Поля отдела](/docs/entities/departments/fields)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 47, "name": "Коммерческий отдел", "sort": 500, "parentId": 1, "headId": 99 }, { "id": 107, "name": "Отдел разработки", "sort": 600, "parentId": 1, "headId": 1 } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'department' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `department` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Параметры `order` и `offset` не применяются.** Параметр `order` принимается без ошибки, но порядок результата не меняется — выборка возвращается в фиксированном порядке. Параметр `offset` тоже принимается, но всегда возвращается выборка с начала. Для больших порталов запрашивайте всю выборку фильтра и сортируйте на стороне клиента. **Когда использовать search вместо list:** для сложных условий по нескольким полям удобнее [`POST /v1/departments/search`](./search.md) — параметры передаются в теле запроса. ## Смотрите также - [Поиск отделов](/docs/entities/departments/search) — POST-запрос для сложных фильтров - [Получить отдел](/docs/entities/departments/get) — получение одного отдела по ID - [Создать отдел](/docs/entities/departments/create) - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — общие принципы (select, фильтры) - [Batch](/docs/batch) — объединение нескольких запросов --- # Departments: Search ## Поиск отделов `POST /v1/departments/search` Поиск отделов с фильтрами. Аналог `GET /v1/departments` с фильтрами, но через POST — удобнее для сложных запросов с несколькими условиями. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/departments/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `{ "parentId": 1 }` | | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string[] | — | Выборка полей: `["id", "name"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/departments/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "parentId": 1 }, "limit": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/departments/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "parentId": 1 }, "limit": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { parentId: 1 }, limit: 10, }), }) const { success, data, meta } = await res.json() console.log('Найдено:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { parentId: 1 }, limit: 10, }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив отделов (см. [Поля отдела](/docs/entities/departments/fields)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 47, "name": "Коммерческий отдел", "sort": 500, "parentId": 1, "headId": 99 }, { "id": 107, "name": "Отдел разработки", "sort": 600, "parentId": 1, "headId": 1 } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'department' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `department` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Параметры `order` и `offset` не применяются.** Поле `order` в теле запроса принимается без ошибки, но порядок результата не меняется. Поле `offset` тоже принимается, но всегда возвращается выборка с начала. Для больших порталов запрашивайте всю выборку фильтра и сортируйте на стороне клиента. ## Смотрите также - [Список отделов](/docs/entities/departments/list) — GET-запрос для простых фильтров через query-параметры - [Поля отдела](/docs/entities/departments/fields) — какие поля доступны для фильтрации - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких запросов --- # Departments: Update ## Обновить отдел `PATCH /v1/departments/:id` Обновляет поля существующего отдела. Передайте только изменяемые поля. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `name` | string | Название отдела | | `parentId` | number | ID нового родительского отдела — для перемещения отдела в дереве. Должен ссылаться на существующий отдел. Список: [`GET /v1/departments`](./list.md) | | `headId` | number | Новый руководитель. Источник: [`GET /v1/users`](/docs/entities/users) | | `sort` | number | Порядок среди отделов того же уровня | Полный список полей — [Поля отдела](/docs/entities/departments/fields). ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/departments/47" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Коммерческий отдел Запад", "headId": 101 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/departments/47" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Коммерческий отдел Запад", "headId": 101 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/47', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Коммерческий отдел Запад', headId: 101, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/departments/47', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Коммерческий отдел Запад', headId: 101, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект отдела со всеми полями — см. [Поля](/docs/entities/departments/fields) | ## Пример ответа ```json { "success": true, "data": { "id": 47, "name": "Коммерческий отдел Запад", "sort": 500, "parentId": 1, "headId": 101 } } ``` ## Пример ответа при ошибке 404 — отдел не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "department 9999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Отдел не найден | | 422 | `BITRIX_ERROR` | `parentId` ссылается на несуществующий отдел, или `headId` ссылается на несуществующего сотрудника | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `department` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить отдел](/docs/entities/departments/get) — текущие значения полей - [Поля отдела](/docs/entities/departments/fields) — какие поля можно изменять - [Batch](/docs/batch) — массовое обновление отделов --- # Doc Templates: Create ## Создать шаблон `POST /v1/doc-templates` Создаёт шаблон документа из файла `.docx`. Файл передаётся одним из двух способов: - `file` — содержимое `.docx` в виде строки base64; - `fileId` — идентификатор файла, заранее загруженного на Диск. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `name` | string | да | Название шаблона | | `numeratorId` | number | да | Идентификатор нумератора | | `region` | string | да | Регион, например `ru` | | `file` | string | * | Содержимое файла `.docx` в виде строки base64. Альтернатива полю `fileId` | | `fileId` | number | * | Идентификатор файла на Диске. Источник: загрузка через `POST /v1/files/upload`. Альтернатива полю `file` | | `code` | string | нет | Символьный код шаблона | | `active` | string | нет | Активность шаблона: `"Y"` или `"N"` | | `withStamps` | string | нет | Использовать печати и подписи: `"Y"` или `"N"` | | `sort` | number | нет | Индекс сортировки | | `users` | array | нет | Идентификаторы сотрудников, которым доступен шаблон | \* Поля `file` и `fileId` взаимоисключающие: передаётся одно из двух. Чтобы получить `fileId`, загрузите файл `.docx` через `POST /v1/files/upload` — значение `id` из ответа используйте как `fileId`. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/doc-templates" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Шаблон договора", "numeratorId": 1, "region": "ru", "fileId": 9175 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/doc-templates" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Шаблон договора", "numeratorId": 1, "region": "ru", "fileId": 9175 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Шаблон договора', numeratorId: 1, region: 'ru', fileId: 9175, }), }) const { success, data } = await res.json() console.log('ID шаблона:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Шаблон договора', numeratorId: 1, region: 'ru', fileId: 9175, }), }) const { success, data } = await res.json() ``` Альтернатива — передать содержимое файла `.docx` напрямую в поле `file` (base64): ```json { "name": "Шаблон договора", "numeratorId": 1, "region": "ru", "file": "" } ``` ## Поля ответа Возвращается полный объект созданного шаблона. Статус ответа — `201`. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор созданного шаблона | | `name` | string | Название шаблона | | `region` | string | Регион | | `code` | string | Символьный код шаблона | | `active` | string | Активность: `"Y"` или `"N"` | | `moduleId` | string | Идентификатор модуля-источника шаблона | | `numeratorId` | number | Идентификатор нумератора | | `withStamps` | string | Использование печатей и подписей: `"Y"` или `"N"` | | `providers` | object | Сопоставление поставщиков данных шаблона | | `users` | object | Сопоставление идентификаторов пользователей, которым доступен шаблон | | `isDeleted` | boolean | Помечен ли шаблон удалённым | | `sort` | number | Индекс сортировки | | `createTime` | string | Дата создания (ISO 8601) | | `updateTime` | string | Дата последнего изменения (ISO 8601) | | `download` | string | Адрес скачивания собранного документа из шаблона | | `downloadMachine` | string | Адрес скачивания с токеном для программного доступа | ## Пример ответа ```json { "success": true, "data": { "id": 209, "name": "Шаблон договора", "region": "ru", "code": null, "download": "/bitrix/services/main/ajax.php?action=documentgenerator.api.template.download&SITE_ID=s1&id=209", "active": "Y", "moduleId": "rest", "numeratorId": 1, "withStamps": "N", "providers": { "bitrix\\documentgenerator\\dataprovider\\rest": "bitrix\\documentgenerator\\dataprovider\\rest" }, "users": { "U1": "U1" }, "isDeleted": false, "sort": 500, "createTime": "2026-05-12T09:03:38.000Z", "updateTime": "2026-05-12T09:03:38.000Z", "downloadMachine": "https:///rest/1//documentgenerator.api.template.download/?token=" } } ``` ## Пример ответа при ошибке 400 — не передан файл: ```json { "success": false, "error": { "code": "MISSING_FILE_OR_FILE_ID", "message": "POST /v1/doc-templates requires either \"file\" (base64-encoded .docx content) or \"fileId\" (Disk file ID). Neither was provided." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_FILE_OR_FILE_ID` | Не передан ни `file`, ни `fileId` | | 400 | `CONFLICTING_FILE_FIELDS` | Переданы и `file`, и `fileId` | | 400 | `MISSING_REQUIRED_FIELD` | Отсутствует `name`, `numeratorId` или `region` | | 415 | `UNSUPPORTED_MEDIA_TYPE` | Запрос отправлен с `multipart/form-data` | | 413 | `FST_ERR_CTP_BODY_TOO_LARGE` | Тело запроса в формате `multipart/form-data` содержит данные | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `TOKEN_MISSING` | У ключа нет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить шаблон](/docs/entities/doc-templates/get) - [Обновить шаблон](/docs/entities/doc-templates/update) - [Список шаблонов](/docs/entities/doc-templates/list) --- # Doc Templates: Delete ## Удалить шаблон `DELETE /v1/doc-templates/:id` Удаляет шаблон документа по идентификатору. Восстановить удалённый шаблон через API нельзя — при необходимости создайте новый. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор шаблона | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/doc-templates/209" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/doc-templates/209" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/209', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Шаблон удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/209', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Шаблон удалён') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом; признак успеха — код ответа, не содержимое. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — шаблон не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Шаблон не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Шаблона с указанным `id` нет (в том числе повторное удаление) | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `TOKEN_MISSING` | У ключа нет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить шаблон](/docs/entities/doc-templates/get) - [Список шаблонов](/docs/entities/doc-templates/list) - [Создать шаблон](/docs/entities/doc-templates/create) --- # Doc Templates: Fields ## Поля шаблона `GET /v1/doc-templates/fields` Возвращает полную схему полей шаблона документа: имя поля, тип, признак «только для чтения» и обязательность при создании. Поля помечены ★ — обязательны в теле запроса при создании шаблона. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/doc-templates/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/doc-templates/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Всего полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `id` | number | да | ID шаблона | | `name` | `name` | string | | ★ Название шаблона | | `numeratorId` | `numeratorId` | number | | ★ ID нумератора, который присваивает документам порядковые номера | | `region` | `region` | string | | ★ Код региона шаблона, например `ru` или `by` | | `code` | `code` | string | | Системный код шаблона для привязки в коде приложения | | `moduleId` | `moduleId` | string | | Идентификатор модуля-владельца шаблона | | `active` | `active` | string | | Доступность шаблона: `Y` — включён, `N` — выключен | | `bodyType` | `bodyType` | string | | Формат тела документа, например `DOCX` | | `withStamps` | `withStamps` | string | | Печать факсимиле и штампов: `Y` — добавляются, `N` — нет | | `sort` | `sort` | number | | Порядок шаблона в списке: чем меньше значение, тем выше | | `users` | `users` | array | | Идентификаторы сотрудников, которым доступен шаблон. Список: `GET /v1/users` | | `fileId` | `fileId` | number | | ID файла на Диске; загрузка через `POST /v1/files/upload` | | `file` | `file` | string | | Содержимое .docx в base64, принимается при создании | | `isDeleted` | `isDeleted` | boolean | да | Шаблон помечен как удалённый | | `createTime` | `createTime` | datetime | да | Дата создания | | `updateTime` | `updateTime` | datetime | да | Дата изменения | | `provider` | `provider` | string | да | Системный поставщик хранилища, в котором лежит файл шаблона | | `download` | `download` | string | да | Ссылка для скачивания исходного файла шаблона | | `downloadMachine` | `downloadMachine` | string | да | Ссылка для скачивания файла по машинному доступу без авторизации в браузере | | `providers` | `providers` | object | да | Перечень доступных поставщиков хранилищ с их настройками | ★ — поля `name`, `numeratorId`, `region` обязательны в теле запроса при создании шаблона. ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false, "required": true }, "numeratorId": { "type": "number", "readonly": false, "required": true }, "region": { "type": "string", "readonly": false, "required": true }, "code": { "type": "string", "readonly": false }, "moduleId": { "type": "string", "readonly": false }, "active": { "type": "string", "readonly": false }, "bodyType": { "type": "string", "readonly": false }, "withStamps": { "type": "string", "readonly": false }, "sort": { "type": "number", "readonly": false }, "users": { "type": "array", "readonly": false }, "fileId": { "type": "number", "readonly": false }, "file": { "type": "string", "readonly": false }, "isDeleted": { "type": "boolean", "readonly": true }, "createTime": { "type": "datetime", "readonly": true }, "updateTime": { "type": "datetime", "readonly": true }, "provider": { "type": "string", "readonly": true }, "download": { "type": "string", "readonly": true }, "downloadMachine": { "type": "string", "readonly": true }, "providers": { "type": "object", "readonly": true } } } } ``` ## Пример ответа при ошибке 403 — у ключа нет нужного скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'documentgenerator' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключу не хватает скоупа `documentgenerator` | | 401 | `TOKEN_MISSING` | у ключа нет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать шаблон](/docs/entities/doc-templates/create) - [Список шаблонов](/docs/entities/doc-templates/list) --- # Doc Templates: Get ## Получить шаблон `GET /v1/doc-templates/:id` Возвращает один шаблон документа по идентификатору. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор шаблона | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/doc-templates/209" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/doc-templates/209" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/209', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Шаблон:', data.name) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/209', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект шаблона | | `data.id` | number | Идентификатор шаблона | | `data.name` | string | Название | | `data.region` | string | Регион | | `data.code` | string \| null | Системный код шаблона | | `data.active` | string | Доступность: `Y` / `N` | | `data.moduleId` | string | Модуль-источник шаблона | | `data.numeratorId` | number | Идентификатор нумератора | | `data.withStamps` | string | Печати и подписи: `Y` / `N` | | `data.sort` | number | Порядок в списке | | `data.users` | object | Сопоставление идентификаторов сотрудников, которым доступен шаблон | | `data.providers` | object | Поставщики данных шаблона | | `data.isDeleted` | boolean | Помечен ли шаблон удалённым | | `data.createTime` | string | Дата создания (ISO 8601) | | `data.updateTime` | string | Дата изменения (ISO 8601) | | `data.download` | string | Адрес скачивания документа | | `data.downloadMachine` | string | Адрес скачивания для программного доступа | Полная схема полей шаблона — [Поля шаблона](./fields.md). ## Пример ответа ```json { "success": true, "data": { "id": 209, "name": "Шаблон договора", "region": "ru", "code": null, "download": "/bitrix/services/main/ajax.php?action=documentgenerator.api.template.download&SITE_ID=s1&id=209", "active": "Y", "moduleId": "rest", "numeratorId": 1, "withStamps": "N", "providers": { "bitrix\\documentgenerator\\dataprovider\\rest": "bitrix\\documentgenerator\\dataprovider\\rest" }, "users": { "U1": "U1" }, "isDeleted": false, "sort": 500, "createTime": "2026-05-12T09:03:38.000Z", "updateTime": "2026-05-12T09:03:38.000Z", "downloadMachine": "https:///rest/1//documentgenerator.api.template.download/?token=" } } ``` ## Пример ответа при ошибке 404 — шаблон не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Шаблон не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Шаблона с указанным `id` нет (сообщение «Шаблон не найден») | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `TOKEN_MISSING` | У ключа нет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список шаблонов](/docs/entities/doc-templates/list) - [Обновить шаблон](/docs/entities/doc-templates/update) - [Поля шаблона](/docs/entities/doc-templates/fields) --- # Doc Templates: List ## Список шаблонов `GET /v1/doc-templates` Возвращает список шаблонов документов портала с поддержкой фильтрации, выборки полей, сортировки и пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям шаблона. Список полей — `GET /v1/doc-templates/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[active]=Y` | | `select` | string | — | Выборка полей: `?select=id,name,region` | | `order` | object | — | Сортировка по полю: `?order[sort]=asc` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Смещение для пагинации | Для `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 на стороне сервера. Максимум — 5000 записей за вызов. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/doc-templates?limit=10&filter[active]=Y" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/doc-templates?limit=10&filter[active]=Y" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates?limit=10&filter[active]=Y', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} шаблонов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates?limit=10&filter[active]=Y', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив шаблонов | | `data[].id` | number | Идентификатор шаблона | | `data[].name` | string | Название | | `data[].active` | string | Доступность: `Y` / `N` | | `data[].code` | string \| null | Системный код шаблона | | `data[].region` | string | Регион | | `data[].sort` | number | Порядок в списке | | `data[].createTime` | string | Дата создания (ISO 8601) | | `data[].updateTime` | string | Дата изменения (ISO 8601) | | `data[].createdBy` | string | Идентификатор создавшего сотрудника | | `data[].updatedBy` | string \| null | Идентификатор изменившего сотрудника | | `data[].moduleId` | string | Модуль-источник шаблона | | `data[].fileId` | number | Идентификатор файла на Диске | | `data[].bodyType` | string | Формат тела документа | | `data[].numeratorId` | number | Идентификатор нумератора | | `data[].withStamps` | string | Печати и подписи: `Y` / `N` | | `data[].productsTableVariant` | string | Вариант таблицы товаров в документе | | `data[].isDeleted` | boolean | Помечен ли шаблон удалённым | | `data[].isDefault` | string | Шаблон по умолчанию: `Y` / `N` | | `data[].users` | array | Идентификаторы сотрудников, которым доступен шаблон | | `data[].download` | string | Адрес скачивания документа | | `data[].downloadMachine` | string | Адрес скачивания для программного доступа | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | Полная схема полей шаблона — [Поля шаблона](./fields.md). ## Пример ответа ```json { "success": true, "data": [ { "id": 209, "active": "Y", "name": "Шаблон договора", "code": null, "region": "ru", "sort": 500, "createTime": "2026-05-12T09:03:38.000Z", "updateTime": "2026-05-12T09:03:38.000Z", "createdBy": "1", "updatedBy": null, "moduleId": "rest", "fileId": 9175, "bodyType": "Bitrix\\DocumentGenerator\\Body\\Docx", "numeratorId": 1, "withStamps": "N", "productsTableVariant": "", "isDeleted": false, "isDefault": "N", "users": ["U1"], "download": "/bitrix/services/main/ajax.php?action=documentgenerator.api.template.download&SITE_ID=s1&id=209", "downloadMachine": "https:///rest/1//documentgenerator.api.template.download/?token=" }, { "id": 211, "active": "Y", "name": "Шаблон счёта", "code": null, "region": "ru", "sort": 500, "createTime": "2026-05-12T09:04:38.000Z", "updateTime": "2026-05-12T09:04:38.000Z", "createdBy": "1", "updatedBy": null, "moduleId": "rest", "fileId": 5901, "bodyType": "Bitrix\\DocumentGenerator\\Body\\Docx", "numeratorId": 1, "withStamps": "N", "productsTableVariant": "", "isDeleted": false, "isDefault": "N", "users": ["U1"], "download": "/bitrix/services/main/ajax.php?action=documentgenerator.api.template.download&SITE_ID=s1&id=211", "downloadMachine": "https:///rest/1//documentgenerator.api.template.download/?token=" } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю. Сообщение перечисляет доступные для фильтрации поля: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'bogusField' for entity 'doc-templates'. Available: id, name, numeratorId, region, code, moduleId, active, bodyType, withStamps, sort, users, fileId, file, isDeleted, createTime, updateTime, provider, download, downloadMachine, providers" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по несуществующему полю; сообщение перечисляет доступные поля | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `TOKEN_MISSING` | У ключа нет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Сортировка по несуществующему полю.** Параметр `order` по полю, которого нет, не вызывает ошибку — запрос отрабатывает со статусом `200`, а неизвестное поле сортировки пропускается. ## Смотрите также - [Получить шаблон](/docs/entities/doc-templates/get) - [Поиск шаблонов](/docs/entities/doc-templates/search) - [Поля шаблона](/docs/entities/doc-templates/fields) - [Синтаксис фильтрации](/docs/filtering) --- # Doc Templates: Search ## Поиск шаблонов `POST /v1/doc-templates/search` Возвращает шаблоны документов портала по фильтру, переданному в теле запроса. Поиск рассчитан на большие выборки с разбиением по датам; для выборок до 5000 записей используйте `GET /v1/doc-templates` с параметрами в строке запроса. ## Поля запроса (body) | Поле | Тип | По умолч. | Описание | |------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям шаблона. Список полей — `GET /v1/doc-templates/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `{"filter": {"active": "Y"}}` | | `select` | string[] | — | Выборка полей: `["id", "name", "region"]` | | `sort` | object | — | Сортировка по полю: `{"sort": {"id": "desc"}}` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Смещение для пагинации | | `autoWindow` | boolean | `true` | Разбиение выборки по датам при фильтре с полями `createTime` / `updateTime`. Передайте `false`, чтобы отключить разбиение | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/doc-templates/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "region": "ru", "active": "Y" }, "limit": 10, "select": ["id", "name", "region", "active"] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/doc-templates/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "region": "ru", "active": "Y" }, "limit": 10, "select": ["id", "name", "region", "active"] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { region: 'ru', active: 'Y' }, limit: 10, select: ['id', 'name', 'region', 'active'], }), }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} шаблонов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { region: 'ru', active: 'Y' }, limit: 10, select: ['id', 'name', 'region', 'active'], }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив шаблонов | | `data[].id` | number | Идентификатор шаблона | | `data[].name` | string | Название | | `data[].active` | string | Доступность: `Y` / `N` | | `data[].code` | string \| null | Системный код шаблона | | `data[].region` | string | Регион | | `data[].sort` | number | Порядок в списке | | `data[].createTime` | string | Дата создания (ISO 8601) | | `data[].updateTime` | string | Дата изменения (ISO 8601) | | `data[].createdBy` | string | Идентификатор создавшего сотрудника | | `data[].updatedBy` | string \| null | Идентификатор изменившего сотрудника | | `data[].moduleId` | string | Модуль-источник шаблона | | `data[].fileId` | number | Идентификатор файла на Диске | | `data[].bodyType` | string | Формат тела документа | | `data[].numeratorId` | number | Идентификатор нумератора | | `data[].withStamps` | string | Печати и подписи: `Y` / `N` | | `data[].productsTableVariant` | string | Вариант таблицы товаров в документе | | `data[].isDeleted` | boolean | Помечен ли шаблон удалённым | | `data[].isDefault` | string | Шаблон по умолчанию: `Y` / `N` | | `data[].users` | array | Идентификаторы сотрудников, которым доступен шаблон | | `data[].download` | string | Адрес скачивания документа | | `data[].downloadMachine` | string | Адрес скачивания для программного доступа | | `meta.total` | number | Количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | | `meta.durationMs` | number | Время выполнения запроса на стороне сервера, миллисекунды | | `meta.autoWindowed` | boolean | Присутствует, когда выборка разбита по датам | | `meta.windowCount` | number | Количество подзапросов при разбиении по датам | Полная схема полей шаблона — [Поля шаблона](./fields.md). ## Пример ответа ```json { "success": true, "data": [ { "id": 209, "active": "Y", "name": "Шаблон договора", "code": null, "region": "ru", "sort": 500, "createTime": "2026-05-12T09:03:38.000Z", "updateTime": "2026-05-12T09:03:38.000Z", "createdBy": "1", "updatedBy": null, "moduleId": "rest", "fileId": 9175, "bodyType": "Bitrix\\DocumentGenerator\\Body\\Docx", "numeratorId": 1, "withStamps": "N", "productsTableVariant": "", "isDeleted": false, "isDefault": "N", "users": ["U1"], "download": "/bitrix/services/main/ajax.php?action=documentgenerator.api.template.download&SITE_ID=s1&id=209", "downloadMachine": "https:///rest/1//documentgenerator.api.template.download/?token=" }, { "id": 211, "active": "Y", "name": "Шаблон счёта", "code": null, "region": "ru", "sort": 500, "createTime": "2026-05-12T09:04:38.000Z", "updateTime": "2026-05-12T09:04:38.000Z", "createdBy": "1", "updatedBy": null, "moduleId": "rest", "fileId": 5901, "bodyType": "Bitrix\\DocumentGenerator\\Body\\Docx", "numeratorId": 1, "withStamps": "N", "productsTableVariant": "", "isDeleted": false, "isDefault": "N", "users": ["U1"], "download": "/bitrix/services/main/ajax.php?action=documentgenerator.api.template.download&SITE_ID=s1&id=211", "downloadMachine": "https:///rest/1//documentgenerator.api.template.download/?token=" } ], "meta": { "total": 2, "hasMore": false, "durationMs": 799 } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю. Сообщение перечисляет доступные для фильтрации поля: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'bogusField' for entity 'doc-templates'. Available: id, name, numeratorId, region, code, moduleId, active, bodyType, withStamps, sort, users, fileId, file, isDeleted, createTime, updateTime, provider, download, downloadMachine, providers" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по несуществующему полю; сообщение перечисляет доступные поля | | 400 | `UNKNOWN_SORT_FIELD` | Сортировка по несуществующему полю в `sort`; сообщение перечисляет доступные поля | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `TOKEN_MISSING` | У ключа нет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Разбиение по датам.** При фильтре с полями `createTime` или `updateTime` выборка делится на подзапросы по интервалам дат, и в `meta` появляются `autoWindowed` и `windowCount`. Передайте `autoWindow: false`, чтобы выполнить один запрос без разбиения. ## Смотрите также - [Список шаблонов](/docs/entities/doc-templates/list) - [Поля шаблона](/docs/entities/doc-templates/fields) - [Синтаксис фильтрации](/docs/filtering) --- # Doc Templates: Update ## Обновить шаблон `PATCH /v1/doc-templates/:id` Частично обновляет шаблон документа. Передавайте плоско в корне JSON только те поля, которые меняете, — остальные значения сохраняются. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор шаблона | ## Поля запроса (body) | Поле | Тип | Описание | |------|-----|---------| | `name` | string | Название шаблона | | `numeratorId` | number | ID нумератора, который присваивает документам порядковые номера | | `region` | string | Код региона шаблона, например `ru` или `by` | | `code` | string | Системный код шаблона для привязки в коде приложения | | `active` | string | Доступность шаблона: `Y` — включён, `N` — выключен | | `withStamps` | string | Печать факсимиле и штампов: `Y` — добавляются, `N` — нет | | `sort` | number | Порядок шаблона в списке: чем меньше значение, тем выше | | `users` | array | Идентификаторы сотрудников, которым доступен шаблон. Список: `GET /v1/users` | Поля только для чтения (`id`, `createTime`, `updateTime`, `isDeleted`, `download`, `downloadMachine`, `providers`, `provider`) в теле запроса не принимаются. ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/doc-templates/209" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Шаблон договора (ред.)" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/doc-templates/209" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Шаблон договора (ред.)" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/209', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Шаблон договора (ред.)', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/doc-templates/209', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Шаблон договора (ред.)', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Обновлённый шаблон целиком | | `data.id` | number | Идентификатор шаблона | | `data.name` | string | Название | | `data.region` | string | Регион | | `data.code` | string \| null | Системный код шаблона | | `data.active` | string | Доступность: `Y` / `N` | | `data.moduleId` | string | Модуль-источник шаблона | | `data.numeratorId` | number | Идентификатор нумератора | | `data.withStamps` | string | Печати и подписи: `Y` / `N` | | `data.sort` | number | Порядок в списке | | `data.users` | object | Сопоставление идентификаторов сотрудников, которым доступен шаблон | | `data.providers` | object | Поставщики данных шаблона | | `data.isDeleted` | boolean | Помечен ли шаблон удалённым | | `data.createTime` | string | Дата создания (ISO 8601) | | `data.updateTime` | string | Дата изменения (ISO 8601) | | `data.download` | string | Адрес скачивания документа | | `data.downloadMachine` | string | Адрес скачивания для программного доступа | Полная схема полей шаблона — [Поля шаблона](./fields.md). ## Пример ответа ```json { "success": true, "data": { "id": 209, "name": "Шаблон договора (ред.)", "region": "ru", "code": null, "download": "/bitrix/services/main/ajax.php?action=documentgenerator.api.template.download&SITE_ID=s1&id=209&ts=0", "active": "Y", "moduleId": "rest", "numeratorId": 1, "withStamps": "N", "providers": { "bitrix\\documentgenerator\\dataprovider\\rest": "bitrix\\documentgenerator\\dataprovider\\rest" }, "users": { "U1": "U1" }, "isDeleted": false, "sort": 500, "createTime": "2026-05-12T09:03:38.000Z", "updateTime": "2026-05-25T10:00:11.000Z", "downloadMachine": "https:///rest/1//documentgenerator.api.template.download/?token=" } } ``` ## Пример ответа при ошибке 404 — шаблон не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Шаблон не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Шаблона с указанным `id` нет (сообщение «Шаблон не найден») | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `TOKEN_MISSING` | У ключа нет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить шаблон](/docs/entities/doc-templates/get) - [Создать шаблон](/docs/entities/doc-templates/create) - [Поля шаблона](/docs/entities/doc-templates/fields) --- # Documents: Create ## Создать документ `POST /v1/documents` Создаёт документ по шаблону: Битрикс24 формирует файл, подставляя в шаблон значения из провайдера данных. ## Поля запроса (body) Минимум для создания: `templateId`, `providerClassName`, `value`. | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `templateId` | number | ★ | Идентификатор шаблона, по которому формируется документ. Список шаблонов: `GET /v1/doc-templates` | | `providerClassName` | string | ★ | Класс провайдера данных — источник значений для меток шаблона. Например `Bitrix\DocumentGenerator\DataProvider\Rest` | | `value` | string | ★ | Внешний идентификатор объекта-источника, по которому провайдер подставляет значения. Например `ORDER-1024` | | `values` | object | | Значения полей-меток шаблона. Ключ — имя метки, значение — подставляемый текст. Например `{"DocumentNumber":"2026-001"}` | | `fields` | object | | Описание форматирования полей документа | | `stampsEnabled` | boolean | | Подставлять в документ печати и подписи | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/documents \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateId": 53, "providerClassName": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1024", "values": { "DocumentNumber": "2026-001" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/documents \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "templateId": 53, "providerClassName": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1024", "values": { "DocumentNumber": "2026-001" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ templateId: 53, providerClassName: 'Bitrix\\DocumentGenerator\\DataProvider\\Rest', value: 'ORDER-1024', values: { DocumentNumber: '2026-001' }, }), }) const { success, data } = await res.json() console.log('Document ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ templateId: 53, providerClassName: 'Bitrix\\DocumentGenerator\\DataProvider\\Rest', value: 'ORDER-1024', values: { DocumentNumber: '2026-001' }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Созданный документ со всеми полями — см. [Поля документа](/docs/entities/documents/fields) | Поле `provider` в ответе соответствует переданному в запросе `providerClassName`. ## Пример ответа ```json { "success": true, "data": { "id": 51, "title": "Договор поставки 2026-001", "number": "2026-001", "templateId": 53, "provider": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1024", "fileId": 241, "pdfId": 245, "imageId": 243, "createTime": "2026-03-18T17:27:48+03:00", "updateTime": "2026-03-18T17:27:48+03:00", "createdBy": 503, "updatedBy": null, "values": { "DocumentNumber": "2026-001" }, "stampsEnabled": false, "publicUrl": null, "downloadUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getfile&id=51", "pdfUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getpdf&id=51" } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'documentgenerator' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `documentgenerator` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 422 | `BITRIX_ERROR` | Шаблон не найден или недоступен, либо провайдер данных не вернул объект по указанному `value` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список документов](/docs/entities/documents/list) - [Получить документ](/docs/entities/documents/get) - [Шаблоны документов](/docs/entities/doc-templates) - [Entity API](/docs/entity-api) --- # Documents: Delete ## Удалить документ `DELETE /v1/documents/:id` Удаляет документ по идентификатору. Восстановить удалённый документ через API нельзя — создавайте новый при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор документа | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/documents/51" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/documents/51" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/51', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Документ удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/51', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом. Признак успеха — код ответа, не содержимое. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — документ не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Документ не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Документ с таким `id` не найден | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить документ](/docs/entities/documents/get) - [Список документов](/docs/entities/documents/list) - [Entity API](/docs/entity-api) --- # Documents: Fields ## Поля документа `GET /v1/documents/fields` Возвращает полную схему полей документа: имя поля, тип, признак «только для чтения» и обязательность при создании. Поля помечены ★ — обязательны в теле запроса при создании документа. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/documents/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/documents/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Всего полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `id` | number | да | Идентификатор документа | | `title` | `title` | string | | Название документа | | `number` | `number` | string | | Номер документа | | `templateId` | `templateId` | number | | ★ Идентификатор шаблона. Список: `GET /v1/doc-templates` | | `providerClassName` | `providerClassName` | string | | ★ Класс провайдера данных, например `Bitrix\DocumentGenerator\DataProvider\Rest` | | `value` | `value` | string | | ★ Внешний идентификатор объекта-источника, из которого подставляются данные | | `values` | `values` | object | | Значения полей-меток шаблона | | `fields` | `fields` | object | | Описание форматирования полей | | `createTime` | `createTime` | datetime | да | Дата создания | | `updateTime` | `updateTime` | datetime | да | Дата последнего изменения | | `fileId` | `fileId` | number | | Идентификатор файла DOCX | | `pdfId` | `pdfId` | number | | Идентификатор файла PDF | | `imageId` | `imageId` | number | | Идентификатор файла изображения | | `stampsEnabled` | `stampsEnabled` | boolean | | Включены ли печати и подписи | | `provider` | `provider` | string | да | Класс провайдера данных документа | | `downloadUrl` | `downloadUrl` | string | да | Ссылка на скачивание DOCX для пользователя | | `pdfUrl` | `pdfUrl` | string | да | Ссылка на скачивание PDF для пользователя | | `imageUrl` | `imageUrl` | string | да | Ссылка на изображение для пользователя | | `downloadUrlMachine` | `downloadUrlMachine` | string | да | Ссылка на скачивание DOCX для приложения | | `pdfUrlMachine` | `pdfUrlMachine` | string | да | Ссылка на скачивание PDF для приложения | | `imageUrlMachine` | `imageUrlMachine` | string | да | Ссылка на изображение для приложения | | `createdBy` | `createdBy` | number | да | Идентификатор создавшего пользователя. Список: `GET /v1/users` | | `updatedBy` | `updatedBy` | number | да | Идентификатор изменившего пользователя. Список: `GET /v1/users` | | `publicUrl` | `publicUrl` | string | да | Публичная ссылка на документ | ★ — поля `templateId`, `providerClassName`, `value` обязательны в теле запроса при создании документа. ## Пример ответа Показаны 8 из 24 полей. Полный список — в таблице выше. ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "title": { "type": "string", "readonly": false }, "number": { "type": "string", "readonly": false }, "templateId": { "type": "number", "readonly": false, "required": true }, "providerClassName": { "type": "string", "readonly": false, "required": true }, "value": { "type": "string", "readonly": false, "required": true }, "createTime": { "type": "datetime", "readonly": true }, "publicUrl": { "type": "string", "readonly": true } }, "batch": ["create", "update", "delete"] } } ``` Поле `batch` перечисляет операции документа, доступные в [пакетном запросе](/docs/batch). ## Пример ответа при ошибке 403 — у ключа нет нужного скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'documentgenerator' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключу не хватает скоупа `documentgenerator` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список документов](/docs/entities/documents/list) - [Создать документ](/docs/entities/documents/create) - [Справочник сущностей](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) --- # Documents: Get ## Получить документ `GET /v1/documents/:id` Возвращает документ по идентификатору со всеми полями, включая ссылки на готовый файл, PDF и изображение. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор документа | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/documents/51" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/documents/51" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/51', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Документ:', data.title, '—', data.number) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/51', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект документа со всеми полями — см. [Поля документа](/docs/entities/documents/fields) | ## Пример ответа ```json { "success": true, "data": { "id": 51, "title": "Договор поставки 2026-001", "number": "2026-001", "templateId": 53, "provider": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1024", "fileId": 241, "pdfId": 245, "imageId": 243, "createTime": "2026-03-18T17:27:48+03:00", "updateTime": "2026-03-18T17:27:48+03:00", "createdBy": 503, "updatedBy": null, "values": { "DocumentNumber": "2026-001", "ClientName": "ООО «Ромашка»" }, "stampsEnabled": false, "publicUrl": "https://example.bitrix24.ru/~aBcDeF", "downloadUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getfile&id=51", "pdfUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getpdf&id=51", "imageUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getimage&id=51", "downloadUrlMachine": "https://example.bitrix24.ru/rest/documentgenerator.api.document.getfile.json?token=t0k3n", "pdfUrlMachine": "https://example.bitrix24.ru/rest/documentgenerator.api.document.getpdf.json?token=t0k3n", "imageUrlMachine": "https://example.bitrix24.ru/rest/documentgenerator.api.document.getimage.json?token=t0k3n" } } ``` ## Пример ответа при ошибке 404 — документ не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Документ не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Документ с таким `id` не найден | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список документов](/docs/entities/documents/list) - [Обновить документ](/docs/entities/documents/update) - [Поля документа](/docs/entities/documents/fields) - [Entity API](/docs/entity-api) --- # Documents: List ## Список документов `GET /v1/documents` Возвращает список документов с поддержкой фильтрации, сортировки, выбора полей и автоматической пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,title,number` | | `order` | object | — | Сортировка: `?order[id]=desc` | | `filter` | object | — | Фильтрация по полям `GET /v1/documents/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[templateId]=53` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/documents?limit=10&order[id]=desc&filter[templateId]=53" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/documents?limit=10&order[id]=desc&filter[templateId]=53" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents?limit=10&order[id]=desc&filter[templateId]=53', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} документов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents?limit=10&order[id]=desc&filter[templateId]=53', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив документов (все поля элемента — см. [Поля документа](/docs/entities/documents/fields)) | | `meta.total` | number | Количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 51, "title": "Договор поставки 2026-001", "number": "2026-001", "templateId": 53, "provider": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1024", "fileId": 241, "pdfId": 245, "imageId": 243, "createTime": "2026-03-18T17:27:48+03:00", "updateTime": "2026-03-18T17:27:48+03:00", "createdBy": 503, "updatedBy": null, "values": { "DocumentNumber": "2026-001" }, "stampsEnabled": false, "downloadUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getfile&id=51", "pdfUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getpdf&id=51" }, { "id": 52, "title": "Договор поставки 2026-002", "number": "2026-002", "templateId": 53, "provider": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1025", "fileId": 248, "pdfId": 250, "imageId": 249, "createTime": "2026-03-19T10:12:03+03:00", "updateTime": "2026-03-19T10:12:03+03:00", "createdBy": 503, "updatedBy": null, "values": { "DocumentNumber": "2026-002" }, "stampsEnabled": false, "downloadUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getfile&id=52", "pdfUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getpdf&id=52" } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'zzzNope' for entity 'documents'. Available: id, title, number, templateId, providerClassName, value, values, fields, createTime, updateTime, fileId, pdfId, imageId, stampsEnabled, provider, downloadUrl, pdfUrl, imageUrl, downloadUrlMachine, pdfUrlMachine, imageUrlMachine, createdBy, updatedBy, publicUrl" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет у документа. Список полей — `GET /v1/documents/fields` | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности При `limit > 50` Вайбкод запрашивает несколько страниц и собирает все записи в один ответ. За один вызов возвращается не более 5000 записей. При `offset ≥ 2500` для устойчивости запроса используйте `limit ≤ 500`. Для сложных фильтров с множеством условий параметры передаются в теле запроса — `POST /v1/documents/search`. Этот эндпоинт также поддерживает оконный поиск по датам для больших выборок. См. [Поиск документов](/docs/entities/documents/search). ## Смотрите также - [Поиск документов](/docs/entities/documents/search) - [Создать документ](/docs/entities/documents/create) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entity-api) - [Batch-запросы](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Documents: Search ## Поиск документов `POST /v1/documents/search` Возвращает документы по фильтру, переданному в теле запроса. Аналогичен `GET /v1/documents` с фильтрами, но условия отбора передаются в теле запроса — это удобнее для сложных выборок с большим количеством условий. ## Поля запроса (body) | Поле | Тип | По умолч. | Описание | |------|-----|-----------|---------| | `filter` | object | — | Отбор по полям документа.
[Синтаксис фильтрации](/docs/filtering). Пример: `{ "filter": { "templateId": 53 } }` | | `limit` | number | `50` | Количество документов в ответе, до 5000 | | `offset` | number | `0` | Пропустить указанное число документов | | `sort` | object | — | Сортировка: `{ "id": "desc" }`. Допустимы те же поля, что и в `filter` | | `select` | string[] | — | Выборка полей: `["id", "title", "number"]`. В ответе остаются только перечисленные поля и `id` | | `autoWindow` | boolean | `true` | Разбиение выборки по датам при фильтре с полями `createTime` / `updateTime`. Передайте `false`, чтобы отключить разбиение | Имена полей для `filter`, `sort` и `select` — из [Полей документа](/docs/entities/documents/fields). ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/documents/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "templateId": 53 }, "limit": 10, "sort": { "id": "desc" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/documents/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "templateId": 53 }, "limit": 10, "sort": { "id": "desc" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { templateId: 53 }, limit: 10, sort: { id: 'desc' }, }), }) const { data, meta } = await res.json() console.log('Найдено:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { templateId: 53 }, limit: 10, sort: { id: 'desc' }, }), }) const { data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив документов (все поля — см. [Поля документа](/docs/entities/documents/fields)) | | `meta.total` | number | Количество документов, попавших под фильтр | | `meta.hasMore` | boolean | Есть ли документы за пределами `limit` | | `meta.durationMs` | number | Время обработки запроса в миллисекундах | | `meta.autoWindowed` | boolean | Присутствует, когда выборка разбита по датам | | `meta.windowCount` | number | Количество подзапросов при разбиении по датам | ## Пример ответа ```json { "success": true, "data": [ { "id": 51, "title": "Договор поставки 2026-001", "number": "2026-001", "templateId": 53, "provider": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1024", "createTime": "2026-03-18T17:27:48+03:00", "updateTime": "2026-03-18T17:27:48+03:00", "createdBy": 503, "updatedBy": null, "values": { "DocumentNumber": "2026-001" }, "stampsEnabled": false, "pdfUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getpdf&id=51" } ], "meta": { "total": 1, "hasMore": false, "durationMs": 42 } } ``` Когда под фильтр не попал ни один документ, `data` приходит пустым массивом, а `meta.total` равен `0`: ```json { "success": true, "data": [], "meta": { "total": 0, "hasMore": false, "durationMs": 644 } } ``` ## Пример ответа при ошибке 400 — поле в `filter` не входит в список полей документа: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown filter field 'notArealField' for entity 'documents'." } } ``` ## Известные особенности Имя поля в `filter` и `sort` сверяется со списком полей документа до обращения к данным. Неизвестное поле в `filter` возвращает `400 UNKNOWN_FILTER_FIELD`, неизвестное поле в `sort` — `400 UNKNOWN_SORT_FIELD`; в обоих случаях сообщение перечисляет допустимые имена полей. **Разбиение по датам.** При фильтре с полями `createTime` или `updateTime` выборка делится на подзапросы по интервалам дат, и в `meta` появляются `autoWindowed` и `windowCount`. Передайте `autoWindow: false`, чтобы выполнить один запрос без разбиения. ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Поле в `filter` не входит в список полей документа | | 400 | `UNKNOWN_SORT_FIELD` | Поле в `sort` не входит в список полей документа | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список документов](/docs/entities/documents/list) - [Синтаксис фильтрации](/docs/filtering) - [Справочник сущностей](/docs/entity-api) - [Batch-запросы](/docs/batch) --- # Documents: Update ## Обновить документ `PATCH /v1/documents/:id` Обновляет поля существующего документа — передайте только изменяемые. Системные поля (даты, автор, ссылки на файлы) доступны только для чтения. Полный список — в [справочнике полей](/docs/entities/documents/fields). ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название документа | | `number` | string | Номер документа | | `stampsEnabled` | boolean | Печати и подписи на документе | | `values` | object | Значения полей-меток шаблона | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/documents/51" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Договор поставки 2026-001 (ред.)", "stampsEnabled": true }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/documents/51" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Договор поставки 2026-001 (ред.)", "stampsEnabled": true }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/51', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Договор поставки 2026-001 (ред.)', stampsEnabled: true, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/documents/51', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Договор поставки 2026-001 (ред.)', stampsEnabled: true, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект документа со всеми полями — см. [Поля документа](/docs/entities/documents/fields) | ## Пример ответа ```json { "success": true, "data": { "id": 51, "title": "Договор поставки 2026-001 (ред.)", "number": "2026-001", "templateId": 53, "provider": "Bitrix\\DocumentGenerator\\DataProvider\\Rest", "value": "ORDER-1024", "createTime": "2026-03-18T17:27:48+03:00", "updateTime": "2026-03-20T09:14:11+03:00", "createdBy": 503, "updatedBy": 503, "values": { "DocumentNumber": "2026-001" }, "stampsEnabled": true, "publicUrl": "https://example.bitrix24.ru/~aBcDeF", "downloadUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getfile&id=51", "pdfUrl": "https://example.bitrix24.ru/bitrix/services/main/ajax.php?action=documentgenerator.api.document.getpdf&id=51" } } ``` ## Пример ответа при ошибке 404 — документ не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Документ не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Документа с указанным `id` не существует | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `documentgenerator` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить документ](/docs/entities/documents/get) - [Создать документ](/docs/entities/documents/create) - [Поля документа](/docs/entities/documents/fields) - [Entity API](/docs/entity-api) --- # Files: Copyto ## Скопировать файл `POST /v1/files/:id/copyto` Создаёт копию файла в указанной папке. Оригинал остаётся на месте, копия получает новый идентификатор. ## Параметры | Параметр | В | Тип | Обяз. | Описание | |----------|---|-----|:-----:|---------| | `id` | path | number | да | ID файла, который нужно скопировать. Получить через `GET /v1/files` | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `targetFolderId` | number | да | ID папки-назначения. Получить через `GET /v1/folders` | ## Примеры ### curl — личный ключ ```bash curl -X POST \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"targetFolderId": 649}' \ https://vibecode.bitrix24.tech/v1/files/9250/copyto ``` ### curl — OAuth-приложение ```bash curl -X POST \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"targetFolderId": 649}' \ https://vibecode.bitrix24.tech/v1/files/9250/copyto ``` ### JavaScript — личный ключ ```javascript const res = await fetch( 'https://vibecode.bitrix24.tech/v1/files/9250/copyto', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ targetFolderId: 649 }), } ) const body = await res.json() if (!body.success) { console.error(body.error.code, body.error.message) } else { console.log('Копия создана, ID:', body.data.id) } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch( 'https://vibecode.bitrix24.tech/v1/files/9250/copyto', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ targetFolderId: 649 }), } ) const body = await res.json() ``` ## Поля ответа Возвращается объект созданной копии. | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | `true` при успешном копировании | | `data.id` | number | ID созданной копии (отличается от ID оригинала) | | `data.name` | string | Имя файла | | `data.code` | string \| null | Системный код файла | | `data.storageId` | number | ID хранилища | | `data.type` | string | Тип объекта — всегда `"file"` | | `data.folderId` | number | ID папки-назначения | | `data.deletedType` | number | Тип удаления: `0` — не удалён | | `data.globalContentVersion` | number | Глобальная версия содержимого | | `data.fileId` | number | Внутренний идентификатор содержимого файла | | `data.size` | number | Размер в байтах | | `data.createdBy` | number | ID пользователя, создавшего копию | | `data.updatedBy` | number | ID пользователя, обновившего копию | | `data.deletedBy` | number \| null | ID удалившего. У новой копии всегда `null` | | `data.createdAt` | string (ISO 8601) | Дата создания копии | | `data.updatedAt` | string (ISO 8601) | Дата обновления копии | | `data.deletedAt` | string \| null | Дата удаления. У новой копии всегда `null` | | `data.downloadUrl` | string | Прямой URL для скачивания файла | | `data.detailUrl` | string | URL карточки файла в Битрикс24 | ## Пример ответа ```json { "success": true, "data": { "id": 9253, "name": "doc-copy-test.txt", "code": null, "storageId": 1, "type": "file", "folderId": 649, "deletedType": 0, "globalContentVersion": 1, "fileId": 34869, "size": 4, "createdBy": 1, "updatedBy": 1, "deletedBy": null, "createdAt": "2026-05-06T09:35:13.000Z", "updatedAt": "2026-05-06T09:35:13.000Z", "deletedAt": null, "downloadUrl": "https://...", "detailUrl": "https://..." } } ``` ## Пример ответа при ошибке 400 — не передан `targetFolderId`: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "targetFolderId is required." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан обязательный параметр `targetFolderId` | | 400 | `INVALID_PARAMS` | `targetFolderId` не является положительным целым числом | | 400 | `INVALID_ID` | `id` в path не является положительным целым числом | | 400 | `OPERATION_FAILED` | Битрикс24 вернул пустой результат — копирование не выполнено | | 401 | `NO_TOKENS` | Для портала не найдены токены авторизации | | 403 | `SCOPE_MISSING` | У API-ключа отсутствует скоуп `disk` | | 422 | `BITRIX_ERROR` | В папке-назначении уже существует файл с таким именем | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности - **Копия получает новый ID.** Оригинал остаётся в исходной папке без изменений. Идентификатор копии (поле `data.id`) не совпадает с идентификатором оригинала — используйте `data.id` для дальнейшей работы с копией. - **Копирование работает между хранилищами.** В отличие от операции перемещения (`POST /v1/files/:id/moveto`), копирование допустимо даже тогда, когда исходный файл и папка-назначение принадлежат разным хранилищам. - **Конфликт имён.** Если в папке-назначении уже есть файл с таким же именем, операция завершится ошибкой `422`. Переименуйте оригинал или выберите другую папку. ## Смотрите также - [Переместить файл](./moveto.md) - [Загрузить файл](./upload.md) - [Список файлов](./list.md) - [Список папок](/docs/entities/folders) --- # Files: Delete ## Удалить файл `DELETE /v1/files/:id` Перемещает файл в корзину Битрикс24. Файл не удаляется навсегда — его можно восстановить средствами Битрикс24 вручную. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|----------| | `id` (path) | number | да | ID файла. Целое число больше нуля | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/files/3291" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/files/3291" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/3291', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Файл перемещён в корзину') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/3291', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Файл перемещён в корзину') } ``` ## Ответ При успешном перемещении в корзину возвращается HTTP-статус `204 No Content` с пустым телом. Признак успеха — код ответа, не содержимое. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — файл не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Could not find entity with id '99999999'." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|----------| | 404 | `ENTITY_NOT_FOUND` | Файл с указанным ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `disk` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов авторизации | | 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности Операция перемещает файл в корзину Битрикс24 — мягкое удаление. Файл сохраняется в корзине и может быть восстановлен администратором портала через интерфейс Битрикс24. Безвозвратное удаление через API Вайбкода недоступно. ## Смотрите также - [Список файлов](/docs/entities/files/list) - [Получить файл](/docs/entities/files/get) - [Переименовать файл](/docs/entities/files/update) - [Загрузить файл](/docs/entities/files/upload) --- # Files: Download ## Скачать файл `GET /v1/files/:id/download` Скачивает содержимое файла через прокси Вайбкода с автоматической авторизацией. В отличие от поля `downloadUrl` в ответе `GET /v1/files/:id`, этот эндпоинт добавляет авторизацию при каждом вызове — токен не нужно извлекать и подставлять вручную. Ответ — бинарный поток с заголовком `Content-Disposition`, браузеры предлагают сохранить файл автоматически. ## Параметры | Параметр | В | Тип | Обяз. | Описание | |----------|---|-----|:-----:|----------| | `id` | path | number | да | ID файла. Получить: `GET /v1/files` или `GET /v1/files/:id` | Тело запроса пустое. ## Примеры ### curl — личный ключ ```bash # Сохранить в файл с исходным именем из заголовка Content-Disposition curl -OJ -H "X-Api-Key: YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/files/205/download # Указать имя файла явно curl -H "X-Api-Key: YOUR_API_KEY" \ https://vibecode.bitrix24.tech/v1/files/205/download \ -o myfile.pdf ``` ### curl — OAuth-приложение ```bash curl -OJ \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ https://vibecode.bitrix24.tech/v1/files/205/download ``` ### JavaScript — личный ключ ```javascript const fileId = 205 const res = await fetch( `https://vibecode.bitrix24.tech/v1/files/${fileId}/download`, { headers: { 'X-Api-Key': 'YOUR_API_KEY' } } ) if (!res.ok) { const body = await res.json() throw new Error(body.error?.code ?? String(res.status)) } // Сохранить blob в браузере const blob = await res.blob() const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = res.headers.get('Content-Disposition')?.match(/filename="(.+?)"/)?.[1] ?? 'file' a.click() URL.revokeObjectURL(url) ``` ### JavaScript — OAuth-приложение ```javascript const fileId = 205 const res = await fetch( `https://vibecode.bitrix24.tech/v1/files/${fileId}/download`, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, } ) if (!res.ok) { const body = await res.json() throw new Error(body.error?.code ?? String(res.status)) } const blob = await res.blob() ``` ## Заголовки ответа При успехе возвращается бинарное содержимое файла (HTTP 200). Секции `## Поля ответа` нет — тело ответа не является JSON. | Заголовок | Пример значения | Описание | |-----------|-----------------|----------| | `Content-Type` | `application/pdf` | Тип содержимого. Зависит от типа файла: `text/plain`, `image/png`, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` и т. д. | | `Content-Disposition` | `attachment; filename="report.pdf"` | Имя файла для сохранения. Браузеры используют его автоматически при скачивании | | `Content-Length` | `31232` | Размер файла в байтах. Передаётся, если известен из метаданных | ## Пример ответа при ошибке 404 — файл не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Could not find entity with id '99999999'." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|----------| | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный или просроченный ключ | | 403 | `SCOPE_MISSING` | Ключу не хватает скоупа `disk` | | 404 | `ENTITY_NOT_FOUND` | Файла с таким `id` не существует или он недоступен ключу | | 404 | `DOWNLOAD_URL_NOT_FOUND` | У файла нет адреса для скачивания | | 502 | `DOWNLOAD_FAILED` | Битрикс24 вернул ошибку при проксировании (например, `403`) | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности - **Авторизация добавляется автоматически.** Для ключей OAuth-приложений Вайбкод добавляет токен авторизации к запросу при каждом вызове. Для ключей типа вебхук токен уже встроен в адрес — Вайбкод использует адрес как есть. - **Поле `downloadUrl` из `GET /v1/files/:id` — временное.** Этот эндпоинт (`/download`) — стабильный способ скачивания: он каждый раз получает актуальный адрес и добавляет авторизацию. Обращение напрямую по сохранённому `downloadUrl` может завершиться ошибкой, когда токен устареет. ## Смотрите также - [Получить файл](/docs/entities/files/get) — `GET /v1/files/:id` - [Список файлов](/docs/entities/files/list) — `GET /v1/files` - [Файлы](/docs/entities/files) --- # Files: Fields ## Поля файла `GET /v1/files/fields` Возвращает схему доступных полей сущности: типы данных и признак доступности для записи. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/files/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/files/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `ID` | number | да | Идентификатор объекта | | `name` | `NAME` | string | | Имя файла или папки | | `size` | `SIZE` | number | да | Размер файла в байтах (только для файлов). ⚠ Только в `GET /v1/files/:id` — списочный `GET /v1/files` это поле не возвращает | | `folderId` | `PARENT_ID` | number | | ID родительской папки. Список папок: `GET /v1/folders` | | `storageId` | `STORAGE_ID` | number | да | ID хранилища. Список: `GET /v1/storages` | | `type` | `TYPE` | string | да | Тип объекта: `"file"` или `"folder"` | | `code` | `CODE` | string | | Символьный код объекта | | `fileId` | `FILE_ID` | number | да | Внутренний ID файла. ⚠ Только в `GET /v1/files/:id` — списочный `GET /v1/files` это поле не возвращает | | `downloadUrl` | `DOWNLOAD_URL` | string | да | Временная ссылка для скачивания. ⚠ Только в `GET /v1/files/:id` — списочный `GET /v1/files` это поле не возвращает | | `detailUrl` | `DETAIL_URL` | string | да | Ссылка на объект в интерфейсе | | `contentProvider` | `CONTENT_PROVIDER` | string | да | Провайдер контента. ⚠ Только в `GET /v1/files/:id` — списочный `GET /v1/files` это поле не возвращает | | `globalContentVersion` | `GLOBAL_CONTENT_VERSION` | number | да | Счётчик версий файла. ⚠ Только в `GET /v1/files/:id` — списочный `GET /v1/files` это поле не возвращает | | `deletedType` | `DELETED_TYPE` | number | да | Статус удаления: `0` — не удалён, `3` — в корзине, `4` — удалён вместе с папкой | | `realObjectId` | `REAL_OBJECT_ID` | number | да | Внутренний ID объекта | | `createdBy` | `CREATED_BY` | number | да | ID пользователя-создателя. Поиск: `GET /v1/users` | | `updatedBy` | `UPDATED_BY` | number | да | ID автора последнего изменения. Поиск: `GET /v1/users` | | `deletedBy` | `DELETED_BY` | number | да | ID пользователя, удалившего объект. Поиск: `GET /v1/users` | | `createdAt` | `CREATE_TIME` | datetime | да | Дата и время создания (ISO 8601 UTC) | | `updatedAt` | `UPDATE_TIME` | datetime | да | Дата и время последнего изменения | | `deletedAt` | `DELETE_TIME` | datetime | да | Дата и время удаления; `null` — объект не удалён | Поля `name`, `folderId` и `code` доступны при создании и обновлении объекта. Через `PATCH /v1/files/:id` обновляется только поле `name`. ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false }, "size": { "type": "number", "readonly": true }, "folderId": { "type": "number", "readonly": false }, "storageId": { "type": "number", "readonly": true }, "type": { "type": "string", "readonly": true }, "code": { "type": "string", "readonly": false }, "fileId": { "type": "number", "readonly": true }, "downloadUrl": { "type": "string", "readonly": true }, "detailUrl": { "type": "string", "readonly": true }, "contentProvider": { "type": "string", "readonly": true }, "globalContentVersion": { "type": "number", "readonly": true }, "deletedType": { "type": "number", "readonly": true }, "createdBy": { "type": "number", "readonly": true }, "updatedBy": { "type": "number", "readonly": true }, "createdAt": { "type": "datetime", "readonly": true }, "updatedAt": { "type": "datetime", "readonly": true }, "deletedAt": { "type": "datetime", "readonly": true }, "realObjectId": { "type": "number", "readonly": true }, "deletedBy": { "type": "number", "readonly": true } } } } ``` ## Пример ответа при ошибке 403 — нет скоупа `disk`: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'disk' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `disk` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов портала | | 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список файлов](/docs/entities/files/list) - [Получить файл](/docs/entities/files/get) - [Обновить файл](/docs/entities/files/update) - [Файлы](/docs/entities/files) - [Синтаксис фильтрации](/docs/filtering) --- # Files: Get ## Получить файл `GET /v1/files/:id` Возвращает файл по ID со всеми полями, включая ссылку для скачивания и прямой URL в интерфейсе Битрикс24. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID файла. Получить: `GET /v1/files?folderId=X` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/files/205" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/files/205" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/205', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Файл:', data.name, '—', data.size, 'байт') ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/205', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Только чтение | Описание | |------|-----|:---:|---------| | `success` | boolean | | Всегда `true` при успехе | | `data.id` | number | ✓ | Идентификатор файла | | `data.name` | string | | Имя файла | | `data.code` | string\|null | | Символьный код файла | | `data.realObjectId` | number | ✓ | Внутренний ID объекта | | `data.storageId` | number | ✓ | ID хранилища. Список: `GET /v1/storages` | | `data.type` | string | ✓ | Тип объекта: всегда `"file"` | | `data.folderId` | number | | ID родительской папки. Список: `GET /v1/folders` | | `data.deletedType` | number | ✓ | Статус удаления: `0` — активен, `3` — в корзине, `4` — удалён вместе с папкой | | `data.globalContentVersion` | number | ✓ | Счётчик версий файла | | `data.fileId` | number | ✓ | Внутренний идентификатор файла в Битрикс24 | | `data.size` | number | ✓ | Размер файла в байтах | | `data.createdBy` | number | ✓ | ID пользователя-создателя. Список: `GET /v1/users` | | `data.updatedBy` | number | ✓ | ID автора последнего изменения. Список: `GET /v1/users` | | `data.deletedBy` | number\|null | ✓ | ID пользователя, удалившего файл; `null` — файл не удалён | | `data.createdAt` | datetime | ✓ | Дата и время создания (ISO 8601) | | `data.updatedAt` | datetime | ✓ | Дата и время последнего изменения (ISO 8601) | | `data.deletedAt` | datetime\|null | ✓ | Дата и время перемещения в корзину; `null` — файл не удалён | | `data.downloadUrl` | string | ✓ | Ссылка для скачивания файла | | `data.detailUrl` | string | ✓ | Ссылка на файл в интерфейсе Битрикс24 | | `data.contentProvider` | string | ✓ | Поставщик контента (может отсутствовать) | ## Пример ответа ```json { "success": true, "data": { "id": 205, "name": "project-report.pdf", "code": null, "realObjectId": 205, "storageId": 1, "type": "file", "folderId": 27, "deletedType": 0, "globalContentVersion": 1, "fileId": 363, "size": 31232, "createdBy": 1, "updatedBy": 1, "deletedBy": null, "createdAt": "2020-05-15T09:29:09.000Z", "updatedAt": "2020-05-15T09:29:09.000Z", "deletedAt": null, "downloadUrl": "https://example.bitrix24.ru/disk/downloadFile/363/?...", "detailUrl": "https://example.bitrix24.ru/disk/file/project-report.pdf/" } } ``` ## Пример ответа при ошибке 404 — файл не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Could not find entity with id '99999999'." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Файл с указанным ID не существует | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `disk` | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов авторизации | | 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности `downloadUrl` содержит токен авторизации и действует ограниченное время. Для программного скачивания используйте `GET /v1/files/:id/download` — он возвращает перенаправление на актуальную ссылку без встроенного токена. Метод возвращает только объекты типа `"file"`. Чтобы получить данные папки, используйте `GET /v1/folders/:id`. ## Смотрите также - [Список файлов](/docs/entities/files/list) - [Переименовать файл](/docs/entities/files/update) - [Удалить файл](/docs/entities/files/delete) - [Получить папку](/docs/entities/folders/get) --- # Files: List ## Список файлов папки `GET /v1/files` Возвращает список объектов в указанной папке: папки и файлы вместе. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `folderId` (query) | number | да | — | ID папки, содержимое которой нужно получить. Список папок: `GET /v1/folders` | | `limit` (query) | number | нет | `50` | Количество записей (до 5000) | | `offset` (query) | number | нет | `0` | Пропустить N записей | | `sort` (query) | string | нет | — | Поле для сортировки | | `filter` (query) | object | нет | — | Фильтрация по полям `GET /v1/files/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[type]=file` | **Пагинация.** При `limit > 50` Вайбкод автоматически выполняет несколько запросов к Битрикс24 и возвращает все записи в одном ответе. Максимум — 5000 записей за вызов. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/files?folderId=27&limit=10" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/files?folderId=27&limit=10" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files?folderId=27&limit=10', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Объектов в папке: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files?folderId=27&limit=10', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив объектов папки (папки и файлы). Полный список полей элемента — ниже | | `data[].id` | number | Идентификатор объекта | | `data[].name` | string | Имя объекта | | `data[].code` | string | Символьный код | | `data[].storageId` | number | ID хранилища. Список хранилищ: `GET /v1/storages` | | `data[].type` | string | Тип: `"file"` или `"folder"` | | `data[].folderId` | number | ID родительской папки | | `data[].deletedType` | number | Статус удаления: `0` — активен, `3` — в корзине, `4` — удалён вместе с папкой | | `data[].realObjectId` | number | Внутренний ID объекта. Присутствует только у папок | | `data[].createdBy` | number | ID создателя. Список пользователей: `GET /v1/users` | | `data[].updatedBy` | number | ID автора последнего изменения. Список пользователей: `GET /v1/users` | | `data[].deletedBy` | number\|null | ID пользователя, удалившего объект; `null` — не удалён | | `data[].createdAt` | datetime | Дата создания (ISO 8601) | | `data[].updatedAt` | datetime | Дата последнего изменения (ISO 8601) | | `data[].deletedAt` | datetime | Дата удаления (ISO 8601), `null` — не удалён | | `data[].detailUrl` | string | Ссылка на объект в интерфейсе Битрикс24 | | `data[].size` | number | ⚠ В **списке не возвращается** (облегчённая проекция `disk.folder.getchildren`) — читайте через `GET /v1/files/:id` | | `data[].fileId` | number | ⚠ В списке не возвращается — только `GET /v1/files/:id` | | `data[].globalContentVersion` | number | ⚠ В списке не возвращается — только `GET /v1/files/:id` | | `data[].downloadUrl` | string | ⚠ В списке не возвращается — только `GET /v1/files/:id` (для программного скачивания — `GET /v1/files/:id/download`) | | `data[].contentProvider` | string | ⚠ В списке не возвращается — только `GET /v1/files/:id` | | `meta.total` | number | Общее количество объектов в папке | | `meta.hasMore` | boolean | Есть ли ещё объекты за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 1275, "name": "Архив проекта", "code": "ARCHIVE_PROJECT", "storageId": 1, "type": "folder", "folderId": 27, "deletedType": 0, "realObjectId": 1275, "createdBy": 5, "updatedBy": 5, "deletedBy": null, "createdAt": "2023-04-12T08:30:00.000Z", "updatedAt": "2023-04-12T08:30:01.000Z", "deletedAt": null, "detailUrl": "https://example.bitrix24.ru/docs/path/to/folder/" }, { "id": 205, "name": "presentation_q1.pdf", "code": null, "storageId": 1, "type": "file", "folderId": 27, "deletedType": 0, "createdBy": 5, "updatedBy": 5, "deletedBy": null, "createdAt": "2023-03-15T09:29:09.000Z", "updatedAt": "2023-03-15T09:29:09.000Z", "deletedAt": null, "detailUrl": "https://example.bitrix24.ru/docs/path/to/file/" } ], "meta": { "total": 40, "hasMore": true } } ``` ## Пример ответа при ошибке 400 — не передан `folderId`: ```json { "success": false, "error": { "code": "MISSING_REQUIRED_PARAMS", "message": "GET /v1/files requires query parameters: folderId. Example: GET /v1/files?folderId=..." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_REQUIRED_PARAMS` | Не передан обязательный параметр `folderId` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `disk` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов портала | | 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Смешанный список.** Ответ содержит одновременно папки (`type: "folder"`) и файлы (`type: "file"`). Разграничить объекты можно по полю `type`. Поля `size`, `fileId`, `globalContentVersion`, `downloadUrl` и `contentProvider` в списочном ответе **не приходят вовсе** — B24 `disk.folder.getchildren` отдаёт облегчённую проекцию (VB-6801078f, проверено на живом портале). Чтобы получить их, запросите карточку `GET /v1/files/:id` (`disk.file.get`). Поле `realObjectId` — только у папок. ## Смотрите также - [Файлы — обзор](/docs/entities/files) - [Папки](/docs/entities/folders) - [Хранилища](/docs/entities/storages) - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) --- # Files: Moveto ## Переместить файл `POST /v1/files/:id/moveto` Перемещает файл в другую папку того же хранилища. После успеха поле `folderId` в ответе содержит ID целевой папки; `id`, `createdAt` и `createdBy` у файла не изменяются. ## Параметры | Параметр | В | Тип | Обяз. | Описание | |----------|---|-----|:-----:|----------| | `id` | path | number | да | ID файла. Получить через `GET /v1/files` | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|----------| | `targetFolderId` | number | да | ID папки-назначения. Получить через `GET /v1/folders` | ## Примеры ### curl — личный ключ ```bash curl -X POST \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"targetFolderId":649}' \ https://vibecode.bitrix24.tech/v1/files/9251/moveto ``` ### curl — OAuth-приложение ```bash curl -X POST \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"targetFolderId":649}' \ https://vibecode.bitrix24.tech/v1/files/9251/moveto ``` ### JavaScript — личный ключ ```javascript const res = await fetch( 'https://vibecode.bitrix24.tech/v1/files/9251/moveto', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ targetFolderId: 649 }), } ) const body = await res.json() if (!body.success) throw new Error(body.error.code) console.log('Файл перемещён, новая папка:', body.data.folderId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch( 'https://vibecode.bitrix24.tech/v1/files/9251/moveto', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ targetFolderId: 649 }), } ) const body = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|----------| | `success` | boolean | `true` при успешном перемещении | | `data.id` | number | ID файла (не изменяется после перемещения) | | `data.name` | string | Имя файла | | `data.code` | string \| null | Символьный код файла | | `data.folderId` | number | ID папки-назначения — равен переданному `targetFolderId` | | `data.storageId` | number | ID хранилища | | `data.type` | string | Тип объекта — всегда `"file"` | | `data.deletedType` | number | Статус удаления: `0` — активен | | `data.globalContentVersion` | number | Счётчик версий файла | | `data.fileId` | number | Внутренний ID файла в Битрикс24 | | `data.size` | number | Размер файла в байтах | | `data.createdBy` | number | ID пользователя, создавшего файл | | `data.updatedBy` | number | ID пользователя, выполнившего перемещение | | `data.deletedBy` | number \| null | ID пользователя, удалившего файл; `null` — не удалён | | `data.createdAt` | string | Дата создания файла (ISO 8601) — не изменяется | | `data.updatedAt` | string | Дата последнего изменения (ISO 8601) | | `data.deletedAt` | string \| null | Дата удаления или `null` | | `data.downloadUrl` | string | URL для скачивания файла | | `data.detailUrl` | string | URL карточки файла в Битрикс24 | ## Пример ответа ```json { "success": true, "data": { "id": 9251, "name": "verify-move-test.txt", "code": null, "storageId": 1, "type": "file", "folderId": 649, "deletedType": 0, "globalContentVersion": 1, "fileId": 34867, "size": 11, "createdBy": 1, "updatedBy": 1, "deletedBy": null, "createdAt": "2026-05-06T09:32:39.000Z", "updatedAt": "2026-05-06T09:34:16.000Z", "deletedAt": null, "downloadUrl": "https://example.bitrix24.ru/disk/downloadFile/34867/?...", "detailUrl": "https://example.bitrix24.ru/company/personal/user/1/disk/file/verify-move-test.txt/" } } ``` ## Пример ответа при ошибке 422 — в целевой папке уже существует файл с таким именем: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Файл с таким именем уже есть (DISK_OBJ_22000)." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|----------| | 400 | `MISSING_PARAMS` | Не передан `targetFolderId` | | 400 | `INVALID_PARAMS` | `targetFolderId` не является положительным целым числом | | 400 | `INVALID_ID` | `id` файла не является положительным целым числом | | 400 | `OPERATION_FAILED` | Перемещение между разными хранилищами не поддерживается — используйте `POST /v1/files/:id/copyto` | | 401 | `NO_TOKENS` | Для портала нет токенов авторизации | | 403 | `SCOPE_MISSING` | Ключу не хватает скоупа `disk` | | 404 | `ENTITY_NOT_FOUND` | Файл с указанным `id` не найден | | 422 | `BITRIX_ERROR` | В целевой папке уже есть файл с таким именем — переименуйте файл через `PATCH /v1/files/:id` перед перемещением | | 429 | `RATE_LIMITED` | Превышен лимит запросов — подождите 1-2 секунды и повторите | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Постоянство идентификатора.** После перемещения `id`, `createdAt` и `createdBy` файла не изменяются — все внешние ссылки на файл по ID остаются рабочими. ## Смотрите также - [Скопировать файл](./copyto.md) — `POST /v1/files/:id/copyto` - [Получить файл](./get.md) — `GET /v1/files/:id` - [Список файлов](/docs/entities/files) — `GET /v1/files` - [Список папок](/docs/entities/folders) — `GET /v1/folders` --- # Files: Update ## Переименовать файл `PATCH /v1/files/:id` Переименовывает файл на диске. Принимает только поле `name` — остальные поля файла остаются без изменений, расположение файла не меняется. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `name` | string | ✓ | Новое имя файла с расширением | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/files/9251" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "doc-renamed.txt" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/files/9251" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "doc-renamed.txt" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/9251', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'doc-renamed.txt', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/files/9251', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'doc-renamed.txt', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект файла с обновлённым именем. Набор полей совпадает с ответом `GET /v1/files/:id`. | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор файла | | `data.name` | string | Новое имя файла | | `data.code` | string\|null | Символьный код файла | | `data.storageId` | number | ID хранилища | | `data.type` | string | Тип объекта — всегда `"file"` | | `data.folderId` | number | ID родительской папки | | `data.deletedType` | number | Статус удаления: `0` — активен | | `data.globalContentVersion` | number | Счётчик версий файла | | `data.fileId` | number | Внутренний ID файла в Битрикс24 | | `data.size` | number | Размер файла в байтах | | `data.createdBy` | number | ID пользователя-создателя | | `data.updatedBy` | number | ID пользователя, выполнившего переименование | | `data.deletedBy` | number\|null | ID пользователя, удалившего файл; `null` — не удалён | | `data.createdAt` | string | Дата и время создания (ISO 8601) | | `data.updatedAt` | string | Дата и время переименования (ISO 8601) | | `data.deletedAt` | string\|null | Дата удаления; `null` — файл не удалён | | `data.contentProvider` | string | Поставщик контента (может отсутствовать) | | `data.realObjectId` | number | Внутренний ID объекта | | `data.downloadUrl` | string | Ссылка для скачивания файла | | `data.detailUrl` | string | Ссылка на файл в интерфейсе Битрикс24 | ## Пример ответа ```json { "success": true, "data": { "id": 9251, "name": "doc-renamed.txt", "code": null, "storageId": 1, "type": "file", "folderId": 27, "deletedType": 0, "globalContentVersion": 1, "fileId": 34867, "size": 11, "createdBy": 1, "updatedBy": 1, "deletedBy": null, "createdAt": "2026-05-06T09:32:39.000Z", "updatedAt": "2026-05-26T07:08:50.000Z", "deletedAt": null, "downloadUrl": "https://example.bitrix24.ru/disk/downloadFile/34867/?...", "detailUrl": "https://example.bitrix24.ru/company/personal/user/1/disk/file/doc-renamed.txt/" } } ``` ## Пример ответа при ошибке 404 — файл не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "diskFile 9251 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Файл с указанным `id` не существует | | 400 | `MISSING_FIELDS` | Тело запроса не содержит поля `name` | | 403 | `SCOPE_DENIED` | Ключ не имеет скоупа `disk` | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов авторизации | | 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить файл](/docs/entities/files/get) - [Поля файла](/docs/entities/files/fields) - [Переместить файл](/docs/entities/files/moveto) - [Удалить файл](/docs/entities/files/delete) - [Файлы](/docs/entities/files) --- # Files: Upload ## Загрузить файл `POST /v1/files/upload` Загружает файл на Диск Битрикс24. Содержимое передаётся в кодировке Base64 в теле JSON-запроса. Для загрузки необходимо указать папку (`folderId`) или хранилище (`storageId`). ## Поля запроса | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `filename` | string | да | Имя файла с расширением, например `report.pdf` | | `content` | string | да | Содержимое файла в кодировке Base64 | | `folderId` | number | условно | ID папки-назначения. Список папок: `GET /v1/folders`. Обязателен, если не указан `storageId` | | `storageId` | number | условно | ID хранилища (загрузка в корень). Список хранилищ: `GET /v1/storages`. Обязателен, если не указан `folderId` | Необходимо указать один из двух параметров: `folderId` или `storageId`. ## Примеры ### curl — личный ключ ```bash curl -X POST \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"folderId":27,"filename":"report.txt","content":"SGVsbG8gV29ybGQ="}' \ https://vibecode.bitrix24.tech/v1/files/upload ``` ### curl — OAuth-приложение ```bash curl -X POST \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"folderId":27,"filename":"report.txt","content":"SGVsbG8gV29ybGQ="}' \ https://vibecode.bitrix24.tech/v1/files/upload ``` ### JavaScript — личный ключ ```javascript const content = Buffer.from('Hello World').toString('base64') const res = await fetch('https://vibecode.bitrix24.tech/v1/files/upload', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ folderId: 27, filename: 'report.txt', content, }), }) const body = await res.json() console.log(body.data.id, body.data.downloadUrl) ``` ### JavaScript — OAuth-приложение ```javascript const content = Buffer.from('Hello World').toString('base64') const res = await fetch('https://vibecode.bitrix24.tech/v1/files/upload', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ folderId: 27, filename: 'report.txt', content, }), }) const body = await res.json() console.log(body.data.id, body.data.downloadUrl) ``` ### Загрузка в корень хранилища Если нужно загрузить файл в корень хранилища, а не в папку, передайте `storageId` вместо `folderId`. ID хранилища доступен в поле `id` из `GET /v1/storages`, корневая папка — в поле `rootFolderId`. ```bash curl -X POST \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"storageId":1,"filename":"backup.txt","content":"SGVsbG8gV29ybGQ="}' \ https://vibecode.bitrix24.tech/v1/files/upload ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | ID созданного файла | | `data.name` | string | Имя файла | | `data.code` | string \| null | Символьный код файла | | `data.storageId` | number | ID хранилища, в котором находится файл | | `data.type` | string | Тип объекта — всегда `"file"` | | `data.folderId` | number | ID папки, в которой находится файл | | `data.deletedType` | number | Тип удаления: `0` — не удалён | | `data.globalContentVersion` | number | Версия содержимого файла | | `data.fileId` | number | ID файла во внутреннем хранилище Битрикс24 | | `data.size` | number | Размер файла в байтах | | `data.createdBy` | number | ID пользователя, создавшего файл. Список: `GET /v1/users` | | `data.updatedBy` | number | ID пользователя, изменившего файл последним | | `data.deletedBy` | number \| null | ID удалившего файл или `null`, если файл не удалён | | `data.createdAt` | string | Дата и время создания (ISO 8601) | | `data.updatedAt` | string | Дата и время последнего изменения (ISO 8601) | | `data.deletedAt` | string \| null | Дата и время удаления или `null`, если файл не удалён | | `data.downloadUrl` | string | URL для скачивания файла | | `data.detailUrl` | string | URL карточки файла в Битрикс24 | ## Пример ответа При успешной загрузке возвращается HTTP-статус `201 Created`. ```json { "success": true, "data": { "id": 9251, "name": "report.txt", "code": null, "storageId": 1, "type": "file", "folderId": 27, "deletedType": 0, "globalContentVersion": 1, "fileId": 34867, "size": 11, "createdBy": 1, "updatedBy": 1, "deletedBy": null, "createdAt": "2026-05-06T09:32:39.000Z", "updatedAt": "2026-05-06T09:32:39.000Z", "deletedAt": null, "downloadUrl": "https://example.bitrix24.ru/disk/downloadFile/...", "detailUrl": "https://example.bitrix24.ru/company/personal/user/1/disk/file/report.txt" } } ``` ## Пример ответа при ошибке 400 — не указаны `filename` и `content`: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "filename and content (base64) are required." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не переданы `filename` и `content`, либо не указан ни `folderId`, ни `storageId` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ | | 401 | `NO_TOKENS` | Токены доступа к порталу Битрикс24 недоступны | | 403 | `SCOPE_MISSING` | Ключу не хватает скоупа `disk` | | 404 | `ENTITY_NOT_FOUND` | Папка или хранилище с указанным ID не найдены | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку при загрузке файла | | 429 | `RATE_LIMITED` | Превышен лимит запросов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Содержимое передаётся в Base64.** Файл кодируется в Base64 и передаётся как строка в поле `content`. Передача файла через `multipart/form-data` не поддерживается. ## Смотрите также - [Файлы](/docs/entities/files) - [Папки](/docs/entities/folders) - [Хранилища](/docs/entities/storages) - [Удалить файл](/docs/entities/files/delete) --- # Invoices: Aggregate ## Агрегация счетов `POST /v1/invoices/aggregate` Подсчёт количества, сумма, среднее, минимум и максимум по счетам с фильтрацией и группировкой. **Стандартные поля:** - `opportunity` — сумма счёта (числовое агрегирование имеет смысл) - `stageId` — стадия (для `groupBy`) - `assignedById` — ответственный (для `groupBy`) **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "opportunity", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/invoices/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/invoices/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "opportunity", "function": "sum" }, { "field": "opportunity", "function": "avg" } ], "filter": { "assignedById": 1 }, "groupBy": "stageId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/invoices/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "opportunity", "function": "sum" }, { "field": "opportunity", "function": "avg" } ], "filter": { "assignedById": 1 }, "groupBy": "stageId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'opportunity', function: 'sum' }, { field: 'opportunity', function: 'avg' }, ], filter: { assignedById: 1 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() console.log('Всего счетов:', data.count) console.log('По стадиям:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'opportunity', function: 'sum' }, { field: 'opportunity', function: 'avg' }, ], filter: { assignedById: 1 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["stageId", "assignedById"]` (максимум 5). ## Другие сценарии Только `count` — самый быстрый запрос, без выгрузки записей: ```json { "filter": { "assignedById": 1 } } ``` Работа с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF: ```json { "aggregate": [{ "field": "UF_CRM_TAX", "function": "sum" }], "groupBy": "UF_CRM_PAYMENT_METHOD" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций: `{ "opportunity": { "sum": 120000, "avg": 2200 } }` | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей обработано для числовых агрегаций (максимум 5000) | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (агрегации + `groupBy: "stageId"`): ```json { "success": true, "data": { "count": 55, "aggregates": { "opportunity": { "sum": 120000, "avg": 2200 } }, "groups": [ { "stageId": "DT31_5:N", "count": 30, "aggregates": { "opportunity": { "sum": 70000 } } }, { "stageId": "DT31_5:P", "count": 25, "aggregates": { "opportunity": { "sum": 50000 } } } ], "meta": { "totalRecords": 55, "recordsProcessed": 55, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неверное имя функции, несуществующее поле или `groupBy` по неаггрегируемому полю: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Field 'foo' not found. Available numeric fields: opportunity, stageId, assignedById" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Невалидное имя функции, несуществующее поле, нечисловое поле в `sum`/`avg`/`min`/`max`, `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` vs числовые функции.** `count` считается одним вызовом в Битрикс24 на любом объёме данных. Функции `sum`/`avg`/`min`/`max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод — если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true`, агрегация выполнится по первым 5000. Для точных счётчиков на больших выборках используйте `count` или сужайте фильтр. **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "ufCrm_1234": "value" } }` вернёт количество счетов с этим значением UF. ## Смотрите также - [Список счетов](/docs/entities/invoices/list) — получить записи с фильтрацией - [Поиск счетов](/docs/entities/invoices/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Invoices: Create ## Создать счёт `POST /v1/invoices` Создаёт новый счёт в CRM. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название счёта | | `stageId` | string | Стадия. Формат: `DT31_{categoryId}:{stage}`. Список стадий: `GET /v1/statuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId зависит от портала. Узнать: `GET /v1/invoices?limit=1&select=categoryId` или запросить у администратора | | `categoryId` | number | ID воронки | | `contactId` | number | ID контакта-плательщика. Поиск: `GET /v1/contacts` | | `companyId` | number | ID компании-плательщика. Поиск: `GET /v1/companies` | | `mycompanyId` | number | ID своей компании | | `opportunity` | number | Сумма счёта | | `currencyId` | string | Валюта. Список: `GET /v1/currencies` | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `comments` | string | Комментарий | Полный список полей: [GET /v1/invoices/fields](/docs/entities/invoices/fields). Пользовательские поля (`ufCrm_*`) также принимаются. ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/invoices \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Счёт за услуги", "stageId": "DT31_5:N", "contactId": 42, "companyId": 15, "opportunity": 150000, "currencyId": "RUB", "assignedById": 1 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/invoices \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Счёт за услуги", "stageId": "DT31_5:N", "contactId": 42, "companyId": 15, "opportunity": 150000, "currencyId": "RUB", "assignedById": 1 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Счёт за услуги', stageId: 'DT31_5:N', contactId: 42, companyId: 15, opportunity: 150000, currencyId: 'RUB', assignedById: 1, }), }) const { success, data } = await res.json() console.log('Invoice ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Счёт за услуги', stageId: 'DT31_5:N', contactId: 42, companyId: 15, opportunity: 150000, currencyId: 'RUB', assignedById: 1, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного счёта | | `title` | string | Название | | `stageId` | string | Стадия | | `contactId` | number | ID контакта | | `companyId` | number | ID компании | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdTime` | datetime | Дата создания | | `updatedTime` | datetime | Дата изменения | Ответ содержит все поля счёта, включая пользовательские (`ufCrm_*`). URL карточки счёта в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/crm/type/31/details// ``` `31` — `entityTypeId` смарт-счёта в Битрикс24. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 891, "title": "Счёт за услуги", "stageId": "DT31_5:N", "categoryId": 5, "contactId": 42, "companyId": 15, "opportunity": 150000, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T14:30:00+03:00" } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список счетов](/docs/entities/invoices/list) — получение с фильтрами - [Поля счёта](/docs/entities/invoices/fields) — полный список полей - [Контакты](/docs/entities/contacts) — привязка через `contactId` - [Компании](/docs/entities/companies) — привязка через `companyId` - [Entity API](/docs/entity-api) — общие принципы --- # Invoices: Delete ## Удалить счёт `DELETE /v1/invoices/:id` Удаляет счёт по ID. Восстановить удалённый счёт через API нельзя — создавайте новый при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID счёта | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/invoices/891" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/invoices/891" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/891', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) if (res.status === 204) { console.log('Счёт удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/891', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — счёт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Счёт с указанным ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список счетов](/docs/entities/invoices/list) — получение с фильтрами - [Создать счёт](/docs/entities/invoices/create) — создание нового счёта - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Invoices: Fields ## Поля счёта `GET /v1/invoices/fields` Возвращает описание всех полей счёта, включая пользовательские (`ufCrm_*`). ## Примеры ### curl — личный ключ ```bash curl -X GET https://vibecode.bitrix24.tech/v1/invoices/fields \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET https://vibecode.bitrix24.tech/v1/invoices/fields \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Только чтение | Описание | |------|-----|:---:|---------| | `id` | number | да | ID счёта | | `title` | string | | Название | | `stageId` | string | | Стадия. Формат: `DT31_{categoryId}:{stage}`. Список стадий: `GET /v1/statuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId зависит от портала. Узнать: `GET /v1/invoices?limit=1&select=categoryId` или запросить у администратора | | `categoryId` | number | | ID воронки | | `contactId` | number | | ID контакта-плательщика. Поиск: `GET /v1/contacts` | | `companyId` | number | | ID компании-плательщика. Поиск: `GET /v1/companies` | | `mycompanyId` | number | | ID своей компании | | `opportunity` | number | | Сумма | | `currencyId` | string | | Валюта. Список: `GET /v1/currencies` | | `assignedById` | number | | Ответственный. Список: `GET /v1/users` | | `createdBy` | number | да | ID создателя | | `createdTime` | datetime | да | Дата создания | | `updatedTime` | datetime | да | Дата изменения | Пользовательские поля (`ufCrm_*`) возвращаются в ответе и доступны для записи. ## Пример ответа ```json { "success": true, "data": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "opportunity": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Сумма" } } } ``` ## Доступные include Эндпоинт `GET /v1/invoices/fields` возвращает список доступных include: `contact`, `company`. Пример использования: [Получить invoices](/docs/entities/invoices/get#связанные-данные). Подробнее об include: [Связанные данные](/docs/includes). ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать счёт](/docs/entities/invoices/create) — создание с полями - [Список счетов](/docs/entities/invoices/list) — фильтрация по полям - [Entity API](/docs/entity-api) — общие принципы --- # Invoices: Get ## Получить счёт `GET /v1/invoices/:id` Возвращает счёт по ID. Поддерживает включение связанных сущностей через `include`. ## Параметры запроса | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | ID счёта (в URL) | ## Примеры ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/invoices/891" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/invoices/891" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/891', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() console.log('Получено:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/891', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` Подробнее об include: [Связанные данные](/docs/includes). ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID счёта | | `title` | string | Название | | `stageId` | string | Стадия | | `categoryId` | number | ID воронки | | `contactId` | number | ID контакта | | `companyId` | number | ID компании | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdTime` | datetime | Дата создания | | `updatedTime` | datetime | Дата изменения | | `_included` | object | Связанные сущности (при `include`) | ## Связанные данные (include) ``` GET /v1/invoices/1?include=contact,company ``` Доступные include: `contact`, `company`. Результат в поле `_included`. ## Пример ответа ```json { "success": true, "data": { "id": 891, "title": "Счёт за услуги", "stageId": "DT31_5:N", "categoryId": 5, "contactId": 42, "companyId": 15, "opportunity": 150000, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T14:30:00+03:00", "_included": { "contact": { "id": 42, "name": "Иван", "lastName": "Петров" }, "company": { "id": 15, "title": "ООО Ромашка" } } } } ``` ## Пример ответа при ошибке 404 — счёт не найден: ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Entity not found" } } ``` Подробнее об include: [Связанные данные](/docs/includes). ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Счёт с указанным ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список счетов](/docs/entities/invoices/list) — получение с фильтрами - [Обновить счёт](/docs/entities/invoices/update) — изменение полей - [Контакты](/docs/entities/contacts) — данные контакта через `include` - [Компании](/docs/entities/companies) — данные компании через `include` - [Entity API](/docs/entity-api) — общие принципы --- # Invoices: List ## Список счетов `GET /v1/invoices` Возвращает список счетов с фильтрацией, сортировкой и пагинацией. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `?order[createdTime]=desc` | | `select` | string | — | Выборка полей: `?select=id,title,stageId` | | `filter` | object | — | Фильтрация по полям `GET /v1/invoices/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[stageId]=DT31_5:N` | ## Примеры ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/invoices?limit=10&sort=-createdTime&filter[stageId]=DT31_5:N" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/invoices?limit=10&sort=-createdTime&filter[stageId]=DT31_5:N" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const params = new URLSearchParams({ limit: '10', sort: '-createdTime', 'filter[stageId]': 'DT31_5:N', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/invoices?${params}`, { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data, total } = await res.json() console.log(`Найдено: ${total}`) ``` ### JavaScript — OAuth-приложение ```javascript const params = new URLSearchParams({ limit: '10', sort: '-createdTime', 'filter[stageId]': 'DT31_5:N', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/invoices?${params}`, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, total } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив счетов | | `total` | number | Общее количество записей | | `data[].id` | number | ID счёта | | `data[].title` | string | Название | | `data[].stageId` | string | Стадия | | `data[].opportunity` | number | Сумма | | `data[].currencyId` | string | Валюта | | `data[].contactId` | number | ID контакта | | `data[].companyId` | number | ID компании | | `data[].assignedById` | number | Ответственный | | `data[].createdTime` | datetime | Дата создания | URL карточки любого счёта из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/type/31/details// ``` `31` — `entityTypeId` смарт-счёта в Битрикс24. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 891, "title": "Счёт за услуги", "stageId": "DT31_5:N", "categoryId": 5, "contactId": 42, "companyId": 15, "opportunity": 150000, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T14:30:00+03:00" } ], "total": 47 } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить счёт](/docs/entities/invoices/get) — получение по ID с include - [Поиск счетов](/docs/entities/invoices/search) — расширенный поиск с датами - [Поля счёта](/docs/entities/invoices/fields) — полный список полей - [Entity API](/docs/entity-api) — общие принципы - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Invoices: Products Add ## Добавить товар в счёт `POST /v1/invoices/:id/products` Добавляет одну товарную позицию в счёт. В отличие от `PUT /v1/invoices/:id/products`, не заменяет существующие позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID счёта | | `productId` | number | нет | ID товара из каталога. Если задан без `productName`, имя подставляется из каталога. Каталог: `GET /v1/products` | | `productName` | string | нет | Название товарной позиции — для произвольной строки без товара из каталога. Укажите хотя бы одно из `productId` / `productName`. | | `price` | number | нет | Цена за единицу | | `quantity` | number | нет | Количество | | `discount` | number | нет | Сумма скидки | | `taxRate` | number | нет | Ставка налога (%) | | `taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/invoices/58/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/invoices/58/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/58/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() console.log('ID строки:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/58/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID созданной товарной строки | ## Пример ответа ```json { "success": true, "data": { "id": 1465 } } ``` ## Пример ответа при ошибке 404 — счёт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Счёт не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/invoices/products-get) — получить текущий список - [Установить товары](/docs/entities/invoices/products-set) — заменить все позиции - [Удалить товар](/docs/entities/invoices/products-delete) — удалить одну позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Invoices: Products Delete ## Удалить товар из счёта `DELETE /v1/invoices/:id/products/:rowId` Удаляет одну товарную позицию из счёта по ID строки. Восстановить удалённую позицию через API нельзя — добавляйте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID счёта | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/invoices/58/products/1465" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/invoices/58/products/1465" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/58/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Товар удалён из счёта') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/58/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — счёт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Счёт или товарная строка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/invoices/products-get) — получить текущий список - [Добавить товар](/docs/entities/invoices/products-add) — добавить позицию - [Установить товары](/docs/entities/invoices/products-set) — заменить все позиции - [Товары каталога](/docs/entities/products) — справочник товаров --- # Invoices: Products Fields ## Поля товаров счёта `GET /v1/invoices/:id/products/fields` Возвращает описание полей товарных позиций счёта: названия, типы, доступность для чтения и записи. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID счёта | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/invoices/741/products/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/invoices/741/products/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Обяз. | Описание | |------|-----|:--:|:-----:|---------| | `id` | integer | да | | ID позиции | | `productId` | integer | | да | ID товара. Каталог: `GET /v1/products` | | `productName` | string | | | Название товара | | `price` | double | | | Цена | | `quantity` | double | | | Количество | | `discountSum` | double | | | Сумма скидки | | `discountRate` | double | | | Величина скидки (%) | | `discountTypeId` | integer | | | Тип скидки | | `taxRate` | double | | | Налог (%) | | `taxIncluded` | char | | | Налог включён в цену (`Y`/`N`) | | `priceExclusive` | double | да | | Цена без налога со скидкой | | `priceNetto` | double | да | | Цена нетто | | `priceBrutto` | double | да | | Цена брутто | | `measureCode` | integer | | | Код единицы измерения | | `measureName` | string | | | Единица измерения | | `customized` | char | | | Изменён (`Y`/`N`) | | `sort` | integer | | | Сортировка | | `type` | integer | да | | Тип | | `storeId` | integer | да | | ID склада | | `ownerId` | integer | | да | ID владельца (счёта) | | `ownerType` | string | | да | Тип владельца | ## Пример ответа ```json { "success": true, "data": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "ownerId": { "type": "integer", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "ID владельца" }, "ownerType": { "type": "string", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "Тип владельца" }, "productId": { "type": "integer", "isRequired": true, "isReadOnly": false, "title": "Товар" }, "productName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название товара" }, "price": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Цена" }, "priceExclusive": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "Цена без налога со скидкой" }, "priceNetto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_NETTO" }, "priceBrutto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_BRUTTO" }, "quantity": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Количество" }, "discountTypeId": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Тип скидки" }, "discountRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Величина скидки" }, "discountSum": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Сумма скидки" }, "taxRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Налог" }, "taxIncluded": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Налог включен в цену" }, "customized": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Изменен" }, "measureCode": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Код единицы измерения" }, "measureName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Единица измерения" }, "sort": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Сортировка" }, "type": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "TYPE" }, "storeId": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "STORE_ID" } } } ``` ## Пример ответа при ошибке 404 — счёт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Счёт не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/invoices/products-get) — получить товары счёта - [Добавить товар](/docs/entities/invoices/products-add) — добавить позицию - [Установить товары](/docs/entities/invoices/products-set) — заменить все позиции - [Поля счёта](/docs/entities/invoices/fields) — описание полей счёта --- # Invoices: Products Get ## Товарные позиции счёта `GET /v1/invoices/:id/products` Возвращает список товарных позиций, привязанных к счёту. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID счёта | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/invoices/741/products" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/invoices/741/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Товаров:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив товарных позиций | | `data[].productId` | number | ID товара. Каталог: `GET /v1/products` | | `data[].productName` | string | Название товара | | `data[].price` | number | Цена за единицу | | `data[].quantity` | number | Количество | | `data[].discount` | number | Сумма скидки | | `data[].taxRate` | number/null | Ставка налога (%) | | `data[].taxIncluded` | boolean | Налог включён в цену | Показаны основные поля. Полный список (20 полей, включая priceAccount, measureCode и др.): [Поля товаров](/docs/entities/invoices/products-fields). ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 1000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 404 — счёт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Счёт не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Установить товары](/docs/entities/invoices/products-set) — заменить товарные позиции - [Получить счёт](/docs/entities/invoices/get) — основные данные счёта - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Invoices: Products Get Single ## Получить товар из счёта `GET /v1/invoices/:id/products/:rowId` Возвращает одну товарную позицию счёта по ID строки. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID счёта | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/invoices/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/invoices/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Цена:', data.price) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID товарной строки | | `data.productId` | number | ID товара из каталога | | `data.productName` | string | Название товара | | `data.price` | number | Цена за единицу | | `data.quantity` | number | Количество | | `data.discount` | number | Сумма скидки | | `data.discountRate` | number | Процент скидки | | `data.discountTypeId` | number | Тип скидки (1 — сумма, 2 — процент) | | `data.taxRate` | number \| null | Ставка налога (%) | | `data.taxIncluded` | boolean | Налог включён в цену | | `data.priceExclusive` | number | Цена без скидки | | `data.priceNetto` | number | Цена нетто | | `data.priceBrutto` | number | Цена брутто | | `data.priceAccount` | number | Цена в валюте учёта | | `data.measureCode` | number | Код единицы измерения | | `data.measureName` | string | Название единицы измерения | | `data.sort` | number | Сортировка | ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "День добрый!", "price": 5000, "priceAccount": 5000, "priceExclusive": 5000, "priceNetto": 5000, "priceBrutto": 5000, "quantity": 3, "discountTypeId": 2, "discountRate": 0, "discount": 0, "taxRate": null, "taxIncluded": false, "customized": "Y", "measureCode": 796, "measureName": "шт", "sort": 0, "xmlId": "sale_basket_995", "type": 1 } } ``` ## Пример ответа при ошибке 404 — счёт или товарная строка не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Счёт или товарная строка не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/invoices/products-get) — получить все позиции - [Обновить товар](/docs/entities/invoices/products-update) — обновить позицию - [Добавить товар](/docs/entities/invoices/products-add) — добавить позицию - [Удалить товар](/docs/entities/invoices/products-delete) — удалить позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Invoices: Products Set ## Установить товары счёта `PUT /v1/invoices/:id/products` Устанавливает товарные позиции счёта. Полностью заменяет текущий список — передайте все нужные позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `items` | array | да | Массив товарных позиций | | `items[].productId` | number | да | ID товара. Каталог: `GET /v1/products` | | `items[].price` | number | да | Цена за единицу | | `items[].quantity` | number | да | Количество | | `items[].discount` | number | нет | Сумма скидки | | `items[].taxRate` | number | нет | Ставка налога (%) | | `items[].taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/invoices/58/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### curl — OAuth-приложение ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/invoices/58/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/58/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/58/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив установленных позиций с полями productId, productName, price, quantity, discount, taxRate, taxIncluded | Массив установленных позиций с полями `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 25000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false }, { "productId": 5, "productName": "Установка и настройка", "price": 5000, "quantity": 1, "discount": 500, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 400 — неверный формат: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "items must be an array" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `items` не является массивом | | 404 | `ENTITY_NOT_FOUND` | Счёт не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Полная замена:** PUT заменяет весь список товаров. Чтобы добавить позицию — сначала получите текущие (`GET`), добавьте новую в массив, отправьте всё (`PUT`). ## Смотрите также - [Товарные позиции](/docs/entities/invoices/products-get) — получить текущий список - [Получить счёт](/docs/entities/invoices/get) — основные данные счёта - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Invoices: Products Update ## Обновить товар счёта `PATCH /v1/invoices/:id/products/:rowId` Обновляет товарную позицию счёта. Передайте только изменяемые поля. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID счёта | | `rowId` (path) | number | да | ID товарной позиции (из ответа list или add, не productId из каталога) | ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `price` | number | Цена за единицу | | `quantity` | number | Количество | | `productId` | number | ID товара. Каталог: `GET /v1/products` | | `discount` | number | Сумма скидки | | `taxRate` | number | Ставка налога (%) | | `taxIncluded` | boolean | Налог включён в цену | | `sort` | number | Сортировка | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/invoices/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/invoices/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() console.log('Обновлено:', data.price, 'x', data.quantity) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() ``` ## Поля ответа Обновлённый объект товарной позиции: `id`, `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "Серверное оборудование", "price": 9999, "quantity": 10, "discount": 0, "taxRate": null, "taxIncluded": false } } ``` ## Пример ответа при ошибке 404 — позиция не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Позиция не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить товар](/docs/entities/invoices/products-get-single) — получение одной позиции - [Получить товары](/docs/entities/invoices/products-get) — список всех позиций - [Добавить товар](/docs/entities/invoices/products-add) — добавление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Invoices: Search ## Поиск счетов `POST /v1/invoices/search` Расширенный поиск счетов с фильтрацией, сортировкой и авто-пагинацией. Поддерживает до 5000 записей. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `filter` | object | Фильтрация по полям `GET /v1/invoices/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[stageId]=DT31_5:N` | | `sort` | string | Сортировка. Префикс `-` — по убыванию | | `limit` | number | Количество записей (по умолчанию 50, макс. 5000) | | `select` | array | Список возвращаемых полей | | `autoWindow` | boolean | Авто-разбивка по датам (по умолчанию `true`) | ### Синтаксис фильтров Поддерживаются три формата: ```json { "filter": { ">=opportunity": 100000 } } { "filter": { "opportunity": { "$gte": 100000 } } } { "filter": { "opportunity": { ">=": 100000 } } } ``` ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/invoices/search \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { ">=opportunity": 100000, "assignedById": 1 }, "sort": "-createdTime", "limit": 100 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/invoices/search \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { ">=opportunity": 100000, "assignedById": 1 }, "sort": "-createdTime", "limit": 100 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { '>=opportunity': 100000, assignedById: 1 }, sort: '-createdTime', limit: 100, }), }) const { success, data, total } = await res.json() console.log(`Найдено: ${total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { '>=opportunity': 100000, assignedById: 1 }, sort: '-createdTime', limit: 100, }), }) const { success, data, total } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив счетов | | `total` | number | Общее количество | URL карточки любого счёта из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/type/31/details// ``` `31` — `entityTypeId` смарт-счёта в Битрикс24. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 891, "title": "Счёт за услуги", "stageId": "DT31_5:N", "opportunity": 150000, "currencyId": "RUB", "assignedById": 1, "createdTime": "2026-04-15T14:30:00+03:00" } ], "total": 12 } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидный фильтр или параметры | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список счетов](/docs/entities/invoices/list) — простое получение с фильтрами - [Поля счёта](/docs/entities/invoices/fields) — полный список полей - [Пакетные запросы](/docs/batch) — поиск через batch - [Entity API](/docs/entity-api) — общие принципы --- # Invoices: Update ## Обновить счёт `PATCH /v1/invoices/:id` Обновляет поля счёта. Передавайте только изменяемые поля. ## Параметры запроса | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | ID счёта (в URL) | ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название счёта | | `stageId` | string | Стадия. Формат: `DT31_{categoryId}:{stage}`. Список стадий: `GET /v1/statuses?filter[entityId]=SMART_INVOICE_STAGE_{categoryId}` — categoryId зависит от портала. Узнать: `GET /v1/invoices?limit=1&select=categoryId` или запросить у администратора | | `contactId` | number | ID контакта-плательщика | | `companyId` | number | ID компании-плательщика | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта. Список: `GET /v1/currencies` | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `comments` | string | Комментарий | Полный список полей: [GET /v1/invoices/fields](/docs/entities/invoices/fields). Пользовательские поля (`ufCrm_*`) также принимаются. ## Примеры ### curl — личный ключ ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/invoices/891 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "opportunity": 200000, "stageId": "DT31_5:WON" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/invoices/891 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "opportunity": 200000, "stageId": "DT31_5:WON" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/891', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ opportunity: 200000, stageId: 'DT31_5:WON', }), }) const { success, data } = await res.json() console.log('Обновлён:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/invoices/891', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ opportunity: 200000, stageId: 'DT31_5:WON', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID счёта | | `title` | string | Название | | `stageId` | string | Стадия | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта | | `assignedById` | number | Ответственный | | `updatedTime` | datetime | Дата изменения | Ответ содержит все поля счёта после обновления. ## Пример ответа ```json { "success": true, "data": { "id": 891, "title": "Счёт за услуги", "stageId": "DT31_5:WON", "categoryId": 5, "contactId": 42, "companyId": 15, "opportunity": 200000, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T15:10:00+03:00" } } ``` ## Пример ответа при ошибке 404 — счёт не найден: ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Entity not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Счёт с указанным ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить счёт](/docs/entities/invoices/get) — получение по ID - [Поля счёта](/docs/entities/invoices/fields) — полный список полей - [Создать счёт](/docs/entities/invoices/create) — создание нового счёта - [Entity API](/docs/entity-api) — общие принципы --- # Items: Aggregate ## Агрегация элементов `POST /v1/items/:entityTypeId/aggregate` Подсчёт количества, сумма, среднее, минимум и максимум по элементам смарт-процесса с фильтрацией и группировкой. Смарт-процесс задаётся в пути через `entityTypeId` — ID типа процесса, который можно получить через [GET /v1/smart-processes](/docs/entities/smart-processes/list). **Стандартные поля:** - `opportunity` — сумма элемента (числовое агрегирование имеет смысл) - `categoryId` — категория (для `groupBy`) - `assignedById` — ответственный (для `groupBy`) - `stageId` — стадия (для `groupBy`) - `createdBy` — создал (для `groupBy`) - `updatedBy` — последний изменил (для `groupBy`) **Пользовательские поля (UF):** UF-поля имеют префикс с номером типа: `ufCrm_*` (например, `ufCrm7_1652689362`). Типы `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Основной источник бизнес-данных в смарт-процессах — именно UF. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Path-параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` | number | да | ID типа смарт-процесса. Для пользовательских смарт-процессов — любое положительное целое из `GET /v1/smart-processes`. Значения `1` (лиды), `2` (сделки), `3` (контакты), `4` (компании), `7` (предложения), `31` (счета) зарезервированы — используйте специализированные API: [/v1/deals](/docs/entities/deals/aggregate), [/v1/leads](/docs/entities/leads/aggregate) и т.д. | ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "opportunity", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/items/:entityTypeId/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Принимает стандартные поля и UF-поля любого типа | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/items/177/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "opportunity", "function": "sum" }, { "field": "opportunity", "function": "avg" } ], "filter": { "categoryId": 7 }, "groupBy": "stageId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/items/177/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "opportunity", "function": "sum" }, { "field": "opportunity", "function": "avg" } ], "filter": { "categoryId": 7 }, "groupBy": "stageId" }' ``` ### JavaScript — личный ключ ```javascript const entityTypeId = 177 const res = await fetch(`https://vibecode.bitrix24.tech/v1/items/${entityTypeId}/aggregate`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'opportunity', function: 'sum' }, { field: 'opportunity', function: 'avg' }, ], filter: { categoryId: 7 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() console.log('Всего элементов:', data.count) console.log('По стадиям:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const entityTypeId = 177 const res = await fetch(`https://vibecode.bitrix24.tech/v1/items/${entityTypeId}/aggregate`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'opportunity', function: 'sum' }, { field: 'opportunity', function: 'avg' }, ], filter: { categoryId: 7 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["stageId", "categoryId"]` (максимум 5). ## Другие сценарии Только `count` — самый быстрый запрос, без выгрузки записей: ```json { "filter": { "stageId": "DT177_7:SUCCESS" } } ``` Работа с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF: ```json { "aggregate": [{ "field": "ufCrm7_1741091916816", "function": "sum" }], "groupBy": "ufCrm7_1652689362" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Количество элементов, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций: `{ "opportunity": { "sum": 65911, "avg": 4707.92 } }` | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей было фактически обработано для агрегации | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (агрегации + `groupBy: "stageId"`): ```json { "success": true, "data": { "count": 14, "aggregates": { "opportunity": { "sum": 65911, "avg": 4707.92 } }, "groups": [ { "stageId": "DT177_7:NEW", "count": 8, "aggregates": { "opportunity": { "sum": 40000 } } }, { "stageId": "DT177_7:SUCCESS", "count": 6, "aggregates": { "opportunity": { "sum": 25911 } } } ], "meta": { "totalRecords": 14, "recordsProcessed": 14, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — зарезервированный `entityTypeId` (для стандартных CRM-сущностей): ```json { "success": false, "error": { "code": "INVALID_DYNAMIC_PARAM", "message": "entityTypeId 2 has a dedicated API: use /v1/deals instead" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_DYNAMIC_PARAM` | `entityTypeId` не является положительным целым или является зарезервированным (1, 2, 3, 4, 7, 31) | | 400 | `INVALID_PARAMS` | Невалидное имя функции, несуществующее поле или нечисловое поле в `sum`/`avg`/`min`/`max` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Без массива `aggregate` — только `count`.** Если не передать `aggregate`, метод сделает один быстрый вызов в Битрикс24 и вернёт `count` записей под фильтр. Подходит для счётчиков на дашбордах. **Несколько агрегаций в одном запросе.** Можно объединить в одном вызове: `[{ "field": "opportunity", "function": "sum" }, { "field": "opportunity", "function": "avg" }]`. **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "ufCrm7_1652689362": 1435 } }` вернёт количество элементов с этим значением UF. **Ограничение 5000 записей.** Числовые агрегации подгружают записи постранично и считают на стороне Вайбкод. Если под фильтр попадает больше 5000 записей, результат будет помечен `meta.truncated: true` — берётся только первые 5000. Для точного количества используйте `count` (он работает на любом объёме) или сужайте фильтр. **Зарезервированные `entityTypeId`.** Значения `1` (лиды), `2` (сделки), `3` (контакты), `4` (компании), `7` (предложения), `31` (счета) обслуживаются специализированными API — используйте [/v1/deals/aggregate](/docs/entities/deals/aggregate), [/v1/leads/aggregate](/docs/entities/leads/aggregate), [/v1/contacts/aggregate](/docs/entities/contacts/aggregate), [/v1/companies/aggregate](/docs/entities/companies/aggregate), [/v1/quotes/aggregate](/docs/entities/quotes/aggregate), [/v1/invoices/aggregate](/docs/entities/invoices/aggregate). ## Смотрите также - [Список смарт-процессов](/docs/entities/smart-processes/list) — получить `entityTypeId` для агрегации - [Список элементов](/docs/entities/items/list) — получить записи с фильтрацией - [Поиск элементов](/docs/entities/items/search) — POST-запрос с фильтрами - [Поля смарт-процесса](/docs/entities/items/fields) — список доступных полей для `filter` и `aggregate` - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Items: Create ## Создать элемент смарт-процесса `POST /v1/items/:entityTypeId` Создаёт новый элемент в указанном смарт-процессе. Параметр `entityTypeId` определяет тип смарт-процесса. Узнать доступные типы: `GET /v1/smart-processes`. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название | | `xmlId` | string | Внешний код | | `stageId` | string | Стадия. Формат: `DT{typeId}_{catId}:{stage}`. Список: `GET /v1/statuses?filter[entityId]=DYNAMIC_{entityTypeId}_STAGE_{categoryId}` | | `categoryId` | number | ID воронки | | `contactId` | number | ID контакта. Поиск: `GET /v1/contacts` | | `companyId` | number | ID компании. Поиск: `GET /v1/companies` | | `mycompanyId` | number | ID своей компании | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта. Список: `GET /v1/currencies` | | `opened` | boolean | Доступен для всех | | `begindate` | datetime | Дата начала (ISO 8601) | | `closedate` | datetime | Дата завершения (ISO 8601) | | `sourceId` | string | Источник | | `observers` | array | ID наблюдателей | Полный список полей: [GET /v1/items/:entityTypeId/fields](/docs/entities/items/fields). Пользовательские поля (`ufCrmN_*`) также принимаются. ## Примеры В примерах `entityTypeId = 156` — замените на ID вашего смарт-процесса. ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/items/156 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Новый договор", "categoryId": 41, "assignedById": 1, "companyId": 15, "opportunity": 500000, "currencyId": "RUB" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/items/156 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Новый договор", "categoryId": 41, "assignedById": 1, "companyId": 15, "opportunity": 500000, "currencyId": "RUB" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Новый договор', categoryId: 41, assignedById: 1, companyId: 15, opportunity: 500000, currencyId: 'RUB', }), }) const { success, data } = await res.json() console.log('Item ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Новый договор', categoryId: 41, assignedById: 1, companyId: 15, opportunity: 500000, currencyId: 'RUB', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID элемента | | `title` | string | Название | | `stageId` | string | Стадия | | `categoryId` | number | ID воронки | | `companyId` | number | ID компании | | `contactId` | number | ID контакта | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdTime` | datetime | Дата создания | | `updatedTime` | datetime | Дата изменения | Ответ содержит все поля элемента, включая пользовательские (`ufCrmN_*`). URL карточки элемента в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/crm/type//details// ``` `` — ID типа смарт-процесса (тот же, что в пути запроса). `` — домен портала. Если смарт-процесс вынесен в кастомный раздел портала, Битрикс24 автоматически перенаправит на соответствующий путь. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 783, "title": "Новый договор", "stageId": "DT156_41:NEW", "categoryId": 41, "companyId": 15, "contactId": null, "opportunity": 500000, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T14:30:00+03:00" } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля или несуществующий entityTypeId | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список элементов](/docs/entities/items/list) — получение с фильтрами - [Поля элемента](/docs/entities/items/fields) — полный список полей для типа - [Смарт-процессы](/docs/entities/smart-processes) — получение entityTypeId - [Контакты](/docs/entities/contacts) — привязка через `contactId` - [Компании](/docs/entities/companies) — привязка через `companyId` - [Entity API](/docs/entity-api) — общие принципы --- # Items: Delete ## Удалить элемент `DELETE /v1/items/:entityTypeId/:id` Удаляет элемент смарт-процесса по ID. Восстановить удалённый элемент через API нельзя — создавайте новый при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` (path) | number | да | ID типа смарт-процесса. Получить: [GET /v1/smart-processes](/docs/entities/smart-processes/list). Зарезервированные значения (`1`, `2`, `3`, `4`, `7`, `31`) обслуживаются специализированными API: `/v1/leads`, `/v1/deals`, `/v1/contacts`, `/v1/companies`, `/v1/quotes`, `/v1/invoices` | | `id` (path) | number | да | ID элемента | ## Примеры В примерах `entityTypeId = 177`, `id = 783` — замените на ваши значения. ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/items/177/783" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/items/177/783" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/177/783', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) if (res.status === 204) { console.log('Элемент удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/177/783', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 400 — зарезервированный `entityTypeId` (для стандартных CRM-сущностей): ```json { "success": false, "error": { "code": "INVALID_DYNAMIC_PARAM", "message": "entityTypeId 2 has a dedicated API: use /v1/deals instead" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_DYNAMIC_PARAM` | `entityTypeId` не является положительным целым или является зарезервированным (1, 2, 3, 4, 7, 31) | | 404 | `ENTITY_NOT_FOUND` | Элемент с указанным ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список элементов](/docs/entities/items/list) — найти перед удалением - [Создать элемент](/docs/entities/items/create) — создание нового элемента - [Смарт-процессы](/docs/entities/smart-processes/list) — получение `entityTypeId` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Items: Fields ## Поля элемента смарт-процесса `GET /v1/items/:entityTypeId/fields` Возвращает описание всех полей для указанного типа смарт-процесса, включая пользовательские (`ufCrmN_*`) и родительские ссылки (`parentIdN`). Набор полей зависит от `entityTypeId` — каждый тип смарт-процесса имеет собственные пользовательские поля. ## Примеры В примерах `entityTypeId = 156` — замените на ID вашего смарт-процесса. ### curl — личный ключ ```bash curl -X GET https://vibecode.bitrix24.tech/v1/items/156/fields \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET https://vibecode.bitrix24.tech/v1/items/156/fields \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Только чтение | Описание | |------|-----|:---:|---------| | `id` | number | да | ID элемента | | `title` | string | | Название | | `xmlId` | string | | Внешний код | | `stageId` | string | | Стадия. Формат: `DT{typeId}_{catId}:{stage}` | | `categoryId` | number | | ID воронки | | `assignedById` | number | | Ответственный. Список: `GET /v1/users` | | `companyId` | number | | ID компании. Поиск: `GET /v1/companies` | | `contactId` | number | | ID контакта. Поиск: `GET /v1/contacts` | | `contactIds` | array | да | Привязанные контакты | | `opportunity` | number | | Сумма | | `currencyId` | string | | Валюта. Список: `GET /v1/currencies` | | `opened` | boolean | | Доступен для всех | | `begindate` | datetime | | Дата начала | | `closedate` | datetime | | Дата завершения | | `sourceId` | string | | Источник | | `observers` | array | | Наблюдатели | | `mycompanyId` | number | | ID своей компании | | `createdBy` | number | да | Создатель | | `updatedBy` | number | да | Последний редактор | | `movedBy` | number | да | Переместил стадию | | `createdTime` | datetime | да | Дата создания | | `updatedTime` | datetime | да | Дата изменения | | `movedTime` | datetime | да | Дата смены стадии | | `isManualOpportunity` | boolean | | Сумма задана вручную (`Y`/`N` → `true`/`false`) | | `isRecurring` | boolean | да | Признак регулярного элемента | | `lastActivityTime` | datetime | да | Время последней активности | `isManualOpportunity` и `isRecurring` приходят от Bitrix24 строкой `"Y"`/`"N"` — платформа нормализует их в JSON-`boolean` на чтении (и принимает `true`/`false` на запись для `isManualOpportunity`), как и `opened`. Пользовательские поля (`ufCrmN_*`) и родительские ссылки (`parentIdN`) зависят от конкретного смарт-процесса. Для полей типа `enumeration` ответ содержит массив `items` с доступными значениями. > **Нульность.** Многие поля приходят `null`, когда не заполнены — в частности `xmlId`, `sourceDescription`, `lastActivityTime` и UTM-поля (`utmSource`/`utmMedium`/`utmCampaign`/`utmContent`/`utmTerm`, если включены на портале). Типобезопасным клиентам (TS) объявляйте такие поля как `T | null`. > ⚠ **`/fields` отражает живой контракт Bitrix24, а не форму платформенных доков.** Это проброс схемы B24 `crm.item.fields` как есть: типы приходят в B24-нотации (`integer` вместо `number`, плюс `double`, `crm_contact`, `crm_status`, `user`), флаг — `readonly` (а не `isReadOnly`), у части полей `label` вместо `title`, отдельного `isRequired` нет. Схема также объявляет поля-привязки вроде `contacts` (тип `crm_contact`) — это **входной** формат для create/update на стороне B24; в данных list/get таких ключей нет, привязки читаются через `contactId` / `contactIds` (проверено на живом портале, VB-d79c55b8). Системные поля, которые B24 отдаёт в list/get но не описаны выше (`taxValue`, `webformId`, `previousStageId`, `lastActivityBy`, `lastCommunication*`, `utm*`), проходят сквозным проксированием. ## Пример ответа ```json { "success": true, "data": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "ufCrm156_custom": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Пользовательское поле" }, "parentId2": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Сделка" } } } ``` ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `RESERVED_ENTITY_TYPE` | entityTypeId зарезервирован | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать элемент](/docs/entities/items/create) — создание с полями - [Список элементов](/docs/entities/items/list) — фильтрация по полям - [Смарт-процессы](/docs/entities/smart-processes) — получение entityTypeId - [Entity API](/docs/entity-api) — общие принципы --- # Items: Get ## Получить элемент смарт-процесса `GET /v1/items/:entityTypeId/:id` Возвращает элемент смарт-процесса по ID. ## Параметры запроса | Параметр | Тип | Описание | |----------|-----|---------| | `entityTypeId` | number | ID типа смарт-процесса (в URL) | | `id` | number | ID элемента (в URL) | ## Примеры В примерах `entityTypeId = 156`, `id = 783` — замените на ваши значения. ### curl — личный ключ ```bash curl -X GET https://vibecode.bitrix24.tech/v1/items/156/783 \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET https://vibecode.bitrix24.tech/v1/items/156/783 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/783', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() console.log('Элемент:', data.title) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/783', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID элемента | | `title` | string | Название | | `xmlId` | string | Внешний код | | `stageId` | string | Стадия | | `categoryId` | number | ID воронки | | `companyId` | number | ID компании | | `contactId` | number | ID контакта | | `contactIds` | array | Привязанные контакты | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта | | `opened` | boolean | Доступен для всех | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `updatedBy` | number | Последний редактор | | `movedBy` | number | Переместил стадию | | `createdTime` | datetime | Дата создания | | `updatedTime` | datetime | Дата изменения | | `movedTime` | datetime | Дата смены стадии | | `observers` | array | Наблюдатели | Ответ содержит все поля элемента, включая пользовательские (`ufCrmN_*`) и родительские ссылки (`parentIdN`). ## Пример ответа ```json { "success": true, "data": { "id": 783, "title": "Договор на поставку", "xmlId": null, "stageId": "DT156_41:NEW", "categoryId": 41, "companyId": 15, "contactId": 42, "contactIds": [42], "opportunity": 500000, "currencyId": "RUB", "opened": true, "assignedById": 1, "createdBy": 1, "updatedBy": 1, "movedBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T14:30:00+03:00", "movedTime": "2026-04-15T14:30:00+03:00", "observers": [1, 5], "mycompanyId": 0 } } ``` ## Пример ответа при ошибке 404 — элемент не найден: ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Entity not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Элемент с указанным ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `RESERVED_ENTITY_TYPE` | entityTypeId зарезервирован | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список элементов](/docs/entities/items/list) — получение с фильтрами - [Обновить элемент](/docs/entities/items/update) — изменение полей - [Поля элемента](/docs/entities/items/fields) — полный список полей для типа - [Смарт-процессы](/docs/entities/smart-processes) — получение entityTypeId - [Entity API](/docs/entity-api) — общие принципы --- # Items: List ## Список элементов смарт-процесса `GET /v1/items/:entityTypeId` Возвращает список элементов указанного смарт-процесса с фильтрацией, сортировкой и пагинацией. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `entityTypeId` (path) | number | — | ID типа смарт-процесса. Список: `GET /v1/smart-processes` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `?order[createdTime]=desc` | | `select` | string | — | Выборка полей: `?select=id,title,stageId` | | `filter` | object | — | Фильтрация по полям `GET /v1/items/:entityTypeId/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[assignedById]=1` | ## Примеры В примерах `entityTypeId = 156` — замените на ID вашего смарт-процесса. ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/items/156?limit=10&sort=-createdTime&filter[assignedById]=1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/items/156?limit=10&sort=-createdTime&filter[assignedById]=1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const params = new URLSearchParams({ limit: '10', sort: '-createdTime', 'filter[assignedById]': '1', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/items/156?${params}`, { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data, meta } = await res.json() console.log(`Найдено: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const params = new URLSearchParams({ limit: '10', sort: '-createdTime', 'filter[assignedById]': '1', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/items/156?${params}`, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа Пагинация возвращается в объекте `meta` (как у всех списочных эндпоинтов платформы), **не** на верхнем уровне. | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив элементов | | `meta.total` | number | Общее количество записей | | `meta.hasMore` | boolean | Есть ли ещё страницы | | `data[].id` | number | ID элемента | | `data[].title` | string | Название | | `data[].stageId` | string | Стадия | | `data[].categoryId` | number | ID воронки | | `data[].opportunity` | number | Сумма | | `data[].currencyId` | string | Валюта | | `data[].assignedById` | number | Ответственный | | `data[].createdTime` | datetime | Дата создания | URL карточки любого элемента из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/type//details// ``` `` — ID типа смарт-процесса (тот же, что в пути запроса). `` — домен портала. Если смарт-процесс вынесен в кастомный раздел портала, Битрикс24 автоматически перенаправит на соответствующий путь. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 783, "title": "Договор на поставку", "stageId": "DT156_41:NEW", "categoryId": 41, "companyId": 15, "contactId": 42, "opportunity": 500000, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T14:30:00+03:00" } ], "meta": { "total": 23, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `RESERVED_ENTITY_TYPE` | entityTypeId зарезервирован (например, 2 для сделок). Используйте выделенный эндпоинт | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить элемент](/docs/entities/items/get) — получение по ID - [Поиск элементов](/docs/entities/items/search) — расширенный поиск - [Поля элемента](/docs/entities/items/fields) — полный список полей - [Смарт-процессы](/docs/entities/smart-processes) — получение entityTypeId - [Entity API](/docs/entity-api) — общие принципы - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Items: Products Add ## Добавить товар в элемент смарт-процесса `POST /v1/items/:entityTypeId/:id/products` Добавляет одну товарную позицию в элемент смарт-процесса. В отличие от `PUT /v1/items/:entityTypeId/:id/products`, не заменяет существующие позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` (path) | number | да | ID типа смарт-процесса | | `id` (path) | number | да | ID элемента | | `productId` | number | нет | ID товара из каталога. Если задан без `productName`, имя подставляется из каталога. Каталог: `GET /v1/products` | | `productName` | string | нет | Название товарной позиции — для произвольной строки без товара из каталога. Укажите хотя бы одно из `productId` / `productName`. | | `price` | number | нет | Цена за единицу | | `quantity` | number | нет | Количество | | `discount` | number | нет | Сумма скидки | | `taxRate` | number | нет | Ставка налога (%) | | `taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/items/180/47/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/items/180/47/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/180/47/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() console.log('ID строки:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/180/47/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID созданной товарной строки | ## Пример ответа ```json { "success": true, "data": { "id": 1465 } } ``` ## Пример ответа при ошибке 404 — элемент не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Элемент не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/items/products-get) — получить текущий список - [Установить товары](/docs/entities/items/products-set) — заменить все позиции - [Удалить товар](/docs/entities/items/products-delete) — удалить одну позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Items: Products Delete ## Удалить товар из элемента смарт-процесса `DELETE /v1/items/:entityTypeId/:id/products/:rowId` Удаляет одну товарную позицию из элемента смарт-процесса по ID строки. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` (path) | number | да | ID типа смарт-процесса | | `id` (path) | number | да | ID элемента | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/items/180/47/products/1465" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/items/180/47/products/1465" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/180/47/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/180/47/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | boolean | `true` при успешном удалении | ## Пример ответа ```json { "success": true, "data": true } ``` ## Пример ответа при ошибке 404 — элемент не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Элемент или товарная строка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/items/products-get) — получить текущий список - [Добавить товар](/docs/entities/items/products-add) — добавить позицию - [Установить товары](/docs/entities/items/products-set) — заменить все позиции - [Товары каталога](/docs/entities/products) — справочник товаров --- # Items: Products Fields ## Поля товаров элемента `GET /v1/items/:entityTypeId/:id/products/fields` Возвращает описание полей товарных позиций элемента: названия, типы, доступность для чтения и записи. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID элемента | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/items/156/741/products/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/items/156/741/products/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Обяз. | Описание | |------|-----|:--:|:-----:|---------| | `id` | integer | да | | ID позиции | | `productId` | integer | | да | ID товара. Каталог: `GET /v1/products` | | `productName` | string | | | Название товара | | `price` | double | | | Цена | | `quantity` | double | | | Количество | | `discountSum` | double | | | Сумма скидки | | `discountRate` | double | | | Величина скидки (%) | | `discountTypeId` | integer | | | Тип скидки | | `taxRate` | double | | | Налог (%) | | `taxIncluded` | char | | | Налог включён в цену (`Y`/`N`) | | `priceExclusive` | double | да | | Цена без налога со скидкой | | `priceNetto` | double | да | | Цена нетто | | `priceBrutto` | double | да | | Цена брутто | | `measureCode` | integer | | | Код единицы измерения | | `measureName` | string | | | Единица измерения | | `customized` | char | | | Изменён (`Y`/`N`) | | `sort` | integer | | | Сортировка | | `type` | integer | да | | Тип | | `storeId` | integer | да | | ID склада | | `ownerId` | integer | | да | ID владельца (элемента) | | `ownerType` | string | | да | Тип владельца | ## Пример ответа ```json { "success": true, "data": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "ownerId": { "type": "integer", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "ID владельца" }, "ownerType": { "type": "string", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "Тип владельца" }, "productId": { "type": "integer", "isRequired": true, "isReadOnly": false, "title": "Товар" }, "productName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название товара" }, "price": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Цена" }, "priceExclusive": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "Цена без налога со скидкой" }, "priceNetto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_NETTO" }, "priceBrutto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_BRUTTO" }, "quantity": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Количество" }, "discountTypeId": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Тип скидки" }, "discountRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Величина скидки" }, "discountSum": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Сумма скидки" }, "taxRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Налог" }, "taxIncluded": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Налог включен в цену" }, "customized": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Изменен" }, "measureCode": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Код единицы измерения" }, "measureName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Единица измерения" }, "sort": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Сортировка" }, "type": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "TYPE" }, "storeId": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "STORE_ID" } } } ``` ## Пример ответа при ошибке 404 — элемент не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Элемент не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/items/products-get) — получить товары элемента - [Добавить товар](/docs/entities/items/products-add) — добавить позицию - [Установить товары](/docs/entities/items/products-set) — заменить все позиции - [Поля элемента](/docs/entities/items/fields) — описание полей элемента --- # Items: Products Get ## Товарные позиции элемента `GET /v1/items/:entityTypeId/:id/products` Возвращает список товарных позиций, привязанных к элементу смарт-процесса. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID элемента | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/items/156/741/products" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/items/156/741/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Товаров:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив товарных позиций | | `data[].productId` | number | ID товара. Каталог: `GET /v1/products` | | `data[].productName` | string | Название товара | | `data[].price` | number | Цена за единицу | | `data[].quantity` | number | Количество | | `data[].discount` | number | Сумма скидки | | `data[].taxRate` | number/null | Ставка налога (%) | | `data[].taxIncluded` | boolean | Налог включён в цену | Показаны основные поля. Полный список (20 полей, включая priceAccount, measureCode и др.): [Поля товаров](/docs/entities/items/products-fields). ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 1000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 404 — элемент не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Элемент не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Установить товары](/docs/entities/items/products-set) — заменить товарные позиции - [Получить элемент](/docs/entities/items/get) — основные данные элемента - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Items: Products Get Single ## Получить товар из элемента `GET /v1/items/:entityTypeId/:id/products/:rowId` Возвращает одну товарную позицию элемента по ID строки. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID элемента | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/items/156/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/items/156/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Цена:', data.price) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID товарной строки | | `data.productId` | number | ID товара из каталога | | `data.productName` | string | Название товара | | `data.price` | number | Цена за единицу | | `data.quantity` | number | Количество | | `data.discount` | number | Сумма скидки | | `data.discountRate` | number | Процент скидки | | `data.discountTypeId` | number | Тип скидки (1 — сумма, 2 — процент) | | `data.taxRate` | number \| null | Ставка налога (%) | | `data.taxIncluded` | boolean | Налог включён в цену | | `data.priceExclusive` | number | Цена без скидки | | `data.priceNetto` | number | Цена нетто | | `data.priceBrutto` | number | Цена брутто | | `data.priceAccount` | number | Цена в валюте учёта | | `data.measureCode` | number | Код единицы измерения | | `data.measureName` | string | Название единицы измерения | | `data.sort` | number | Сортировка | ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "День добрый!", "price": 5000, "priceAccount": 5000, "priceExclusive": 5000, "priceNetto": 5000, "priceBrutto": 5000, "quantity": 3, "discountTypeId": 2, "discountRate": 0, "discount": 0, "taxRate": null, "taxIncluded": false, "customized": "Y", "measureCode": 796, "measureName": "шт", "sort": 0, "xmlId": "sale_basket_995", "type": 1 } } ``` ## Пример ответа при ошибке 404 — элемент или товарная строка не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Элемент или товарная строка не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/items/products-get) — получить все позиции - [Обновить товар](/docs/entities/items/products-update) — обновить позицию - [Добавить товар](/docs/entities/items/products-add) — добавить позицию - [Удалить товар](/docs/entities/items/products-delete) — удалить позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Items: Products Set ## Установить товары элемента смарт-процесса `PUT /v1/items/:entityTypeId/:id/products` Устанавливает товарные позиции элемента смарт-процесса. Полностью заменяет текущий список — передайте все нужные позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` (path) | number | да | ID типа смарт-процесса | | `id` (path) | number | да | ID элемента | | `items` | array | да | Массив товарных позиций | | `items[].productId` | number | да | ID товара. Каталог: `GET /v1/products` | | `items[].price` | number | да | Цена за единицу | | `items[].quantity` | number | да | Количество | | `items[].discount` | number | нет | Сумма скидки | | `items[].taxRate` | number | нет | Ставка налога (%) | | `items[].taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/items/180/47/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### curl — OAuth-приложение ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/items/180/47/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/180/47/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/180/47/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа Массив установленных позиций с полями `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 25000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false }, { "productId": 5, "productName": "Установка и настройка", "price": 5000, "quantity": 1, "discount": 500, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 400 — неверный формат: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "items must be an array" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `items` не является массивом | | 404 | `ENTITY_NOT_FOUND` | Элемент не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Полная замена:** PUT заменяет весь список товаров. Чтобы добавить позицию — сначала получите текущие (`GET`), добавьте новую в массив, отправьте всё (`PUT`). ## Смотрите также - [Товарные позиции](/docs/entities/items/products-get) — получить текущий список - [Получить элемент](/docs/entities/items/get) — основные данные элемента - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Items: Products Update ## Обновить товар элемента `PATCH /v1/items/:entityTypeId/:id/products/:rowId` Обновляет товарную позицию элемента. Передайте только изменяемые поля. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID элемента | | `rowId` (path) | number | да | ID товарной позиции (из ответа list или add, не productId из каталога) | ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `price` | number | Цена за единицу | | `quantity` | number | Количество | | `productId` | number | ID товара. Каталог: `GET /v1/products` | | `discount` | number | Сумма скидки | | `taxRate` | number | Ставка налога (%) | | `taxIncluded` | boolean | Налог включён в цену | | `sort` | number | Сортировка | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/items/156/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/items/156/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() console.log('Обновлено:', data.price, 'x', data.quantity) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() ``` ## Поля ответа Обновлённый объект товарной позиции: `id`, `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "Серверное оборудование", "price": 9999, "quantity": 10, "discount": 0, "taxRate": null, "taxIncluded": false } } ``` ## Пример ответа при ошибке 404 — позиция не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Позиция не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить товар](/docs/entities/items/products-get-single) — получение одной позиции - [Получить товары](/docs/entities/items/products-get) — список всех позиций - [Добавить товар](/docs/entities/items/products-add) — добавление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Items: Search ## Поиск элементов смарт-процесса `POST /v1/items/:entityTypeId/search` Расширенный поиск элементов с фильтрацией, сортировкой и авто-пагинацией. Поддерживает до 5000 записей. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `filter` | object | Фильтрация по полям `GET /v1/items/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[assignedById]=1` | | `sort` | string | Сортировка. Префикс `-` — по убыванию | | `limit` | number | Количество записей (по умолчанию 50, макс. 5000) | | `select` | array | Список возвращаемых полей | | `autoWindow` | boolean | Авто-разбивка по датам (по умолчанию `true`) | ### Синтаксис фильтров Поддерживаются три формата: ```json { "filter": { ">=opportunity": 100000 } } { "filter": { "opportunity": { "$gte": 100000 } } } { "filter": { "opportunity": { ">=": 100000 } } } ``` ## Примеры В примерах `entityTypeId = 156` — замените на ID вашего смарт-процесса. ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/items/156/search \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "assignedById": 1, "stageId": "DT156_41:NEW" }, "select": ["id", "title", "opportunity", "stageId"], "sort": "-createdTime", "limit": 100 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/items/156/search \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "assignedById": 1, "stageId": "DT156_41:NEW" }, "select": ["id", "title", "opportunity", "stageId"], "sort": "-createdTime", "limit": 100 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { assignedById: 1, stageId: 'DT156_41:NEW' }, select: ['id', 'title', 'opportunity', 'stageId'], sort: '-createdTime', limit: 100, }), }) const { success, data, total } = await res.json() console.log(`Найдено: ${total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { assignedById: 1, stageId: 'DT156_41:NEW' }, select: ['id', 'title', 'opportunity', 'stageId'], sort: '-createdTime', limit: 100, }), }) const { success, data, total } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив элементов | | `total` | number | Общее количество | URL карточки любого элемента из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/type//details// ``` `` — ID типа смарт-процесса (тот же, что в пути запроса). `` — домен портала. Если смарт-процесс вынесен в кастомный раздел портала, Битрикс24 автоматически перенаправит на соответствующий путь. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 783, "title": "Договор на поставку", "stageId": "DT156_41:NEW", "opportunity": 500000 } ], "total": 5 } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидный фильтр или параметры | | 400 | `RESERVED_ENTITY_TYPE` | entityTypeId зарезервирован | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список элементов](/docs/entities/items/list) — простое получение с фильтрами - [Поля элемента](/docs/entities/items/fields) — полный список полей - [Пакетные запросы](/docs/batch) — поиск через batch - [Смарт-процессы](/docs/entities/smart-processes) — получение entityTypeId - [Entity API](/docs/entity-api) — общие принципы --- # Items: Update ## Обновить элемент смарт-процесса `PATCH /v1/items/:entityTypeId/:id` Обновляет поля элемента смарт-процесса. Передавайте только изменяемые поля. ## Параметры запроса | Параметр | Тип | Описание | |----------|-----|---------| | `entityTypeId` | number | ID типа смарт-процесса (в URL) | | `id` | number | ID элемента (в URL) | ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название | | `stageId` | string | Стадия. Список: `GET /v1/statuses?filter[entityId]=DYNAMIC_{entityTypeId}_STAGE_{categoryId}` | | `contactId` | number | ID контакта | | `companyId` | number | ID компании | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта. Список: `GET /v1/currencies` | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `opened` | boolean | Доступен для всех | | `begindate` | datetime | Дата начала (ISO 8601) | | `closedate` | datetime | Дата завершения (ISO 8601) | | `observers` | array | ID наблюдателей | Полный список полей: [GET /v1/items/:entityTypeId/fields](/docs/entities/items/fields). Пользовательские поля (`ufCrmN_*`) также принимаются. ## Примеры В примерах `entityTypeId = 156`, `id = 783` — замените на ваши значения. ### curl — личный ключ ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/items/156/783 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stageId": "DT156_41:WON", "opportunity": 750000 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/items/156/783 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "stageId": "DT156_41:WON", "opportunity": 750000 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/783', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'DT156_41:WON', opportunity: 750000, }), }) const { success, data } = await res.json() console.log('Обновлён:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/items/156/783', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'DT156_41:WON', opportunity: 750000, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID элемента | | `title` | string | Название | | `stageId` | string | Стадия | | `opportunity` | number | Сумма | | `assignedById` | number | Ответственный | | `updatedBy` | number | Последний редактор | | `updatedTime` | datetime | Дата изменения | Ответ содержит все поля элемента после обновления. ## Пример ответа ```json { "success": true, "data": { "id": 783, "title": "Договор на поставку", "stageId": "DT156_41:WON", "categoryId": 41, "companyId": 15, "contactId": 42, "opportunity": 750000, "currencyId": "RUB", "assignedById": 1, "createdBy": 1, "updatedBy": 1, "movedBy": 1, "createdTime": "2026-04-15T14:30:00+03:00", "updatedTime": "2026-04-15T16:45:00+03:00", "movedTime": "2026-04-15T16:45:00+03:00" } } ``` ## Пример ответа при ошибке 404 — элемент не найден: ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Entity not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Элемент с указанным ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить элемент](/docs/entities/items/get) — получение по ID - [Поля элемента](/docs/entities/items/fields) — полный список полей - [Создать элемент](/docs/entities/items/create) — создание нового элемента - [Entity API](/docs/entity-api) — общие принципы --- # Leads: Aggregate ## Агрегация лидов `POST /v1/leads/aggregate` Подсчёт количества, сумма, среднее, минимум и максимум по лидам с фильтрацией и группировкой. **Стандартные поля:** - `amount` — предполагаемая сумма (числовое агрегирование имеет смысл) - `statusId` — статус (для `groupBy`) - `sourceId` — источник (для `groupBy`) - `assignedById` — ответственный (для `groupBy`) **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "amount", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/leads/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/leads/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "sourceId": "WEB" }, "groupBy": "statusId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/leads/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "sourceId": "WEB" }, "groupBy": "statusId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'amount', function: 'sum' }, { field: 'amount', function: 'avg' }, ], filter: { sourceId: 'WEB' }, groupBy: 'statusId', }), }) const { success, data } = await res.json() console.log('Всего лидов:', data.count) console.log('По статусам:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'amount', function: 'sum' }, { field: 'amount', function: 'avg' }, ], filter: { sourceId: 'WEB' }, groupBy: 'statusId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["statusId", "sourceId"]` (максимум 5). ## Другие сценарии Только `count` — самый быстрый запрос, без выгрузки записей: ```json { "filter": { "statusId": "NEW" } } ``` Работа с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF: ```json { "aggregate": [{ "field": "UF_CRM_BUDGET", "function": "sum" }], "groupBy": "UF_CRM_PRIORITY" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций: `{ "amount": { "sum": 500000, "avg": 5000 } }` | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей обработано для числовых агрегаций (максимум 5000) | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (агрегации + `groupBy: "statusId"`): ```json { "success": true, "data": { "count": 100, "aggregates": { "amount": { "sum": 500000, "avg": 5000 } }, "groups": [ { "statusId": "NEW", "count": 60, "aggregates": { "amount": { "sum": 300000 } } }, { "statusId": "CONVERTED", "count": 40, "aggregates": { "amount": { "sum": 200000 } } } ], "meta": { "totalRecords": 100, "recordsProcessed": 100, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неверное имя функции, несуществующее поле или `groupBy` по неаггрегируемому полю: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Field 'foo' not found. Available numeric fields: statusId, amount, sourceId, assignedById" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Невалидное имя функции, несуществующее поле, нечисловое поле в `sum`/`avg`/`min`/`max`, `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` vs числовые функции.** `count` считается одним вызовом в Битрикс24 на любом объёме данных. Функции `sum`/`avg`/`min`/`max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод — если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true`, агрегация выполнится по первым 5000. Для точных счётчиков на больших выборках используйте `count` или сужайте фильтр. **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "ufCrm_1234": "value" } }` вернёт количество лидов с этим значением UF. ## Смотрите также - [Список лидов](/docs/entities/leads/list) — получить записи с фильтрацией - [Поиск лидов](/docs/entities/leads/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Create ## Создать лид `POST /v1/leads` Создаёт новый лид в CRM. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название лида | | `name` | string | Имя контакта | | `lastName` | string | Фамилия контакта | | `secondName` | string | Отчество | | `stageId` | string | Статус лида (каноническое имя; принимается и алиас `statusId`). Стандартные: `NEW`, `IN_PROCESS`, `PROCESSED`. Портал может иметь свои — список: `GET /v1/statuses?filter[entityId]=STATUS`. В ответе значение возвращается в поле `stageId` | | `opportunity` | number | Сумма (каноническое имя; принимается и алиас `amount`). ⚠ Чтобы значение сохранилось, передайте в том же запросе `isManualOpportunity: true` — иначе B24 пересчитает сумму по товарным позициям | | `isManualOpportunity` | boolean | Ручной режим суммы (см. `opportunity`) | | `currency` | string | Валюта (алиас `currencyId`). Список: `GET /v1/currencies` | | `companyTitle` | string | Название компании (текст, не ID) | | `phone` | string \| string[] \| object[] | Телефон. Принимает три формы: строка `"+7..."`, массив строк `["+7...", "+7..."]`, или массив объектов `[{ "value": "+7...", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MOBILE \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `email` | string \| string[] \| object[] | Email. Принимает три формы: строка `"a@b.com"`, массив строк `["a@b.com", "b@c.com"]`, или массив объектов `[{ "value": "a@b.com", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MAILING \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `post` | string | Должность | | `comments` | string | Комментарий | | `sourceId` | string | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | string | Описание источника | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `opened` | boolean | Доступен для всех | Полный список полей: [GET /v1/leads/fields](/docs/entities/leads/fields). ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/leads \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Заявка с сайта", "name": "Мария", "lastName": "Сидорова", "phone": "+79161234567", "sourceId": "WEB", "stageId": "NEW" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/leads \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Заявка с сайта", "name": "Мария", "lastName": "Сидорова", "phone": "+79161234567", "sourceId": "WEB", "stageId": "NEW" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Заявка с сайта', name: 'Мария', lastName: 'Сидорова', phone: '+79161234567', sourceId: 'WEB', stageId: 'NEW', }), }) const { success, data } = await res.json() console.log('Lead ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Заявка с сайта', name: 'Мария', lastName: 'Сидорова', phone: '+79161234567', sourceId: 'WEB', stageId: 'NEW', }), }) const { success, data } = await res.json() ``` ### Альтернативная форма — массив объектов с явным `typeId` Если нужно указать несколько значений или явный тип (`HOME`, `MOBILE`): ```json { "phone": [ { "value": "+79161234567", "typeId": "WORK" }, { "value": "+79161112233", "typeId": "MOBILE" } ], "email": [ { "value": "work@company.ru", "typeId": "WORK" }, { "value": "personal@me.ru", "typeId": "HOME" } ] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного лида | | `title` | string | Название | | `stageId` | string | Статус (стадия) лида | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdTime` | datetime | Дата создания | Ответ содержит все поля лида. URL карточки лида в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/crm/lead/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 5001, "title": "Заявка с сайта", "stageId": "NEW", "assignedById": 1, "createdBy": 1, "createdTime": "2026-04-15T13:00:00+03:00", "updatedTime": "2026-04-15T13:00:00+03:00", "opened": true, "sourceId": "WEB" } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Конвертация лида:** B24 REST не имеет отдельного метода конвертации. Чтобы «конвертировать» лид, создайте сделку/контакт/компанию с `leadId` и обновите статус лида: ```javascript // 1. Создать сделку из лида await fetch('/v1/deals', { body: { title: 'Из лида', leadId: 5001 } }) // 2. Закрыть лид await fetch('/v1/leads/5001', { method: 'PATCH', body: { statusId: 'CONVERTED' } }) ``` ## Смотрите также - [Список лидов](/docs/entities/leads/list) — получение с фильтрами - [Поля лида](/docs/entities/leads/fields) — полный список полей - [Сделки](/docs/entities/deals) — создание сделки из лида через `leadId` - [Entity API](/docs/entity-api) — общие принципы - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Delete ## Удалить лид `DELETE /v1/leads/:id` Удаляет лид по ID. Восстановить удалённый лид через API нельзя — создавайте новый при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/leads/42" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/leads/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Лид удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — лид не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид не найден | | 403 | `ACCESS_DENIED` | Нет доступа | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список лидов](/docs/entities/leads/list) — найти перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Fields ## Поля лида `GET /v1/leads/fields` Возвращает полный список доступных полей, включая пользовательские (`ufCrm_*`). ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/leads/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/leads/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | ID лида | | `title` | string | | Название лида | | `name` | string | | Имя | | `lastName` | string | | Фамилия | | `secondName` | string | | Отчество | | `stageId` | string | | Статус (стадия) лида — каноническое имя в ответах: `NEW`, `IN_PROCESS`, … Список: `GET /v1/statuses?filter[entityId]=STATUS` | | `statusId` | string | | Алиас `stageId` на запись/в фильтрах. ⚠ В ответах list/get значение приходит в поле `stageId`; ключ `statusId` в данных B24 всегда `null` — читайте `stageId`. Не передавайте алиас и каноническое имя одновременно в одном запросе | | `companyTitle` | string | | Название компании | | `companyId` | number | | ID компании. Поиск: `GET /v1/companies` | | `contactId` | number | | ID контакта. Поиск: `GET /v1/contacts` | | `opportunity` | number | | Сумма — каноническое имя в ответах. ⚠ Чтобы записанное значение сохранилось, B24 требует `isManualOpportunity: true` в том же запросе | | `amount` | number | | Алиас `opportunity` на запись/в фильтрах. В ответах значение приходит в поле `opportunity` | | `isManualOpportunity` | boolean | | Ручной режим суммы. Без `true` B24 пересчитывает `opportunity` по товарным позициям и затирает записанное значение | | `currency` | string | | Алиас `currencyId` на запись/в фильтрах. Валюта. Список: `GET /v1/currencies` | | `currencyId` | string | | Валюта — каноническое имя в ответах | | `sourceId` | string | | Источник. Список: `GET /v1/statuses?filter[entityId]=SOURCE` | | `sourceDescription` | string | | Описание источника | | `assignedById` | number | | Ответственный. Список: `GET /v1/users` | | `createdBy` | number | да | Создатель. Поиск: `GET /v1/users` | | `opened` | boolean | | Доступен для всех | | `comments` | string | | Комментарий | | `post` | string | | Должность | | `phone` | multifield | | Телефон. На вход (POST/PATCH) принимает `string \| string[] \| object[]`; на выходе — алиасы `phone`/`phoneWork`/`phoneMobile`/… плюс полный `fm[]`. ⚠ PATCH **только добавляет** новые записи — старые `phone` не удаляются (особенность B24 `crm.item.update`). См. [Обновить лид](/docs/entities/leads/update). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]`. | | `email` | multifield | | Email. На вход принимает `string \| string[] \| object[]`; на выходе — алиасы `email`/`emailWork`/`emailHome`/`emailMailing` плюс полный `fm[]`. ⚠ PATCH **только добавляет** новые записи — старые `email` не удаляются (особенность B24 `crm.item.update`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]`. | | `createdTime` | datetime | да | Дата создания | | `updatedTime` | datetime | да | Дата изменения | **Пользовательские поля** (`ufCrm_*`) также возвращаются в ответах и принимаются при создании/обновлении. ## Доступные include Эндпоинт `GET /v1/leads/fields` возвращает список доступных include: `contact`, `company`. Пример использования: [Получить leads](/docs/entities/leads/get#связанные-данные). Подробнее об include: [Связанные данные](/docs/includes). ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "assignedById": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Ответственный" } } } } ``` Показаны 3 из множества полей. Полный список в таблице выше. ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить лид](/docs/entities/leads/update) — какие поля передавать - [Конвертация лидов](/docs/entities/deals) — лиды конвертируются в сделки через `leadId` - [Пользовательские поля](/docs/userfields) — создание и управление `ufCrm_*` - [Entity API](/docs/entity-api) — select для выборки полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Get ## Получить лид `GET /v1/leads/:id` Возвращает лид по ID со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/leads/42" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/leads/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/42', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Лид:', data.title, '— статус:', data.statusId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/42', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` Подробнее об include: [Связанные данные](/docs/includes). ## Поля ответа Объект лида со всеми полями — см. [Поля лида](/docs/entities/leads/fields). ## Связанные данные (include) ``` GET /v1/leads/5001?include=contact,company ``` Доступные include: `contact`, `company`. Результат в поле `_included`. ## Пример ответа ```json { "success": true, "data": { "id": 42, "title": "Заявка с сайта #42", "name": "Алексей", "lastName": "Иванов", "secondName": "Петрович", "stageId": "NEW", "companyTitle": "ООО Ромашка", "companyId": 15, "contactId": 71, "opportunity": 150000, "currencyId": "RUB", "sourceId": "WEB", "sourceDescription": "Форма обратной связи", "assignedById": 1, "createdBy": 1, "opened": true, "comments": "Звонить после 14:00", "phone": [{ "value": "+79169876543", "typeId": "WORK" }], "email": [{ "value": "ivanov@company.ru", "typeId": "WORK" }], "createdTime": "2026-04-10T14:30:00+03:00", "updatedTime": "2026-04-12T09:15:00+03:00" } } ``` ## Пример ответа при ошибке 404 — лид не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` Подробнее об include: [Связанные данные](/docs/includes). ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид не найден | | 403 | `ACCESS_DENIED` | Нет доступа к лиду | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить лид](/docs/entities/leads/update) — изменение полей - [Поля лида](/docs/entities/leads/fields) — описание всех полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: List ## Список лидов `GET /v1/leads` Возвращает список лидов с поддержкой фильтрации, сортировки и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` авто-пагинация | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit <= 500` | | `select` | string | — | Выборка полей: `?select=id,title,statusId,amount` | | `order` | object | — | Сортировка: `?order[createdTime]=desc` | | `filter` | object | — | Фильтрация по полям `GET /v1/leads/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[statusId]=NEW` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/leads?limit=10&filter[statusId]=NEW&select=id,title,statusId,amount" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/leads?limit=10&filter[statusId]=NEW&select=id,title,statusId,amount" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads?limit=10&filter[statusId]=NEW&select=id,title,statusId,amount', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} лидов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads?limit=10&filter[statusId]=NEW&select=id,title,statusId,amount', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив лидов (поля — см. [Поля](/docs/entities/leads/fields)) | | `meta.total` | number | Общее количество записей | | `meta.hasMore` | boolean | Есть ещё записи | URL карточки любого лида из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/lead/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 42, "title": "Заявка с сайта #42", "name": "Алексей", "lastName": "Иванов", "stageId": "NEW", "opportunity": 150000, "currencyId": "RUB", "assignedById": 1, "sourceId": "WEB", "createdTime": "2026-04-10T14:30:00+03:00" } ], "meta": { "total": 834, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц. **Когда использовать search:** для сложных фильтров удобнее `POST /v1/leads/search` — параметры в body. См. [Поиск лидов](/docs/entities/leads/search). ## Смотрите также - [Поиск лидов](/docs/entities/leads/search) — POST-запрос для сложных фильтров - [Поля лида](/docs/entities/leads/fields) — описание всех полей - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Products Add ## Добавить товар в лид `POST /v1/leads/:id/products` Добавляет одну товарную позицию в лид. В отличие от `PUT /v1/leads/:id/products`, не заменяет существующие позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | | `productId` | number | нет | ID товара из каталога. Если задан без `productName`, имя подставляется из каталога. Каталог: `GET /v1/products` | | `productName` | string | нет | Название товарной позиции — для произвольной строки без товара из каталога. Укажите хотя бы одно из `productId` / `productName`. | | `price` | number | нет | Цена за единицу | | `quantity` | number | нет | Количество | | `discount` | number | нет | Сумма скидки | | `taxRate` | number | нет | Ставка налога (%) | | `taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/leads/312/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/leads/312/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/312/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() console.log('ID строки:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/312/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID созданной товарной строки | ## Пример ответа ```json { "success": true, "data": { "id": 1465 } } ``` ## Пример ответа при ошибке 404 — лид не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/leads/products-get) — получить текущий список - [Установить товары](/docs/entities/leads/products-set) — заменить все позиции - [Удалить товар](/docs/entities/leads/products-delete) — удалить одну позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Leads: Products Delete ## Удалить товар из лида `DELETE /v1/leads/:id/products/:rowId` Удаляет одну товарную позицию из лида по ID строки. Восстановить удалённую позицию через API нельзя — добавляйте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/leads/312/products/1465" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/leads/312/products/1465" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/312/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Товар удалён из лида') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/312/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — лид не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид или товарная строка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/leads/products-get) — получить текущий список - [Добавить товар](/docs/entities/leads/products-add) — добавить позицию - [Установить товары](/docs/entities/leads/products-set) — заменить все позиции - [Товары каталога](/docs/entities/products) — справочник товаров --- # Leads: Products Fields ## Поля товаров лида `GET /v1/leads/:id/products/fields` Возвращает описание полей товарных позиций лида: названия, типы, доступность для чтения и записи. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/leads/741/products/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/leads/741/products/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Обяз. | Описание | |------|-----|:--:|:-----:|---------| | `id` | integer | да | | ID позиции | | `productId` | integer | | да | ID товара. Каталог: `GET /v1/products` | | `productName` | string | | | Название товара | | `price` | double | | | Цена | | `quantity` | double | | | Количество | | `discountSum` | double | | | Сумма скидки | | `discountRate` | double | | | Величина скидки (%) | | `discountTypeId` | integer | | | Тип скидки | | `taxRate` | double | | | Налог (%) | | `taxIncluded` | char | | | Налог включён в цену (`Y`/`N`) | | `priceExclusive` | double | да | | Цена без налога со скидкой | | `priceNetto` | double | да | | Цена нетто | | `priceBrutto` | double | да | | Цена брутто | | `measureCode` | integer | | | Код единицы измерения | | `measureName` | string | | | Единица измерения | | `customized` | char | | | Изменён (`Y`/`N`) | | `sort` | integer | | | Сортировка | | `type` | integer | да | | Тип | | `storeId` | integer | да | | ID склада | | `ownerId` | integer | | да | ID владельца (лида) | | `ownerType` | string | | да | Тип владельца | ## Пример ответа ```json { "success": true, "data": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "ownerId": { "type": "integer", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "ID владельца" }, "ownerType": { "type": "string", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "Тип владельца" }, "productId": { "type": "integer", "isRequired": true, "isReadOnly": false, "title": "Товар" }, "productName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название товара" }, "price": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Цена" }, "priceExclusive": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "Цена без налога со скидкой" }, "priceNetto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_NETTO" }, "priceBrutto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_BRUTTO" }, "quantity": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Количество" }, "discountTypeId": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Тип скидки" }, "discountRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Величина скидки" }, "discountSum": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Сумма скидки" }, "taxRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Налог" }, "taxIncluded": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Налог включен в цену" }, "customized": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Изменен" }, "measureCode": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Код единицы измерения" }, "measureName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Единица измерения" }, "sort": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Сортировка" }, "type": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "TYPE" }, "storeId": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "STORE_ID" } } } ``` ## Пример ответа при ошибке 404 — лид не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/leads/products-get) — получить товары лида - [Добавить товар](/docs/entities/leads/products-add) — добавить позицию - [Установить товары](/docs/entities/leads/products-set) — заменить все позиции - [Поля лида](/docs/entities/leads/fields) — описание полей лида --- # Leads: Products Get ## Товарные позиции лида `GET /v1/leads/:id/products` Возвращает список товарных позиций, привязанных к лиду. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/leads/741/products" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/leads/741/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Товаров:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив товарных позиций | | `data[].productId` | number | ID товара. Каталог: `GET /v1/products` | | `data[].productName` | string | Название товара | | `data[].price` | number | Цена за единицу | | `data[].quantity` | number | Количество | | `data[].discount` | number | Сумма скидки | | `data[].taxRate` | number/null | Ставка налога (%) | | `data[].taxIncluded` | boolean | Налог включён в цену | Показаны основные поля. Полный список (20 полей, включая priceAccount, measureCode и др.): [Поля товаров](/docs/entities/leads/products-fields). ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 1000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 404 — лид не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Установить товары](/docs/entities/leads/products-set) — заменить товарные позиции - [Получить лид](/docs/entities/leads/get) — основные данные лида - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Products Get Single ## Получить товар из лида `GET /v1/leads/:id/products/:rowId` Возвращает одну товарную позицию лида по ID строки. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/leads/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/leads/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Цена:', data.price) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID товарной строки | | `data.productId` | number | ID товара из каталога | | `data.productName` | string | Название товара | | `data.price` | number | Цена за единицу | | `data.quantity` | number | Количество | | `data.discount` | number | Сумма скидки | | `data.discountRate` | number | Процент скидки | | `data.discountTypeId` | number | Тип скидки (1 — сумма, 2 — процент) | | `data.taxRate` | number \| null | Ставка налога (%) | | `data.taxIncluded` | boolean | Налог включён в цену | | `data.priceExclusive` | number | Цена без скидки | | `data.priceNetto` | number | Цена нетто | | `data.priceBrutto` | number | Цена брутто | | `data.priceAccount` | number | Цена в валюте учёта | | `data.measureCode` | number | Код единицы измерения | | `data.measureName` | string | Название единицы измерения | | `data.sort` | number | Сортировка | ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "День добрый!", "price": 5000, "priceAccount": 5000, "priceExclusive": 5000, "priceNetto": 5000, "priceBrutto": 5000, "quantity": 3, "discountTypeId": 2, "discountRate": 0, "discount": 0, "taxRate": null, "taxIncluded": false, "customized": "Y", "measureCode": 796, "measureName": "шт", "sort": 0, "xmlId": "sale_basket_995", "type": 1 } } ``` ## Пример ответа при ошибке 404 — лид или товарная строка не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид или товарная строка не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/leads/products-get) — получить все позиции - [Обновить товар](/docs/entities/leads/products-update) — обновить позицию - [Добавить товар](/docs/entities/leads/products-add) — добавить позицию - [Удалить товар](/docs/entities/leads/products-delete) — удалить позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Leads: Products Set ## Установить товары лида `PUT /v1/leads/:id/products` Устанавливает товарные позиции лида. Полностью заменяет текущий список — передайте все нужные позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `items` | array | да | Массив товарных позиций | | `items[].productId` | number | да | ID товара. Каталог: `GET /v1/products` | | `items[].price` | number | да | Цена за единицу | | `items[].quantity` | number | да | Количество | | `items[].discount` | number | нет | Сумма скидки | | `items[].taxRate` | number | нет | Ставка налога (%) | | `items[].taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/leads/312/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### curl — OAuth-приложение ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/leads/312/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 25000, "quantity": 2 }, { "productId": 5, "price": 5000, "quantity": 1, "discount": 500 } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/312/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/312/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 25000, quantity: 2 }, { productId: 5, price: 5000, quantity: 1, discount: 500 }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив установленных позиций с полями productId, productName, price, quantity, discount, taxRate, taxIncluded | Массив установленных позиций с полями `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 25000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false }, { "productId": 5, "productName": "Установка и настройка", "price": 5000, "quantity": 1, "discount": 500, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 400 — неверный формат: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "items must be an array" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `items` не является массивом | | 404 | `ENTITY_NOT_FOUND` | Лид не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Полная замена:** PUT заменяет весь список товаров. Чтобы добавить позицию — сначала получите текущие (`GET`), добавьте новую в массив, отправьте всё (`PUT`). ## Смотрите также - [Товарные позиции](/docs/entities/leads/products-get) — получить текущий список - [Получить лид](/docs/entities/leads/get) — основные данные лида - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Products Update ## Обновить товар лида `PATCH /v1/leads/:id/products/:rowId` Обновляет товарную позицию лида. Передайте только изменяемые поля. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID лида | | `rowId` (path) | number | да | ID товарной позиции (из ответа list или add, не productId из каталога) | ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `price` | number | Цена за единицу | | `quantity` | number | Количество | | `productId` | number | ID товара. Каталог: `GET /v1/products` | | `discount` | number | Сумма скидки | | `taxRate` | number | Ставка налога (%) | | `taxIncluded` | boolean | Налог включён в цену | | `sort` | number | Сортировка | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/leads/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/leads/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() console.log('Обновлено:', data.price, 'x', data.quantity) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() ``` ## Поля ответа Обновлённый объект товарной позиции: `id`, `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "Серверное оборудование", "price": 9999, "quantity": 10, "discount": 0, "taxRate": null, "taxIncluded": false } } ``` ## Пример ответа при ошибке 404 — позиция не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Позиция не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить товар](/docs/entities/leads/products-get-single) — получение одной позиции - [Получить товары](/docs/entities/leads/products-get) — список всех позиций - [Добавить товар](/docs/entities/leads/products-add) — добавление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Search ## Поиск лидов `POST /v1/leads/search` Поиск лидов с фильтрами через POST — удобнее для сложных запросов. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/leads/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[statusId]=NEW` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "createdTime": "desc" }` | | `select` | string[] | — | Выборка полей: `["id", "title", "statusId", "amount"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/leads/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "statusId": "NEW", ">=amount": 100000 }, "limit": 10, "order": { "createdTime": "desc" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/leads/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "statusId": "NEW", ">=amount": 100000 }, "limit": 10, "order": { "createdTime": "desc" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { statusId: 'NEW', '>=amount': 100000 }, limit: 10, order: { createdTime: 'desc' }, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { statusId: 'NEW', '>=amount': 100000 }, limit: 10, order: { createdTime: 'desc' }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив лидов (поля — см. [Поля](/docs/entities/leads/fields)) | URL карточки любого лида из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/lead/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 42, "title": "Заявка с сайта #42", "stageId": "NEW", "opportunity": 150000, "currencyId": "RUB", "assignedById": 1, "sourceId": "WEB", "createdTime": "2026-04-10T14:30:00+03:00" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список лидов](/docs/entities/leads/list) — GET-запрос для простых фильтров - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Leads: Update ## Обновить лид `PATCH /v1/leads/:id` Обновляет поля существующего лида. Передайте только изменяемые поля. Полный список в [справочнике полей](/docs/entities/leads/fields), включая пользовательские (`ufCrm_*`). > ⚠ **Важно про `email` / `phone` (multifield):** Bitrix24 в `crm.item.update` **только добавляет** новые multifield-записи. PATCH `{"email": "new@y.com"}` к лиду, у которого уже есть email, **не заменит** старый — у лида станет два email. Это особенность B24, не Вайбкод. Чтобы заменить или удалить email/phone — отредактируйте лид через UI Битрикс24. ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `stageId` | string | Статус лида (каноническое имя; принимается и алиас `statusId`). Список: `GET /v1/statuses?filter[entityId]=STATUS`. В ответе значение возвращается в поле `stageId` | | `opportunity` | number | Сумма (каноническое имя; принимается и алиас `amount`). ⚠ Чтобы значение сохранилось, передайте в том же запросе `isManualOpportunity: true` | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `title` | string | Название лида | | `phone` | string \| string[] \| object[] | Телефон. Принимает три формы: строка `"+7..."`, массив строк `["+7...", "+7..."]`, или массив объектов `[{ "value": "+7...", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MOBILE \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | | `email` | string \| string[] \| object[] | Email. Принимает три формы: строка `"a@b.com"`, массив строк `["a@b.com", "b@c.com"]`, или массив объектов `[{ "value": "a@b.com", "typeId": "WORK" }, …]`. `typeId`: `WORK \| HOME \| MAILING \| OTHER` (по умолчанию `WORK`). ⚠ B24-native UPPER-форма `[{ "VALUE": "...", "VALUE_TYPE": "WORK" }]` **не принимается** — вернёт `400 INVALID_MULTIFIELD_SHAPE`. Используйте camelCase: `[{ "value": "...", "typeId": "WORK" }]` | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/leads/42" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stageId": "IN_PROCESS", "opportunity": 250000, "isManualOpportunity": true, "assignedById": 3, "title": "Заявка с сайта — горячий клиент" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/leads/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "stageId": "IN_PROCESS", "opportunity": 250000, "isManualOpportunity": true, "assignedById": 3, "title": "Заявка с сайта — горячий клиент" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'IN_PROCESS', opportunity: 250000, isManualOpportunity: true, assignedById: 3, title: 'Заявка с сайта — горячий клиент', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/leads/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'IN_PROCESS', opportunity: 250000, isManualOpportunity: true, assignedById: 3, title: 'Заявка с сайта — горячий клиент', }), }) const { success, data } = await res.json() ``` ### Альтернативная форма — массив объектов с явным `typeId` Если нужно указать несколько значений или явный тип (`HOME`, `MOBILE`): ```json { "phone": [ { "value": "+79161234567", "typeId": "WORK" }, { "value": "+79161112233", "typeId": "MOBILE" } ], "email": [ { "value": "work@company.ru", "typeId": "WORK" }, { "value": "personal@me.ru", "typeId": "HOME" } ] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект лида со всеми полями — см. [Поля](/docs/entities/leads/fields) | Обновленный объект лида — см. [Поля лида](/docs/entities/leads/fields). ## Пример ответа ```json { "success": true, "data": { "id": 42, "title": "Заявка с сайта", "stageId": "IN_PROCESS", "assignedById": 1, "createdTime": "2026-04-15T12:00:00+03:00", "updatedTime": "2026-04-15T13:00:00+03:00" } } ``` ## Пример ответа при ошибке 404 — лид не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Лид не найден | | 403 | `ACCESS_DENIED` | Нет доступа | | 400 | `INVALID_REQUEST` | Невалидные поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить лид](/docs/entities/leads/get) — текущие значения - [Поля лида](/docs/entities/leads/fields) — все доступные поля - [Статусы](/docs/entities/statuses) — значения `statusId` - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Openline Configs: Aggregate ## Агрегация конфигураций открытых линий `POST /v1/openline-configs/aggregate` Подсчёт количества конфигураций открытых линий с опциональной группировкой по типу очереди и другим полям схемы. **Группировка.** `groupBy` принимает 2 поля: `active`, `queueType` — это `aggregatable`-поля из [`GET /v1/openline-configs/fields`](/docs/entities/openline-configs/fields). Остальные поля схемы (`id`, `name`, `workTimeFrom`, `workTimeTo`) и UPPER_SNAKE_CASE-поля ответа в `groupBy` отвергаются с `400 INVALID_PARAMS` — подробности в [Известных особенностях](#известные-особенности). **Числовые агрегации (`sum`/`avg`/`min`/`max`) не применимы.** Поля openline-configs — категориальные или идентификационные; поддерживается только функция `count` с `field: "*"`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "*", "function": "count" }`. Функция `count` требует `field: "*"`. Без параметра — только `count` | | `filter` | object | нет | Фильтрация. [Синтаксис фильтрации](/docs/filtering). Пример: `{"active": false}` | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки. Допустимые значения: `active`, `queueType` — см. [Известные особенности](#известные-особенности) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/openline-configs/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "groupBy": "queueType" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/openline-configs/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "groupBy": "queueType" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ groupBy: 'queueType', }), }) const { success, data } = await res.json() console.log('Всего конфигураций:', data.count) console.log('По типу очереди:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ groupBy: 'queueType', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["queueType", "active"]`. Принимаются комбинации из 2 допустимых полей: `active`, `queueType`. ## Другие сценарии Общее количество конфигураций — самый быстрый запрос, без выгрузки записей: ```json {} ``` Явная передача `count` через `aggregate`: ```json { "aggregate": [{ "field": "*", "function": "count" }] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Итоговое количество конфигураций в выборке (после применения фильтра, если он сработал). Это основной показатель для приложения | | `data.aggregates` | object | Результаты агрегаций (для openline-configs всегда `{}`) | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поле группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Сколько записей увидел aggregator во входной выборке. Без `groupBy` совпадает с `data.count`; с `groupBy` равен сумме `count` по всем группам. Техническая метрика | | `data.meta.recordsProcessed` | number | Сколько записей реально обработано при группировке. `0`, если `groupBy` не передан | | `data.meta.truncated` | boolean | `true`, если под выборку попало более 5000 записей | | `data.meta.groupTotal` | number | Количество групп в результате (только при `groupBy`) | | `data.meta.groupsTruncated` | boolean | Признак усечения списка групп (только при `groupBy`) | ## Пример ответа Ответ на основной запрос (`groupBy: "queueType"`): ```json { "success": true, "data": { "count": 10, "aggregates": {}, "groups": [ { "queueType": "all", "count": 9, "aggregates": {} }, { "queueType": "evenly", "count": 1, "aggregates": {} } ], "meta": { "totalRecords": 10, "recordsProcessed": 10, "truncated": false, "groupTotal": 2, "groupsTruncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — функция `count` с неверным именем поля: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "count aggregate requires field \"*\"" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Функция `count` передана с `field` не равным `"*"`, или передан `groupBy` по полю не из схемы Вайбкода | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Параметр `filter` в aggregate игнорируется.** Передача `{"filter": {"active": false}}` не влияет на результат — метод возвращает `count` по всем конфигурациям портала. Причина: aggregate обходит записи через метод списка `imopenlines.config.list.get`, который на стороне Битрикс24 фильтр для openline-configs не применяет. Для подсчёта по подмножеству используйте `groupBy` (например, `groupBy: ["active"]` разобьёт результат по признаку активности) или обрабатывайте результат [`POST /v1/openline-configs/search`](/docs/entities/openline-configs/search) на стороне клиента. **Функция `count` требует `field: "*"`.** При передаче `{"field": "id", "function": "count"}` возвращается `400 INVALID_PARAMS`. Единственный корректный формат: `{"field": "*", "function": "count"}`. **`groupBy` принимает только 2 поля из схемы Вайбкода:** `active`, `queueType`. Это `aggregatable`-поля из ответа [`GET /v1/openline-configs/fields`](/docs/entities/openline-configs/fields). Остальные поля схемы (`id`, `name`, `workTimeFrom`, `workTimeTo`) и UPPER_SNAKE_CASE-поля (`QUEUE_TIME`, `CRM`, ...) в `groupBy` отвергаются с `400 INVALID_PARAMS` и сообщением «groupBy field 'X' is not aggregatable on this entity. Available: active, queueType». ## Смотрите также - [Список конфигураций](/docs/entities/openline-configs/list) — получить записи с фильтрацией и `total` - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Openline Configs: Create ## Создать конфигурацию открытой линии `POST /v1/openline-configs` Создаёт новую конфигурацию открытой линии. Для создания достаточно передать одно поле — остальные параметры устанавливаются по умолчанию. Полная запись с идентификаторами и всеми полями доступна через `GET /v1/openline-configs/:id`. ## Поля запроса (body) Поля передаются в UPPER_SNAKE_CASE — это формат данного эндпоинта. Минимум для создания: хотя бы одно поле (например `LINE_NAME`). | Поле | Тип | Обяз. | Описание | |------|-----|-------|---------| | `LINE_NAME` | string | нет | Название открытой линии | | `ACTIVE` | boolean | нет | Активна ли линия (`true` / `false`) | | `QUEUE_TYPE` | string | нет | Распределение очереди: `all` — всем одновременно, `evenly` — равномерно, `strictly` — строго по порядку | | `QUEUE_TIME` | number | нет | Время ожидания в очереди (секунды) до перевода | | `NO_ANSWER_TIME` | number | нет | Время без ответа (секунды), после которого срабатывает правило `NO_ANSWER_RULE` | | `CRM` | boolean | нет | Включить интеграцию с CRM | | `CRM_CREATE` | string | нет | Режим создания CRM-сущностей при новом обращении | | `WORKTIME_ENABLE` | boolean | нет | Включить расписание рабочего времени | | `WORKTIME_FROM` | string | нет | Начало рабочего дня (например `"9"` или `"9.30"`) | | `WORKTIME_TO` | string | нет | Конец рабочего дня (например `"18"` или `"18.30"`) | | `WORKTIME_TIMEZONE` | string | нет | Часовой пояс расписания (например `"Europe/Moscow"`) | | `WELCOME_MESSAGE` | boolean | нет | Включить приветственное сообщение | | `WELCOME_MESSAGE_TEXT` | string | нет | Текст приветственного сообщения | | `LANGUAGE_ID` | string | нет | Язык линии (например `"ru"`, `"en"`) | Полный список полей — [`GET /v1/openline-configs/fields`](/docs/entities/openline-configs/fields). ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/openline-configs \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "LINE_NAME": "Поддержка клиентов", "ACTIVE": true, "QUEUE_TYPE": "evenly", "WORKTIME_ENABLE": true, "WORKTIME_FROM": "9", "WORKTIME_TO": "18" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/openline-configs \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "LINE_NAME": "Поддержка клиентов", "ACTIVE": true, "QUEUE_TYPE": "evenly", "WORKTIME_ENABLE": true, "WORKTIME_FROM": "9", "WORKTIME_TO": "18" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ LINE_NAME: 'Поддержка клиентов', ACTIVE: true, QUEUE_TYPE: 'evenly', WORKTIME_ENABLE: true, WORKTIME_FROM: '9', WORKTIME_TO: '18', }), }) const { success, data } = await res.json() console.log('Новая конфигурация ID:', data) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ LINE_NAME: 'Поддержка клиентов', ACTIVE: true, QUEUE_TYPE: 'evenly', WORKTIME_ENABLE: true, WORKTIME_FROM: '9', WORKTIME_TO: '18', }), }) const { success, data } = await res.json() console.log('Новая конфигурация ID:', data) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | number | Идентификатор созданной конфигурации | ## Пример ответа ```json { "success": true, "data": 29 } ``` ## Пример ответа при ошибке 400 — тело запроса не содержит ни одного поля: ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Request body must contain at least one field for imopenlines.config.add (e.g. lineName, queueType, agentId)." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `VALIDATION_ERROR` | Тело запроса пустое — не передано ни одного поля | | 401 | `TOKEN_MISSING` | Заголовок `X-Api-Key` не передан | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности `data` в ответе — это число (идентификатор новой конфигурации), а не объект записи. Чтобы получить созданную конфигурацию со всеми полями, выполните отдельный запрос: `GET /v1/openline-configs/:id`. ## Смотрите также - [Получить конфигурацию](/docs/entities/openline-configs/get) - [Список конфигураций](/docs/entities/openline-configs/list) - [Поля конфигурации](/docs/entities/openline-configs/fields) --- # Openline Configs: Delete ## Удалить конфигурацию открытой линии `DELETE /v1/openline-configs/:id` Удаляет конфигурацию открытой линии по ID. Восстановить удалённую запись через API нельзя — создавайте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID конфигурации | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/openline-configs/29" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/openline-configs/29" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/29', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() if (success && data.deleted) { console.log('Конфигурация удалена, ID:', data.id) } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/29', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() if (success && data.deleted) { console.log('Конфигурация удалена, ID:', data.id) } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | ID удалённой конфигурации | | `data.deleted` | boolean | `true` при успешном удалении | ## Пример ответа ```json { "success": true, "data": { "id": 29, "deleted": true } } ``` ## Пример ответа при ошибке 404 — конфигурация не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "openlineConfig 99999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_ID` | `id` не является положительным целым числом | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | | 404 | `ENTITY_NOT_FOUND` | Конфигурация с указанным ID не найдена | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список конфигураций](/docs/entities/openline-configs/list) - [Получить конфигурацию](/docs/entities/openline-configs/get) - [Batch](/docs/batch) — массовое удаление --- # Openline Configs: Fields ## Поля конфигурации открытой линии `GET /v1/openline-configs/fields` Возвращает схему полей, доступных для фильтрации и сортировки, а также полный реестр полей в ответах `list`, `get` и `search`. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/openline-configs/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/openline-configs/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Поля схемы:', Object.keys(data.fields)) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Эндпоинт `/fields` содержит два блока: **схема** (`data.fields`) — 6 полей, по которым работают сортировка и фильтрация; **реестр полей ответа** — все поля, приходящие в ответах `list`, `get`, `search`. Полный набор в `get` — 95 полей; в `list`/`search` — 91 (без 4 полей очереди операторов). ### Схема полей (data.fields) Только эти 6 полей поддерживаются в `sort`, `filter` и `groupBy` агрегации. | Поле | Тип | RO | Описание | |------|-----|----|---------| | `id` | number | да | Идентификатор конфигурации | | `name` | string | | Название открытой линии | | `active` | boolean | | Активна ли линия | | `queueType` | string | | Алгоритм распределения: `all` — всем операторам одновременно, `evenly` — равномерно, `strictly` — строго по очереди | | `workTimeFrom` | string | | Начало рабочего времени (например `"8"` или `"9.30"`) | | `workTimeTo` | string | | Конец рабочего времени | Дополнительно в `data.fields` указаны: - `aggregatable` — поля, доступные для `groupBy`: `["active", "queueType"]` - `batch` — доступные операции: `["create", "update", "delete"]` ### Полный реестр полей ответа (list / get / search) В `get` объект `data` содержит 95 полей в смешанном регистре, в `list`/`search` — 91 (без 4 полей с отметкой «только `get`»: `QUEUE`, `QUEUE_FULL`, `QUEUE_USERS_FIELDS`, `QUEUE_ONLINE`). #### Основные | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `id` | number | да | везде | Идентификатор конфигурации | | `name` | string | | везде | Название открытой линии | | `active` | boolean | | везде | Линия активна (`true`/`false`) | | `TEMPORARY` | string | | везде | Временная линия: `"Y"` / `"N"` | | `XML_ID` | string\|null | | везде | Внешний идентификатор | | `LANGUAGE_ID` | string | | везде | Язык линии (например `"ru"`) | #### Очередь и операторы | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `queueType` | string | | везде | Алгоритм распределения: `all` — всем операторам одновременно, `evenly` — равномерно, `strictly` — строго по очереди | | `QUEUE_TIME` | string | | везде | Время ожидания в очереди (секунды) | | `NO_ANSWER_TIME` | string | | везде | Время без ответа оператора до переключения (секунды) | | `CHECK_AVAILABLE` | string | | везде | Проверять доступность оператора: `"Y"` / `"N"` | | `MAX_CHAT` | string | | везде | Максимальное число одновременных чатов на оператора (`"0"` — без ограничения) | | `TYPE_MAX_CHAT` | string | | везде | Тип подсчёта лимита чатов: `answered` — только принятые, `total` — все | | `QUEUE` | string[] | да | только `get` | Массив ID операторов в очереди (строки) | | `QUEUE_FULL` | object | да | только `get` | Объекты операторов с полями `ID`, `SORT`, `USER_ID`, `DEPARTMENT_ID`, `USER_NAME`, `USER_WORK_POSITION`, `USER_AVATAR`, `USER_AVATAR_ID` | | `QUEUE_USERS_FIELDS` | object | да | только `get` | Данные профилей операторов: `USER_NAME`, `USER_WORK_POSITION`, `USER_AVATAR`, `USER_AVATAR_ID` | | `QUEUE_ONLINE` | string | да | только `get` | Есть ли операторы онлайн в данный момент: `"Y"` / `"N"` | #### Интеграция с CRM | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `CRM` | string | | везде | Включить интеграцию с CRM: `"Y"` / `"N"` | | `CRM_CREATE` | string | | везде | Тип создаваемой CRM-записи при первом обращении: `deal`, `lead`, `contact`, `company` | | `CRM_CREATE_SECOND` | string | | везде | Тип записи при повторных обращениях (числовой идентификатор типа) | | `CRM_CREATE_THIRD` | string | | везде | Тип записи при третьем и последующих обращениях: `"Y"` / `"N"` | | `CRM_FORWARD` | string | | везде | Переадресовывать обращение ответственному из CRM: `"Y"` / `"N"` | | `CRM_CHAT_TRACKER` | string | | везде | Включить трекер чата в CRM: `"Y"` / `"N"` | | `CRM_TRANSFER_CHANGE` | string | | везде | Менять ответственного при переводе чата: `"Y"` / `"N"` | | `CRM_SOURCE` | string | | везде | Источник CRM-записи: `create` — создавать, другое значение — брать из истории | #### Приветственное сообщение | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `WELCOME_MESSAGE` | string | | везде | Показывать приветствие: `"Y"` / `"N"` | | `WELCOME_MESSAGE_TEXT` | string | | везде | Текст приветствия (поддерживает BB-код) | | `WATCH_TYPING` | string | | везде | Показывать индикатор набора текста: `"Y"` / `"N"` | | `SEND_WELCOME_EACH_SESSION` | string | | везде | Отправлять приветствие при каждой новой сессии: `"Y"` / `"N"` | #### Приветственный бот | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `WELCOME_BOT_ENABLE` | string | | везде | Включить приветственного бота: `"Y"` / `"N"` | | `WELCOME_BOT_ID` | string | | везде | ID бота. Список: `GET /v1/bots` | | `WELCOME_BOT_TIME` | string | | везде | Время ожидания ответа бота (секунды) | | `WELCOME_BOT_JOIN` | string | | везде | Когда бот присоединяется: `always` — всегда, другие значения по настройке | | `WELCOME_BOT_LEFT` | string | | везде | Когда бот покидает чат: `queue` — после постановки в очередь, другие значения по настройке | #### Рабочее время | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `WORKTIME_ENABLE` | string | | везде | Включить расписание рабочего времени: `"Y"` / `"N"` | | `workTimeFrom` | string | | везде | Начало рабочего дня (например `"8"`, `"9.30"`) | | `workTimeTo` | string | | везде | Конец рабочего дня | | `WORKTIME_TIMEZONE` | string | | везде | Часовой пояс (например `"Europe/Kaliningrad"`) | | `WORKTIME_HOLIDAYS` | string[] | | везде | Праздничные нерабочие дни в формате `"ДД.ММ"` (например `["1.01","7.01"]`) | | `WORKTIME_DAYOFF` | string[] | | везде | Выходные дни недели: `"MO"`, `"TU"`, `"WE"`, `"TH"`, `"FR"`, `"SA"`, `"SU"` | #### Сценарии нерабочего времени, нет ответа, закрытие Три группы по четыре поля — сценарий, форма, бот, текст: | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `WORKTIME_DAYOFF_RULE` | string | | везде | Действие в выходной день: `text` — сообщение, `form` — форма, `bot` — бот, `none` — ничего | | `WORKTIME_DAYOFF_FORM_ID` | string | | везде | ID формы для нерабочего времени | | `WORKTIME_DAYOFF_BOT_ID` | string | | везде | ID бота для нерабочего времени. Список: `GET /v1/bots` | | `WORKTIME_DAYOFF_TEXT` | string | | везде | Текст сообщения в нерабочее время (поддерживает BB-код) | | `NO_ANSWER_RULE` | string | | везде | Действие при нет ответа: `text`, `form`, `bot`, `none` | | `NO_ANSWER_FORM_ID` | string | | везде | ID формы при нет ответа | | `NO_ANSWER_BOT_ID` | string | | везде | ID бота при нет ответа. Список: `GET /v1/bots` | | `NO_ANSWER_TEXT` | string | | везде | Текст сообщения при нет ответа | | `CLOSE_RULE` | string | | везде | Действие при закрытии чата: `text`, `form`, `bot`, `none` | | `CLOSE_FORM_ID` | string | | везде | ID формы при закрытии | | `CLOSE_BOT_ID` | string | | везде | ID бота при закрытии. Список: `GET /v1/bots` | | `CLOSE_TEXT` | string | | везде | Текст сообщения при закрытии | | `FULL_CLOSE_TIME` | string | | везде | Время до полного закрытия чата (секунды) | | `CONFIRM_CLOSE` | string | | везде | Запрашивать подтверждение при закрытии чата: `"Y"` / `"N"` | | `SHOW_NOTIFICATION_REDIRECT` | string\|null | | везде | Показывать уведомление при перенаправлении: `"Y"` / `"N"` / `null` | #### Автозакрытие по неактивности | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `AUTO_CLOSE_RULE` | string | | везде | Действие при истечении времени неактивности: `text`, `form`, `bot`, `none` | | `AUTO_CLOSE_FORM_ID` | string | | везде | ID формы при автозакрытии | | `AUTO_CLOSE_BOT_ID` | string | | везде | ID бота при автозакрытии. Список: `GET /v1/bots` | | `AUTO_CLOSE_TIME` | string | | везде | Время до автозакрытия чата (секунды) | | `AUTO_CLOSE_TEXT` | string | | везде | Текст при автозакрытии | | `AUTO_EXPIRE_TIME` | string | | везде | Время истечения сессии по неактивности (секунды) | #### Оценка качества | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `VOTE_MESSAGE` | string | | везде | Включить запрос оценки: `"Y"` / `"N"` | | `VOTE_TIME_LIMIT` | string | | везде | Ограничение времени на оценку (секунды, `"0"` — без ограничения) | | `VOTE_BEFORE_FINISH` | string | | везде | Запрашивать оценку до завершения чата: `"Y"` / `"N"` | | `VOTE_CLOSING_DELAY` | string | | везде | Задержка закрытия после оценки: `"Y"` / `"N"` | | `VOTE_MESSAGE_1_TEXT` | string | | везде | Текст запроса оценки (простые сообщения с кнопками) | | `VOTE_MESSAGE_1_LIKE` | string | | везде | Ответ при положительной оценке | | `VOTE_MESSAGE_1_DISLIKE` | string | | везде | Ответ при отрицательной оценке | | `VOTE_MESSAGE_2_TEXT` | string | | везде | Текст запроса оценки (текстовый режим, `1`/`0`) | | `VOTE_MESSAGE_2_LIKE` | string | | везде | Ответ при `1` (положительная) | | `VOTE_MESSAGE_2_DISLIKE` | string | | везде | Ответ при `0` (отрицательная) | #### Соглашения и категории | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `AGREEMENT_MESSAGE` | string | | везде | Запрашивать согласие с условиями: `"Y"` / `"N"` | | `AGREEMENT_ID` | string | | везде | ID документа с условиями | | `CATEGORY_ENABLE` | string | | везде | Включить категоризацию обращений: `"Y"` / `"N"` | | `CATEGORY_ID` | string | | везде | ID категории по умолчанию | #### Форма ожидания | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `USE_WELCOME_FORM` | string | | везде | Показывать форму перед постановкой в очередь: `"Y"` / `"N"` | | `WELCOME_FORM_ID` | string | | везде | ID формы ожидания | | `WELCOME_FORM_DELAY` | string | | везде | Задержка показа формы: `"Y"` / `"N"` | | `IGNORE_WELCOME_FORM_RESPONSIBLE` | string | | везде | Пропускать форму для ответственного из CRM: `"Y"` / `"N"` | #### Оператор и сессия | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `OPERATOR_DATA` | string | | везде | Данные оператора в чате: `profile` — полный профиль | | `DEFAULT_OPERATOR_DATA` | array | | везде | Данные по умолчанию при отсутствии операторов | | `SESSION_PRIORITY` | string | | везде | Приоритет сессии (`"0"` — стандартный) | | `QUICK_ANSWERS_IBLOCK_ID` | string | | везде | ID инфоблока с быстрыми ответами | #### KPI | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `KPI_FIRST_ANSWER_TIME` | string | | везде | Норматив времени первого ответа (секунды) | | `KPI_FIRST_ANSWER_ALERT` | string | | везде | Отправлять предупреждение при нарушении KPI первого ответа: `"Y"` / `"N"` | | `KPI_FIRST_ANSWER_LIST` | string[] | | везде | Список ID получателей предупреждения по KPI первого ответа | | `KPI_FIRST_ANSWER_TEXT` | string | | везде | Шаблон текста предупреждения (поддерживает `#OPERATOR#`, `#DIALOG#`) | | `KPI_FURTHER_ANSWER_TIME` | string | | везде | Норматив времени последующих ответов (секунды) | | `KPI_FURTHER_ANSWER_ALERT` | string | | везде | Отправлять предупреждение при нарушении KPI последующих ответов: `"Y"` / `"N"` | | `KPI_FURTHER_ANSWER_LIST` | string[] | | везде | Список ID получателей предупреждения | | `KPI_FURTHER_ANSWER_TEXT` | string | | везде | Шаблон текста предупреждения | | `KPI_CHECK_OPERATOR_ACTIVITY` | string | | везде | Контролировать активность оператора: `"Y"` / `"N"` | | `SEND_NOTIFICATION_EMPTY_QUEUE` | string | | везде | Уведомлять при пустой очереди: `"Y"` / `"N"` | #### Служебные | Поле | Тип | RO | Источник | Описание | |------|-----|----|---------|---------| | `DATE_CREATE` | object | да | везде | Дата создания — приходит как пустой объект `{}` | | `DATE_MODIFY` | object | да | везде | Дата последнего изменения — приходит как пустой объект `{}` | | `MODIFY_USER_ID` | string | да | везде | ID пользователя, внёсшего последнее изменение. Поиск: `GET /v1/users` | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false }, "active": { "type": "boolean", "readonly": false }, "queueType": { "type": "string", "readonly": false }, "workTimeFrom": { "type": "string", "readonly": false }, "workTimeTo": { "type": "string", "readonly": false } }, "aggregatable": ["active", "queueType"], "batch": ["create", "update", "delete"] } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "Access denied. Required scope: imopenlines" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `TOKEN_MISSING` | API-ключ не передан | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Два независимых набора имён.** Схема `data.fields` — 6 полей camelCase, по ним работают `filter`, `sort`, `groupBy`. Ответы содержат: 6 camelCase-полей (трансформированы схемой Вайбкода) + UPPER_SNAKE_CASE-поля (приходят как есть из Битрикс24). Всего 91 поле в `list`/`search`, 95 в `get` (добавляются 4 поля очереди операторов). Имена для запроса — camelCase; имена для чтения значений — оба регистра. **Числовые поля приходят строками.** `QUEUE_TIME`, `NO_ANSWER_TIME`, `AUTO_CLOSE_TIME`, `MAX_CHAT`, `KPI_FIRST_ANSWER_TIME` и другие — строки (`"60"`, `"180"`). Исключение — `id` (`number`) и `active` (`boolean`): эти два поля трансформирует схема Вайбкода. **Поля `lineId` и `agentId` удалены из схемы (2026-06-05, VB-5ba3fd91).** `imopenlines.config.*` никогда их не возвращал — они были «зарезервированными» фантомами и убраны из `data.fields`, `aggregatable` и `/v1/guide`. **`DATE_CREATE` и `DATE_MODIFY` всегда пустые объекты `{}`.** Битрикс24 не передаёт значения дат через эти поля. ## Смотрите также - [Список конфигураций](/docs/entities/openline-configs/list) - [Получить конфигурацию](/docs/entities/openline-configs/get) - [Entity API](/docs/entity-api) - [Синтаксис фильтрации](/docs/filtering) --- # Openline Configs: Get ## Получить конфигурацию открытой линии `GET /v1/openline-configs/:id` Возвращает конфигурацию открытой линии по ID со всеми полями, включая данные очереди операторов. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID конфигурации | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/openline-configs/1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/openline-configs/1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/1', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Линия:', data.name, '— тип очереди:', data.queueType) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/1', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Ответ содержит 95 полей. 6 полей в camelCase, остальные в UPPER_SNAKE_CASE — подробное описание: [Поля открытой линии](/docs/entities/openline-configs/fields). | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект конфигурации (все поля — см. [Поля открытой линии](/docs/entities/openline-configs/fields)) | ## Пример ответа Показаны ключевые поля. Полный список: [Поля открытой линии](/docs/entities/openline-configs/fields). ```json { "success": true, "data": { "id": 1, "active": true, "name": "Открытая линия", "queueType": "all", "workTimeFrom": "8", "workTimeTo": "17", "CRM": "Y", "CRM_CREATE": "deal", "QUEUE_TIME": "60", "NO_ANSWER_TIME": "180", "WORKTIME_ENABLE": "Y", "WORKTIME_TIMEZONE": "Europe/Kaliningrad", "WELCOME_MESSAGE": "Y", "VOTE_MESSAGE": "Y", "QUEUE": ["139", "131", "99"], "QUEUE_FULL": { "99": { "ID": "59", "SORT": "2", "USER_ID": "99", "DEPARTMENT_ID": "0", "USER_NAME": "Иван Петров", "USER_WORK_POSITION": "Менеджер поддержки", "USER_AVATAR": "/upload/main/avatars/99.jpg", "USER_AVATAR_ID": "12345" }, "131": { "ID": "57", "SORT": "1", "USER_ID": "131", "DEPARTMENT_ID": "0", "USER_NAME": "Мария Смирнова", "USER_WORK_POSITION": "Старший оператор", "USER_AVATAR": "/upload/main/avatars/131.jpg", "USER_AVATAR_ID": "67890" } }, "QUEUE_USERS_FIELDS": { "99": { "USER_NAME": "Иван Петров", "USER_WORK_POSITION": "Менеджер поддержки", "USER_AVATAR": "/upload/main/avatars/99.jpg" }, "131": { "USER_NAME": "Мария Смирнова", "USER_WORK_POSITION": "Старший оператор", "USER_AVATAR": "/upload/main/avatars/131.jpg" } }, "QUEUE_ONLINE": "N", "DATE_CREATE": {}, "DATE_MODIFY": {} } } ``` ## Пример ответа при ошибке 404 — конфигурация не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "openlineConfig 99999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | | 404 | `ENTITY_NOT_FOUND` | Конфигурация с таким ID не найдена | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поля очереди операторов доступны только здесь.** `QUEUE`, `QUEUE_FULL`, `QUEUE_USERS_FIELDS`, `QUEUE_ONLINE` приходят в ответе одиночного запроса и недоступны в [Списке](/docs/entities/openline-configs/list) и [Поиске](/docs/entities/openline-configs/search). Полный реестр всех 95 полей, регистры имён и пустые `DATE_CREATE`/`DATE_MODIFY` — [Поля конфигурации](/docs/entities/openline-configs/fields). ## Смотрите также - [Поля открытой линии](/docs/entities/openline-configs/fields) - [Список конфигураций](/docs/entities/openline-configs/list) - [Обновить конфигурацию](/docs/entities/openline-configs/update) --- # Openline Configs: List ## Список конфигураций открытых линий `GET /v1/openline-configs` Возвращает список конфигураций открытых линий с поддержкой фильтрации, сортировки и пагинации. ## Параметры | Параметр | Тип | По умолч. | Допустимые значения | Описание | |----------|-----|-----------|---------------------|---------| | `limit` | number | `50` | `1`–`200` | Количество записей на запрос | | `offset` | number | `0` | `0` и больше | Пропустить N записей | | `sort` | string | — | `id`, `name`, `active`, `queueType`, `workTimeFrom`, `workTimeTo` | Поле сортировки | | `order` | string | `asc` | `asc`, `desc` | Направление сортировки | | `filter` | object | — | ключи — те же 6 полей, что и в `sort`; значения — по типу поля | Фильтрация по полям схемы.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[active]=false`, `?filter[queueType]=evenly` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/openline-configs?limit=10&sort=id&order=asc&filter[active]=true" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/openline-configs?limit=10&sort=id&order=asc&filter[active]=true" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs?limit=10&sort=id&order=asc&filter[active]=true', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, total, hasMore } = await res.json() console.log(`Получено ${data.length} конфигураций, всего в окне: ${total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs?limit=10&sort=id&order=asc&filter[active]=true', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, total, hasMore } = await res.json() ``` ## Поля ответа Ответ содержит поля метаданных на верхнем уровне (не вложены в `meta`): | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив конфигураций (все поля — см. [Поля конфигурации](/docs/entities/openline-configs/fields)) | | `total` | number | Количество записей в текущем окне (не общий счётчик портала) | | `limit` | number | Размер страницы | | `offset` | number | Смещение | | `hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа Показаны основные поля. Полный список: [Поля конфигурации](/docs/entities/openline-configs/fields). ```json { "success": true, "data": [ { "id": 1, "active": true, "name": "Открытая линия", "queueType": "all", "workTimeFrom": "8", "workTimeTo": "17", "CRM": "Y", "CRM_CREATE": "deal", "QUEUE_TIME": "60", "NO_ANSWER_TIME": "180", "WELCOME_MESSAGE": "Y", "WORKTIME_ENABLE": "Y", "WORKTIME_TIMEZONE": "Europe/Kaliningrad", "DATE_CREATE": {}, "DATE_MODIFY": {} }, { "id": 3, "active": true, "name": "Wix", "queueType": "all", "workTimeFrom": "9", "workTimeTo": "18.30", "CRM": "Y", "CRM_CREATE": "deal", "QUEUE_TIME": "60", "NO_ANSWER_TIME": "180", "WELCOME_MESSAGE": "Y", "WORKTIME_ENABLE": "N", "WORKTIME_TIMEZONE": "Europe/Moscow", "DATE_CREATE": {}, "DATE_MODIFY": {} } ], "total": 10, "limit": 10, "offset": 0, "hasMore": false } ``` > В примере показаны 2 записи из 10 — остальные 8 опущены для краткости. Каждый элемент содержит ещё около 75 полей помимо показанных. ## Пример ответа при ошибке 400 — неизвестное поле сортировки: ```json { "success": false, "error": { "code": "UNKNOWN_SORT_FIELD", "message": "Unknown sort field: 'createdAt'. Available: id, name, active, queueType, workTimeFrom, workTimeTo" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_SORT_FIELD` | Передано неизвестное поле в `sort`. Сообщение содержит список допустимых значений | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`total` — счётчик текущего окна, а не общий.** Битрикс24 не возвращает общее количество конфигураций для метода списка, поэтому `total` содержит число записей только в текущей странице. Для проверки наличия следующей страницы используйте поле `hasMore`. **Фильтрация и сортировка работают по camelCase-полям схемы.** Параметры `filter` и `sort` принимают только 6 имён из схемы: `id`, `name`, `active`, `queueType`, `workTimeFrom`, `workTimeTo`. Поля в UPPER_SNAKE_CASE (например `CRM_CREATE`, `WORKTIME_TIMEZONE`) для фильтра и сортировки недоступны. **Поля `QUEUE`, `QUEUE_FULL`, `QUEUE_USERS_FIELDS`, `QUEUE_ONLINE` в списке не возвращаются** — они доступны только в [Получить конфигурацию](/docs/entities/openline-configs/get). **Смешанный регистр и пустые даты.** Каждая запись содержит ~91 поле в двух регистрах (6 camelCase + ~85 UPPER_SNAKE_CASE); `DATE_CREATE` и `DATE_MODIFY` приходят пустыми объектами `{}`. Полный реестр полей и пояснения — [Поля конфигурации](/docs/entities/openline-configs/fields). ## Смотрите также - [Получить конфигурацию](/docs/entities/openline-configs/get) - [Создать конфигурацию](/docs/entities/openline-configs/create) - [Поля конфигурации](/docs/entities/openline-configs/fields) - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) - [Лимиты и оптимизация](/docs/optimization) --- # Openline Configs: Search ## Поиск конфигураций открытых линий `POST /v1/openline-configs/search` Возвращает список конфигураций открытых линий с фильтрацией, сортировкой и пагинацией. Параметры передаются в теле запроса — удобнее для сложных условий, чем query-строка. ## Поля запроса (body) | Параметр | Тип | По умолч. | Допустимые значения | Описание | |----------|-----|-----------|---------------------|---------| | `filter` | object | — | ключи — те же 6 полей, что и в `sort`; значения — по типу поля | Фильтрация по полям схемы. Доступные поля — [`GET /v1/openline-configs/fields`](/docs/entities/openline-configs/fields).
Пример: `{"active": false}` | | `limit` | number | `50` | `1`–`200` | Количество записей на запрос | | `offset` | number | `0` | `0` и больше | Пропустить N записей | | `sort` | string | — | `id`, `name`, `active`, `queueType`, `workTimeFrom`, `workTimeTo` | Поле для сортировки | | `order` | string | `asc` | `asc`, `desc` | Направление сортировки | Пустое тело запроса возвращает все конфигурации — эквивалент `GET /v1/openline-configs` без параметров. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/openline-configs/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true }, "limit": 3, "sort": "id", "order": "desc" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/openline-configs/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true }, "limit": 3, "sort": "id", "order": "desc" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, limit: 3, sort: 'id', order: 'desc', }), }) const { success, data, total } = await res.json() console.log('Найдено:', total, 'записей, возвращено:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, limit: 3, sort: 'id', order: 'desc', }), }) const { success, data, total } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив конфигураций (все поля — см. [Поля конфигурации](/docs/entities/openline-configs/fields)) | | `total` | number | Количество записей в текущей странице (не общий счётчик портала — Битрикс24 не передаёт глобальный total для этого метода) | | `limit` | number | Применённое ограничение на количество записей | | `offset` | number | Применённое смещение | | `hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 21, "active": true, "name": "Открытая линия 12", "queueType": "all", "workTimeFrom": "9", "workTimeTo": "18.30", "CRM": "Y", "CRM_CREATE": "lead", "QUEUE_TIME": "60", "NO_ANSWER_TIME": "60", "WELCOME_MESSAGE": "Y", "DATE_CREATE": {}, "DATE_MODIFY": {} } ], "total": 10, "limit": 3, "offset": 0, "hasMore": true } ``` Показаны основные поля. Каждый элемент массива содержит ~91 поле. Полный список — [Поля конфигурации](/docs/entities/openline-configs/fields). ## Пример ответа при ошибке 400 — неизвестное поле сортировки: ```json { "success": false, "error": { "code": "UNKNOWN_SORT_FIELD", "message": "Unknown sort field: statusCode" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_SORT_FIELD` | Передано поле `sort`, которого нет в схеме | | 401 | `TOKEN_MISSING` | Не передан `X-Api-Key` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Пустое тело возвращает все записи** — эквивалент `GET /v1/openline-configs` без параметров. Остальные особенности — те же, что и у списка (`total` как счётчик текущей страницы, фильтр и сортировка только по camelCase-полям схемы, отсутствие полей очереди операторов): подробности — [Известные особенности списка](/docs/entities/openline-configs/list). ## Смотрите также - [Список конфигураций](/docs/entities/openline-configs/list) - [Поля конфигурации](/docs/entities/openline-configs/fields) - [Синтаксис фильтрации](/docs/filtering) --- # Openline Configs: Update ## Обновить конфигурацию открытой линии `PATCH /v1/openline-configs/:id` Обновляет поля существующей конфигурации открытой линии. Передайте только изменяемые поля — остальные не затрагиваются. Полный список полей — [Поля конфигурации](/docs/entities/openline-configs/fields). ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Числовой идентификатор конфигурации | ## Поля запроса (body) Поля передаются в UPPER_SNAKE_CASE. Тело запроса не должно быть пустым — обязательно наличие хотя бы одного поля. | Поле | Тип | Описание | |------|-----|---------| | `LINE_NAME` | string | Название открытой линии | | `ACTIVE` | boolean | Включена ли линия | | `QUEUE_TIME` | number | Время ожидания ответа оператора (секунды) | | `NO_ANSWER_TIME` | number | Время до сработывания правила «Нет ответа» (секунды) | | `WELCOME_MESSAGE_TEXT` | string | Текст приветственного сообщения | | `WORKTIME_FROM` | string | Начало рабочего времени, например `"9"` или `"9.30"` | | `WORKTIME_TO` | string | Конец рабочего времени, например `"18"` или `"17.30"` | | `WORKTIME_TIMEZONE` | string | Часовой пояс рабочего времени | Полный список доступных полей — [Поля конфигурации](/docs/entities/openline-configs/fields). ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/openline-configs/29" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "QUEUE_TIME": 120, "WELCOME_MESSAGE_TEXT": "Здравствуйте! Чем можем помочь?" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/openline-configs/29" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "QUEUE_TIME": 120, "WELCOME_MESSAGE_TEXT": "Здравствуйте! Чем можем помочь?" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/29', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ QUEUE_TIME: 120, WELCOME_MESSAGE_TEXT: 'Здравствуйте! Чем можем помочь?', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/openline-configs/29', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ QUEUE_TIME: 120, WELCOME_MESSAGE_TEXT: 'Здравствуйте! Чем можем помочь?', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Результат операции | | `data.id` | number | Идентификатор обновлённой конфигурации | | `data.updated` | boolean | `true` — обновление применено | ## Пример ответа ```json { "success": true, "data": { "id": 29, "updated": true } } ``` ## Пример ответа при ошибке 404 — конфигурация не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "openlineConfig 99999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_ID` | Параметр `id` не является положительным целым числом | | 400 | `VALIDATION_ERROR` | Тело запроса пустое — необходимо передать хотя бы одно поле | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `imopenlines` | | 404 | `ENTITY_NOT_FOUND` | Конфигурация с указанным `id` не существует | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности Ответ содержит только `id` и `data.updated: true` — полей конфигурации в ответе нет. Чтобы получить актуальные значения всех полей после обновления, выполните `GET /v1/openline-configs/:id`. ## Смотрите также - [Получить конфигурацию](/docs/entities/openline-configs/get) — текущие значения полей - [Поля конфигурации](/docs/entities/openline-configs/fields) — полный список изменяемых полей - [Список конфигураций](/docs/entities/openline-configs/list) — все конфигурации на портале - [Batch](/docs/batch) — массовое обновление записей --- # Order Statuses: Aggregate ## Агрегация статусов заказов `POST /v1/order-statuses/aggregate` Подсчёт количества статусов с группировкой по `type` или `notify`. У сущности нет числовых полей, поэтому числовые функции (`sum`, `avg`) не применяются — основной сценарий — `count` с фильтром или группировкой. ## Стандартные поля Все поля статуса категориальные — подходят только для `groupBy` и `filter`: | Поле | Назначение | |------|------------| | `type` | Группировка по типу: `O` (заказа) или `D` (доставки) | | `notify` | Группировка по тому, отправляется ли уведомление | Полный список агрегируемых полей перечислен в таблице выше. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Для статусов основной вариант — `count` (без других функций, числовых полей нет). Без параметра — `count` записей с учётом фильтра | | `filter` | object | нет | Фильтрация — те же поля, что в [`GET /v1/order-statuses`](./list.md). [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5) | | `groupOrderBy` | array | нет | Сортировка групп: `[{ "field": "count", "direction": "desc" }]` | | `groupLimit` | number | нет | Ограничение количества возвращаемых групп (1-1000) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/order-statuses/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "groupBy": "type" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/order-statuses/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "groupBy": "type" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ groupBy: 'type', }), }) const { success, data } = await res.json() console.log('Распределение статусов:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ groupBy: 'type', }), }) const { success, data } = await res.json() ``` ## Другие сценарии Общее количество статусов на портале: ```json {} ``` Сколько статусов с включённым уведомлением: ```json { "filter": { "notify": true } } ``` Группировка по обоим осям сразу: ```json { "groupBy": ["type", "notify"] } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество статусов, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций — для статусов остаётся пустым (нет числовых полей в `aggregatable`) | | `data.groups` | array | Группы (только при `groupBy`) | | `data.meta.totalRecords` | number | Общее количество записей | | `data.meta.recordsProcessed` | number | Количество обработанных записей | | `data.meta.truncated` | boolean | `true`, если записей больше 5000 | | `data.meta.groupTotal` | number | Количество групп до `groupLimit` | | `data.meta.groupsTruncated` | boolean | Был ли список групп обрезан `groupLimit` | ## Пример ответа ```json { "success": true, "data": { "count": 9, "aggregates": {}, "groups": [ { "type": "O", "count": 6, "aggregates": {} }, { "type": "D", "count": 3, "aggregates": {} } ], "meta": { "totalRecords": 9, "recordsProcessed": 9, "truncated": false, "groupTotal": 2, "groupsTruncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неизвестное поле в `groupBy`: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Unknown field 'foo'. Available: type, notify" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Неизвестная функция или несуществующее поле — сообщение содержит список допустимых полей | | 400 | `INVALID_PARAMS` | Передано больше 5 полей в `groupBy` | | 400 | `INVALID_PARAMS` | Зарезервированные ключевые слова в `groupBy`: `count`, `aggregates`, `meta`, `groups` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только `count` имеет смысл.** Поскольку в схеме статуса нет числовых полей в `aggregatable`, функции `sum` / `avg` / `min` / `max` всегда возвращают пустой `aggregates`. Для подсчёта статусов используйте `count` (без `aggregate`) с фильтром или группировкой. **Малый объём данных.** На порталах число статусов измеряется десятками, поэтому `meta.truncated` (срабатывает только при > 5000 записей) для этой сущности не активируется. ## Смотрите также - [Список статусов](./list.md) — `meta.total` даёт точное число записей - [Поиск статусов](./search.md) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Order Statuses: Create ## Создать статус заказа `POST /v1/order-statuses` Создаёт новый статус для заказа или доставки. Символьный код `id` задаёт пользователь — он используется как ссылка в [`orders.statusId`](../orders/fields.md). ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` | string | да | Символьный код статуса (1-2 символа). Например: `N`, `IP`, `DT`. Должен быть уникальным независимо от типа | | `type` | string | да | Тип статуса: `O` — статус заказа, `D` — статус доставки | | `sort` | number | нет | Порядок сортировки в списках. По умолчанию `100` | | `notify` | boolean | нет | Отправлять ли уведомление клиенту при переходе в этот статус. По умолчанию `true` | | `color` | string | нет | HEX-код цвета для отображения (`#FFA500`). По умолчанию — стандартный голубой | | `xmlId` | string | нет | Внешний идентификатор для синхронизации | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/order-statuses" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "id": "DT", "type": "O", "sort": 160, "notify": true, "color": "#FFA500", "xmlId": "external_delivered" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/order-statuses" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "id": "DT", "type": "O", "sort": 160, "notify": true, "color": "#FFA500", "xmlId": "external_delivered" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ id: 'DT', type: 'O', sort: 160, notify: true, color: '#FFA500', xmlId: 'external_delivered', }), }) const { success, data } = await res.json() console.log('Status created:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ id: 'DT', type: 'O', sort: 160, notify: true, color: '#FFA500', xmlId: 'external_delivered', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданного статуса со всеми переданными полями. | Поле | Тип | Описание | |------|-----|---------| | `id` | string | Символьный код, переданный в запросе | | `type` | string | Тип статуса | | `sort` | number | Порядок сортировки | | `notify` | boolean | Уведомление клиента | | `color` | string | HEX-код цвета | | `xmlId` | string | Внешний идентификатор | ## Пример ответа ```json { "success": true, "data": { "id": "DT", "type": "O", "sort": 160, "notify": true, "color": "#FFA500", "xmlId": "external_delivered" } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные поля: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Required fields: id, type" } } ``` ## Ошибки | HTTP | `error.code` | Маркер в `error.message` | Описание | |------|--------------|--------------------------|---------| | 400 | `BITRIX_ERROR` | `Required fields: id, type` | Не переданы обязательные поля `id` или `type` | | 400 | `BITRIX_ERROR` | `Duplicate entry` | Статус с таким `id` уже существует — `id` должен быть уникальным независимо от типа | | 400 | `BITRIX_ERROR` | — | Длина `id` превышает 2 символа | | 400 | `BITRIX_ERROR` | — | Передано пустое значение `id` | | 403 | `SCOPE_DENIED` | — | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | — | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Уникальность `id` глобальная.** Битрикс24 не позволяет создать статус заказа и статус доставки с одинаковым `id`. Перед созданием проверьте, что код не занят, через [`GET /v1/order-statuses`](./list.md). ## Смотрите также - [Список статусов](./list.md) — проверить уникальность `id` перед созданием - [Получить статус](./get.md) — полные данные после создания - [Обновить статус](./update.md) — изменить `sort` / `color` / `notify` - [Обновить заказ](../orders/update.md) — использовать новый статус в заказе через `statusId` - [Batch](/docs/batch) — массовое создание - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Order Statuses: Delete ## Удалить статус заказа `DELETE /v1/order-statuses/:id` Удаляет статус заказа или доставки по символьному коду. Восстановить удалённый статус через API нельзя — создавайте новый при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | string | да | Символьный код статуса | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/order-statuses/DT" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/order-statuses/DT" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/DT', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Статус удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/DT', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Статус удалён') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — статус не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "status is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Статус с таким `id` не найден или уже удалён | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Заказы со ссылкой на удалённый статус продолжают работать.** При удалении статуса заказы с этим `statusId` не меняются — поле `orders.statusId` сохраняет старое значение. В интерфейсе портала такой заказ будет показан с пустым названием статуса. Для миграции — перед удалением статуса выполните [`PATCH /v1/orders/:id`](../orders/update.md) для всех затронутых заказов. **Стандартные статусы удаляются тем же запросом.** Статусы по умолчанию (`N`, `P`, `F`, `D` и другие) для Битрикс24 не системные — удалить их можно тем же `DELETE /v1/order-statuses/:id`, что и пользовательские. Перед удалением убедитесь, что они не используются в существующих заказах. ## Смотрите также - [Список статусов](./list.md) — найти `id` статуса перед удалением - [Список заказов в статусе](../orders/list.md) — `GET /v1/orders?filter[statusId]=:id` перед удалением - [Обновить заказ](../orders/update.md) — перенести заказы на другой статус перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Order Statuses: Get ## Получить статус заказа `GET /v1/order-statuses/:id` Возвращает один статус заказа или доставки по символьному коду. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | string | да | Символьный код статуса (например, `N`, `IP`, `DT`) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/order-statuses/N" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/order-statuses/N" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/N', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Статус:', data.id, '— тип:', data.type) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/N', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | string | Символьный код статуса | | `type` | string | Тип статуса: `O` — заказа, `D` — доставки | | `sort` | number | Порядок сортировки | | `notify` | boolean | Отправлять ли уведомление клиенту | | `color` | string | HEX-код цвета | | `xmlId` | string | Внешний идентификатор | ## Пример ответа ```json { "success": true, "data": { "id": "N", "type": "O", "sort": 100, "notify": true, "color": "#ACE9FB", "xmlId": null } } ``` ## Пример ответа при ошибке 422 — статус не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "status is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Статус с таким `id` не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить статус](./update.md) — изменение полей - [Удалить статус](./delete.md) — удаление по ID - [Список статусов](./list.md) — все статусы - [Заказы в этом статусе](../orders/list.md) — `GET /v1/orders?filter[statusId]=:id` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Order Statuses: List ## Список статусов заказов `GET /v1/order-statuses` Возвращает список статусов заказов и доставки с поддержкой фильтрации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string | — | Выборка полей: `?select=id,type,sort,color` | | `order` | object | — | Сортировка: `?order[sort]=asc` | | `filter` | object | — | Фильтрация по полям статуса.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[type]=O` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/order-statuses?filter[type]=O&order[sort]=asc" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/order-statuses?filter[type]=O&order[sort]=asc" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses?filter[type]=O&order[sort]=asc', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Статусов заказа: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses?filter[type]=O&order[sort]=asc', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив статусов | | `data[].id` | string | Символьный код статуса | | `data[].type` | string | Тип статуса: `O` — заказа, `D` — доставки | | `data[].sort` | number | Порядок сортировки | | `data[].notify` | boolean | Отправлять ли уведомление клиенту | | `data[].color` | string | HEX-код цвета | | `data[].xmlId` | string | Внешний идентификатор | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": "T", "type": "O", "sort": 30, "notify": true, "color": "#ACE9FB", "xmlId": null }, { "id": "N", "type": "O", "sort": 100, "notify": true, "color": "#ACE9FB", "xmlId": null }, { "id": "S", "type": "O", "sort": 110, "notify": true, "color": "#ACE9FB", "xmlId": null }, { "id": "P", "type": "O", "sort": 130, "notify": true, "color": "#ACE9FB", "xmlId": null }, { "id": "D", "type": "O", "sort": 140, "notify": true, "color": "#FFBEBD", "xmlId": null }, { "id": "F", "type": "O", "sort": 200, "notify": true, "color": "#DBF199", "xmlId": null } ], "meta": { "total": 6, "hasMore": false } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'sale' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме статуса | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Разделение по типу.** По умолчанию ответ включает статусы обоих типов — заказа и доставки. Чтобы получить только статусы заказа, добавьте `filter[type]=O`; для доставки — `filter[type]=D`. ## Смотрите также - [Поиск статусов](./search.md) — POST-запрос для сложных фильтров - [Получить статус](./get.md) — один статус по ID - [Создать статус](./create.md) — добавить новый статус - [Заказ](../orders/list.md) — `filter[statusId]=:id` для поиска заказов в статусе - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Order Statuses: Search ## Поиск статусов заказов `POST /v1/order-statuses/search` Поиск статусов с фильтрацией. Аналогичен [`GET /v1/order-statuses`](./list.md), но через POST — удобнее для сложных запросов с несколькими условиями. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям статуса.
[Синтаксис фильтрации](/docs/filtering) | | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string[] | — | Выборка полей: `["id", "type", "sort", "color"]` | | `order` | object | — | Сортировка: `{ "sort": "asc" }` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/order-statuses/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "type": "O", "notify": true }, "select": ["id", "type", "sort", "color"] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/order-statuses/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "type": "O", "notify": true }, "select": ["id", "type", "sort", "color"] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { type: 'O', notify: true }, select: ['id', 'type', 'sort', 'color'], }), }) const { success, data, meta } = await res.json() console.log('Статусов с уведомлением:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { type: 'O', notify: true }, select: ['id', 'type', 'sort', 'color'], }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив статусов | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": "T", "type": "O", "sort": 30, "color": "#ACE9FB" }, { "id": "N", "type": "O", "sort": 100, "color": "#ACE9FB" }, { "id": "S", "type": "O", "sort": 110, "color": "#ACE9FB" }, { "id": "P", "type": "O", "sort": 130, "color": "#ACE9FB" }, { "id": "D", "type": "O", "sort": 140, "color": "#FFBEBD" }, { "id": "F", "type": "O", "sort": 200, "color": "#DBF199" } ], "meta": { "total": 6, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown field 'foo'. Available: id, type, sort, notify, color, xmlId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме статуса | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`select` ограничивает поля в ответе.** Если передан `select`, в каждом элементе `data[]` будут только перечисленные поля. Без `select` возвращаются все поля статуса. ## Смотрите также - [Список статусов](./list.md) — GET-запрос с query-параметрами (для простых фильтров) - [Получить статус](./get.md) — данные одного статуса по ID - [Заказы](../orders/list.md) — фильтр `filter[statusId]` для поиска заказов в статусе - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Order Statuses: Update ## Обновить статус заказа `PATCH /v1/order-statuses/:id` Обновляет параметры существующего статуса. Передавайте только изменяемые поля плоско в корне JSON — без обёртки `fields`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | string | да | Символьный код статуса | ## Поля для обновления (body) | Параметр | Тип | Описание | |----------|-----|---------| | `sort` | number | Порядок сортировки | | `notify` | boolean | Отправлять ли уведомление клиенту | | `color` | string | HEX-код цвета (`#FFA500`) | | `xmlId` | string | Внешний идентификатор | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/order-statuses/T" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "sort": 35, "color": "#2ECC71" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/order-statuses/T" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "sort": 35, "color": "#2ECC71" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/T', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ sort: 35, color: '#2ECC71', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/order-statuses/T', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ sort: 35, color: '#2ECC71', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект статуса со всеми полями | ## Пример ответа ```json { "success": true, "data": { "id": "T", "type": "O", "sort": 35, "notify": true, "color": "#2ECC71", "xmlId": null } } ``` ## Пример ответа при ошибке 422 — статус не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "status is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Статус с таким `id` не найден | | 400 | `BITRIX_ERROR` | Некорректное значение поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поле `type` подтягивается автоматически.** Вайбкод перед обновлением статуса получает текущее значение `type` через `GET /v1/order-statuses/:id` и автоматически добавляет его в запрос, если оно не передано. Это даёт привычную семантику `PATCH` с одним полем — без необходимости каждый раз указывать тип. **Поле `id` не редактируется.** Изменить символьный код статуса нельзя — `PATCH` принимает остальные поля, но не сам `id`. Чтобы переименовать статус, удалите старый и создайте новый с нужным `id`. Внимание: заказы со ссылкой на старый `id` останутся с этой ссылкой и продолжат работать. ## Смотрите также - [Получить статус](./get.md) — текущие значения перед обновлением - [Список статусов](./list.md) — найти статус по фильтру - [Удалить статус](./delete.md) — необратимое удаление - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: Aggregate ## Агрегация заказов `POST /v1/orders/aggregate` Подсчёт количества заказов и числовые агрегации (`sum`, `avg`, `min`, `max`) по полю `price`. Поддерживает фильтрацию и группировку по `statusId`, `payed`, `canceled`, `personTypeId`, `responsibleId`, `userId`. ## Стандартные поля | Поле | Назначение | |------|------------| | `price` | Единственное числовое поле — подходит для `sum` / `avg` / `min` / `max` | | `statusId` | Категориальное — используется в `groupBy` (статусы заказов) | | `payed`, `canceled` | Логические — используются в `groupBy` (оплачен / отменён) | | `personTypeId`, `responsibleId`, `userId` | Идентификаторы — используются в `groupBy` (по типу плательщика, ответственному, покупателю) | Полный список агрегируемых полей — массив `aggregatable` в [`GET /v1/orders/fields`](./fields.md). ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций: `[{ "field": "price", "function": "sum" }]`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без параметра — только `count` (один запрос в Битрикс24, записи не выгружаются) | | `filter` | object | нет | Фильтрация — те же поля, что в [`GET /v1/orders`](./list.md). [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из массива `aggregatable` | | `groupOrderBy` | array | нет | Сортировка групп: `[{ "field": "price:sum", "direction": "desc" }]`. Поля: `count`, имя dim из `groupBy`, или `:` | | `groupLimit` | number | нет | Ограничение количества возвращаемых групп (1-1000) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/orders/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "price", "function": "sum" }, { "field": "price", "function": "avg" } ], "groupBy": "statusId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/orders/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "price", "function": "sum" }, { "field": "price", "function": "avg" } ], "groupBy": "statusId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'price', function: 'sum' }, { field: 'price', function: 'avg' }, ], groupBy: 'statusId', }), }) const { success, data } = await res.json() // data.groups — массив групп по statusId console.log(data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'price', function: 'sum' }], groupBy: 'statusId', }), }) const { success, data } = await res.json() ``` ## Другие сценарии Только подсчёт записей без выгрузки данных (один запрос в Битрикс24, быстро): ```json {} ``` Сумма по всем заказам без группировки: ```json { "aggregate": [{ "field": "price", "function": "sum" }] } ``` Топ-3 статуса по сумме оплат с сортировкой: ```json { "aggregate": [{ "field": "price", "function": "sum" }], "groupBy": "statusId", "groupOrderBy": [{ "field": "price:sum", "direction": "desc" }], "groupLimit": 3 } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество заказов, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций: `{ "price": { "sum": ..., "avg": ... } }` | | `data.groups` | array | Группы (присутствует только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей, обработанных для агрегации | | `data.meta.recordsProcessed` | number | Количество обработанных записей (до 5000) | | `data.meta.truncated` | boolean | `true`, если записей больше 5000 — агрегация по первым 5000 | | `data.meta.groupTotal` | number | Количество групп до применения `groupLimit` (только при `groupBy`) | | `data.meta.groupsTruncated` | boolean | Был ли список групп обрезан `groupLimit` | ## Пример ответа ```json { "success": true, "data": { "count": 194, "aggregates": { "price": { "sum": 2890284.0999999996 } }, "groups": [ { "statusId": "N", "count": 181, "aggregates": { "price": { "sum": 2876316.6299999994 } } }, { "statusId": "T", "count": 8, "aggregates": { "price": { "sum": 2998.5 } } }, { "statusId": "P", "count": 6, "aggregates": { "price": { "sum": 9958.97 } } }, { "statusId": "F", "count": 1, "aggregates": { "price": { "sum": 1010 } } }, { "statusId": "S", "count": 1, "aggregates": { "price": { "sum": 0 } } } ], "meta": { "totalRecords": 194, "recordsProcessed": 194, "truncated": false, "groupTotal": 5, "groupsTruncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неизвестное поле в `groupBy`: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Unknown field 'foo'. Available: price, statusId, payed, canceled, personTypeId, responsibleId, userId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Неизвестная функция или несуществующее поле в `aggregate` / `groupBy` — сообщение содержит список допустимых полей | | 400 | `INVALID_PARAMS` | Передано больше 5 полей в `groupBy` | | 400 | `INVALID_PARAMS` | Зарезервированные ключевые слова в `groupBy`: `count`, `aggregates`, `meta`, `groups` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` против числовых функций.** `count` считается одним запросом в Битрикс24 — записи не выгружаются, ответ возвращается быстро на любом объёме. `sum` / `avg` / `min` / `max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод. При более чем 5000 записях `meta.truncated` будет `true`, и агрегация выполняется по первым 5000. **Логические поля в группировке.** `groupBy: "payed"` или `groupBy: "canceled"` возвращает группы со значениями `true` / `false`. ## Смотрите также - [Список заказов](./list.md) — `meta.total` даёт точное число записей - [Поиск заказов](./search.md) — POST-запрос с фильтрами - [Поля заказа](./fields.md) — массив `aggregatable` с полным списком допустимых полей - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: Create ## Создать заказ `POST /v1/orders` Создаёт новый заказ интернет-магазина. Тело запроса плоское — без обёртки `fields`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `lid` | string | да | Идентификатор сайта-источника. Для облачных порталов всегда `"s1"` | | `personTypeId` | number | да | Идентификатор типа плательщика. На каждом портале свой набор типов (юр. лицо, физ. лицо и т. п.). REST API не выставляет эндпоинт для перечисления типов; ID можно увидеть в существующих заказах через [`GET /v1/orders`](./list.md) или [`POST /v1/orders/aggregate`](./aggregate.md) с `groupBy: "personTypeId"` | | `currency` | string | да | Валюта заказа. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `price` | number | нет | Общая сумма заказа | | `statusId` | string | нет | Статус заказа. По умолчанию — `"N"` (новый). Список: [`GET /v1/order-statuses?filter[type]=O`](../order-statuses/list.md) | | `userId` | number | нет | Идентификатор пользователя Битрикс24 — покупателя в интернет-магазине. Источник: [`GET /v1/users`](/docs/entities/users). Если не передать — Битрикс24 проставит пользователя по умолчанию | | `companyId` | number | нет | Идентификатор CRM-компании, связанной с заказом. Источник: [`GET /v1/companies`](/docs/entities/companies) | | `responsibleId` | number | нет | Ответственный сотрудник. Источник: [`GET /v1/users`](/docs/entities/users) | | `comments` | string | нет | Комментарий менеджера к заказу | | `userDescription` | string | нет | Комментарий покупателя к заказу | | `xmlId` | string | нет | Внешний идентификатор для синхронизации с внешними системами | | `payed` | boolean | нет | Оплачен ли заказ | | `canceled` | boolean | нет | Отменён ли заказ | | `reasonCanceled` | string | нет | Причина отмены | | `discountValue` | number | нет | Значение скидки | Полный список полей — [`GET /v1/orders/fields`](./fields.md). ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/orders" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "lid": "s1", "personTypeId": 5, "currency": "RUB", "price": 12500, "statusId": "N", "userId": 1, "comments": "Заказ из мобильного приложения" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/orders" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "lid": "s1", "personTypeId": 5, "currency": "RUB", "price": 12500, "statusId": "N", "userId": 1, "comments": "Заказ из мобильного приложения" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ lid: 's1', personTypeId: 5, currency: 'RUB', price: 12500, statusId: 'N', userId: 1, comments: 'Заказ из мобильного приложения', }), }) const { success, data } = await res.json() console.log('Order ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ lid: 's1', personTypeId: 5, currency: 'RUB', price: 12500, statusId: 'N', userId: 1, comments: 'Заказ из мобильного приложения', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданного заказа со всеми полями. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор созданного заказа | | `accountNumber` | string | Порядковый номер заказа на портале (генерируется автоматически) | | `dateInsert` | datetime | Дата создания | | `dateStatus` | datetime | Дата установки текущего статуса | Остальные поля — см. [Поля заказа](./fields.md). URL заказа в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/shop/orders/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 859, "accountNumber": "450", "lid": "s1", "personTypeId": 5, "currency": "RUB", "price": 12500, "discountValue": 0, "taxValue": 0, "sumPaid": 0, "statusId": "N", "dateInsert": "2026-05-13T11:42:18.000Z", "dateUpdate": "2026-05-13T11:42:18.000Z", "dateStatus": "2026-05-13T11:42:18.000Z", "payed": false, "canceled": false, "marked": false, "responsibleId": 1, "userId": 1, "companyId": null, "clients": [ { "entityTypeId": 3, "entityId": 2471, "isPrimary": "Y", "roleId": 0, "sort": 0 } ], "comments": "Заказ из мобильного приложения", "xmlId": "", "externalOrder": false } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные поля: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Required fields: personTypeId, currency, lid" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `BITRIX_ERROR` | Не переданы обязательные поля — сообщение содержит их список (`Required fields: ...`) | | 400 | `BITRIX_ERROR` | Некорректное значение поля — например, ссылка на несуществующий `statusId` или `userId` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Номер счёта генерируется автоматически.** Поле `accountNumber` присваивается Битрикс24 при создании и не может быть передано в запросе — даже если передать, оно будет проигнорировано. **Позиции корзины и оплаты добавляются отдельно.** Заказ — это контейнер. После `POST /v1/orders` для добавления товаров вызовите [`POST /v1/basket-items`](../basket-items/create.md) с `orderId`, для регистрации оплаты — [`POST /v1/payments`](../payments/create.md). ## Смотрите также - [Список заказов](./list.md) — посмотреть существующие заказы перед созданием - [Получить заказ](./get.md) — полные данные после создания - [Обновить заказ](./update.md) — изменить параметры созданного заказа - [Добавить позицию корзины](../basket-items/create.md) — следующий шаг после создания заказа - [Создать оплату](../payments/create.md) — зарегистрировать платёж - [Batch](/docs/batch) — массовое создание - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: Delete ## Удалить заказ `DELETE /v1/orders/:id` Удаляет заказ по идентификатору вместе со связанными позициями корзины и оплатами. Восстановить удалённый заказ через API нельзя — создавайте новый при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор заказа | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/orders/859" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/orders/859" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/859', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Заказ удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/859', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Заказ удалён') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — заказ не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "order is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Заказ с таким ID не найден или уже удалён | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Каскадное удаление.** Удаление заказа автоматически удаляет связанные позиции корзины и оплаты — отдельно вызывать `DELETE /v1/basket-items/:id` или `DELETE /v1/payments/:id` не нужно. **Альтернатива — отмена вместо удаления.** Чтобы сохранить историю и связи, лучше отменить заказ через [`PATCH /v1/orders/:id`](./update.md) с `{"canceled": true, "reasonCanceled": "..."}` — заказ останется в выборках с `filter[canceled]=true`. ## Смотрите также - [Обновить заказ](./update.md) — отмена вместо удаления (`canceled: true`) - [Список заказов](./list.md) — найти ID заказа перед удалением - [Получить заказ](./get.md) — проверить состояние перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: Fields ## Поля заказа `GET /v1/orders/fields` Возвращает схему полей заказа: типы, флаги только-для-чтения, список агрегируемых полей. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/orders/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/orders/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { data } = await res.json() console.log('Поля заказа:', Object.keys(data.fields)) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор заказа (только чтение) | | `accountNumber` | string | Порядковый номер заказа на портале | | `lid` | string | Идентификатор сайта-источника (всегда `"s1"` для облачных порталов) | | `personTypeId` | number | Идентификатор типа плательщика | | `currency` | string | Валюта заказа. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `price` | number | Общая сумма заказа | | `discountValue` | number | Значение скидки | | `taxValue` | number | Сумма налога | | `sumPaid` | number | Сумма, уже оплаченная по этому заказу | | `statusId` | string | Текущий статус заказа. Источник: [`GET /v1/order-statuses?filter[type]=O`](../order-statuses/list.md) | | `userId` | number | Идентификатор пользователя Битрикс24 — покупателя в интернет-магазине. Источник: [`GET /v1/users`](/docs/entities/users) | | `companyId` | number | Идентификатор CRM-компании, связанной с заказом. Источник: [`GET /v1/companies`](/docs/entities/companies) | | `clients` | array | Список CRM-привязок к заказу (только чтение). Каждый элемент: `{entityTypeId, entityId, isPrimary, roleId, sort}`. `entityTypeId = 3` — контакт ([`GET /v1/contacts`](/docs/entities/contacts)), `= 4` — компания ([`GET /v1/companies`](/docs/entities/companies)). Битрикс24 заполняет массив автоматически на основе `userId` и `companyId` | | `responsibleId` | number | Ответственный сотрудник. Источник: [`GET /v1/users`](/docs/entities/users) | | `payed` | boolean | Оплачен ли заказ полностью | | `canceled` | boolean | Отменён ли заказ | | `marked` | boolean | Отмечен ли заказ как проблемный | | `deducted` | boolean | Списан ли товар со склада | | `reserved` | boolean | Зарезервирован ли товар на складе | | `reasonCanceled` | string | Причина отмены | | `reasonMarked` | string | Причина пометки | | `additionalInfo` | string | Дополнительная информация | | `comments` | string | Комментарий менеджера к заказу | | `userDescription` | string | Комментарий покупателя к заказу | | `orderTopic` | string | Тема заказа | | `xmlId` | string | Внешний идентификатор для синхронизации | | `id1c` | string | Идентификатор в 1С | | `version1c` | string | Версия в 1С | | `updated1c` | boolean | Обновлён ли заказ через 1С | | `externalOrder` | boolean | Создан ли заказ во внешней системе | | `recountFlag` | boolean | Флаг автоматического пересчёта | | `affiliateId` | number | Идентификатор партнёра-аффилиата | | `lockedBy` | number | Идентификатор пользователя, заблокировавшего заказ (актуально для коробочных порталов) | | `dateLock` | datetime | Время блокировки | | `recurringId` | number | Идентификатор подписки (если заказ создан из рекуррентного шаблона) | | `dateInsert` | datetime | Дата создания (только чтение) | | `dateUpdate` | datetime | Дата последнего изменения (только чтение) | | `datePaid` | datetime | Дата оплаты (только чтение) | | `dateCanceled` | datetime | Дата отмены (только чтение) | | `dateStatus` | datetime | Дата установки текущего статуса (только чтение) | | `dateBill` | datetime | Дата выставления счёта | | `datePayBefore` | datetime | Дата, до которой нужно оплатить | | `empPaidId` | number | Сотрудник, отметивший оплату (только чтение) | | `empCanceledId` | number | Сотрудник, отменивший заказ (только чтение) | | `empMarkedId` | number | Сотрудник, поставивший пометку (только чтение) | | `empStatusId` | number | Сотрудник, последний раз менявший статус (только чтение) | | `userEmail` | string | E-mail покупателя (только чтение, заполняется из карточки контакта) | | `userName` | string | Имя покупателя (только чтение, заполняется из карточки контакта) | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "accountNumber": { "type": "string", "readonly": false }, "price": { "type": "number", "readonly": false }, "currency": { "type": "string", "readonly": false }, "statusId": { "type": "string", "readonly": false }, "userId": { "type": "number", "readonly": false }, "dateInsert": { "type": "datetime", "readonly": true }, "dateUpdate": { "type": "datetime", "readonly": true }, "payed": { "type": "boolean", "readonly": false }, "canceled": { "type": "boolean", "readonly": false } }, "aggregatable": ["price", "statusId", "payed", "canceled", "personTypeId", "responsibleId", "userId"], "batch": ["create", "update", "delete"] } } ``` Показаны самые важные поля. Полный набор описан в таблице выше — этот же набор возвращается живым вызовом `GET /v1/orders/fields`. ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'sale' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список заказов](./list.md) — использует поля для `select`, `filter`, `order` - [Создать заказ](./create.md) — какие поля можно передавать в body - [Агрегация заказов](./aggregate.md) — какие поля поддерживают `sum` / `avg` / `groupBy` (массив `aggregatable`) - [Entity API](/docs/entity-api) — общие принципы работы с сущностями - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: Get ## Получить заказ `GET /v1/orders/:id` Возвращает один заказ по идентификатору со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор заказа | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/orders/845" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/orders/845" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/845', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Заказ:', data.accountNumber, '—', data.price, data.currency) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/845', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект заказа со всеми полями — см. [Поля заказа](./fields.md). Дополнительно ответ содержит вложенные массивы: | Поле | Описание | |------|---------| | `basketItems[]` | Полные объекты [позиций корзины](../basket-items.md) этого заказа | | `payments[]` | Полные объекты [оплат](../payments.md) этого заказа | | `propertyValues[]` | Значения свойств заказа: ФИО, e-mail, телефон, адрес доставки и другие (зависит от настройки портала) | | `clients[]` | CRM-привязки к контактам/компаниям | | `requisiteLink` | Связь с реквизитами получателя | | `tradeBindings[]` | Привязки к внешним торговым площадкам | ## Пример ответа ```json { "success": true, "data": { "id": 845, "accountNumber": "443", "lid": "s1", "personTypeId": 5, "currency": "RUB", "price": 100, "discountValue": 0, "taxValue": 0, "sumPaid": 0, "statusId": "N", "dateInsert": "2026-04-21T06:48:16.000Z", "dateUpdate": "2026-04-21T06:48:16.000Z", "dateStatus": "2026-04-21T06:48:16.000Z", "payed": false, "canceled": false, "marked": false, "deducted": false, "responsibleId": 1, "userId": 1, "companyId": 15, "clients": [ { "entityTypeId": 3, "entityId": 2471, "isPrimary": "Y", "roleId": 0, "sort": 0 }, { "entityTypeId": 4, "entityId": 15, "isPrimary": "Y", "roleId": 0, "sort": 0 } ], "basketItems": [ { "id": 187, "productId": 1119, "name": "Спортивный Костюм Розовый Вихрь", "price": 12, "currency": "RUB", "quantity": 1, "vatRate": 0, "vatIncluded": true } ], "payments": [ { "id": 117, "paySystemId": 11, "paySystemName": "Наличные", "sum": 100, "currency": "RUB", "paid": true, "datePaid": "2026-04-21T06:48:16.000Z" } ], "propertyValues": [ { "id": 9311, "orderPropsId": 41, "code": "EMAIL", "name": "E-Mail", "value": "buyer@example.com" } ], "comments": "", "xmlId": "", "externalOrder": false } } ``` ## Пример ответа при ошибке 422 — заказ не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "order is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Заказ с таким ID не найден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Поля заказа](./fields.md) — полный список полей - [Обновить заказ](./update.md) — изменение полей - [Удалить заказ](./delete.md) — удаление по ID - [Список заказов](./list.md) — поиск с фильтрами - [Позиции корзины заказа](../basket-items.md) — `GET /v1/basket-items?filter[orderId]=:id` - [Оплаты заказа](../payments.md) — `GET /v1/payments?filter[orderId]=:id` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: List ## Список заказов `GET /v1/orders` Возвращает список заказов интернет-магазина с поддержкой фильтрации и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `offset` | number | `0` | Пропустить N записей. При `offset ≥ 2500` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,price,currency,statusId` | | `order` | object | — | Сортировка: `?order[id]=desc` | | `filter` | object | — | Фильтрация по полям `GET /v1/orders/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[statusId]=N` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/orders?limit=10&filter[statusId]=N&order[id]=desc" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/orders?limit=10&filter[statusId]=N&order[id]=desc" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders?limit=10&filter[statusId]=N&order[id]=desc', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} заказов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders?limit=10&filter[statusId]=N&order[id]=desc', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив заказов (каждый содержит все поля — см. [Поля заказа](./fields.md)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | URL любого заказа из массива `data` — его `id`: ``` https://.bitrix24.ru/shop/orders/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 845, "accountNumber": "443", "price": 100, "currency": "RUB", "statusId": "N", "userId": 1, "personTypeId": 5, "lid": "s1", "payed": false, "canceled": false, "responsibleId": 1, "dateInsert": "2026-04-21T06:48:16.000Z", "dateUpdate": "2026-04-21T06:48:16.000Z" }, { "id": 841, "accountNumber": "441", "price": 100.5, "currency": "RUB", "statusId": "N", "userId": 9, "personTypeId": 5, "lid": "s1", "payed": false, "canceled": false, "responsibleId": 1, "dateInsert": "2026-04-04T20:02:28.000Z", "dateUpdate": "2026-04-04T20:02:28.000Z" } ], "meta": { "total": 194, "hasMore": true } } ``` Показаны основные поля. Полный список — [Поля заказа](./fields.md). ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'sale' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме. Список полей: [`GET /v1/orders/fields`](./fields.md) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 и возвращает все записи в одном ответе. `meta.total` отражает общее количество записей, удовлетворяющих фильтру. **Когда использовать `search` вместо `list`:** для сложных фильтров с множеством условий удобнее [`POST /v1/orders/search`](./search.md) — параметры передаются в body, а не в query-строке. ## Смотрите также - [Поиск заказов](./search.md) — POST-запрос для сложных фильтров - [Получить заказ](./get.md) — один заказ по ID - [Создать заказ](./create.md) — создание нового - [Поля заказа](./fields.md) — полный список полей - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: Search ## Поиск заказов `POST /v1/orders/search` Поиск заказов с фильтрацией, сортировкой и авто-пагинацией. Аналогичен [`GET /v1/orders`](./list.md), но через POST — удобнее для сложных запросов с большим количеством условий. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/orders/fields`.
[Синтаксис фильтрации](/docs/filtering) | | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string[] | — | Выборка полей: `["id", "price", "currency", "statusId"]` | | `order` | object | — | Сортировка: `{ "id": "desc" }` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/orders/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "statusId": "N", "payed": false }, "limit": 10, "select": ["id", "price", "currency", "statusId", "dateInsert"] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/orders/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "statusId": "N", "payed": false }, "limit": 10, "select": ["id", "price", "currency", "statusId", "dateInsert"] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { statusId: 'N', payed: false }, limit: 10, select: ['id', 'price', 'currency', 'statusId', 'dateInsert'], }), }) const { success, data, meta } = await res.json() console.log('Найдено:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { statusId: 'N', payed: false }, limit: 10, select: ['id', 'price', 'currency', 'statusId', 'dateInsert'], }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив заказов (поля — см. [Поля заказа](./fields.md)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | URL любого заказа из массива `data` — его `id`: ``` https://.bitrix24.ru/shop/orders/details// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 845, "price": 100, "currency": "RUB", "statusId": "N", "dateInsert": "2026-04-21T06:48:16.000Z" }, { "id": 841, "price": 100.5, "currency": "RUB", "statusId": "N", "dateInsert": "2026-04-04T20:02:28.000Z" } ], "meta": { "total": 181, "hasMore": true } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown field 'foo'. Available: id, accountNumber, price, currency, statusId, userId, ..." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме. Список полей: [`GET /v1/orders/fields`](./fields.md) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`select` ограничивает поля в ответе.** Если передан `select`, в каждом элементе `data[]` будут только перечисленные поля. Без `select` возвращаются все поля заказа. ## Смотрите также - [Список заказов](./list.md) — GET-запрос с query-параметрами (для простых фильтров) - [Получить заказ](./get.md) — данные одного заказа по ID - [Поля заказа](./fields.md) — список полей для `filter` и `select` - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Orders: Update ## Обновить заказ `PATCH /v1/orders/:id` Обновляет поля существующего заказа. Передавайте только изменяемые поля плоско в корне JSON — без обёртки `fields`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор заказа | ## Поля для обновления (body) | Параметр | Тип | Описание | |----------|-----|---------| | `statusId` | string | Новый статус заказа. Список: [`GET /v1/order-statuses?filter[type]=O`](../order-statuses/list.md) | | `price` | number | Новая сумма заказа | | `discountValue` | number | Значение скидки | | `payed` | boolean | Оплачен ли заказ | | `canceled` | boolean | Отменён ли заказ | | `reasonCanceled` | string | Причина отмены | | `marked` | boolean | Отмечен ли заказ как проблемный | | `reasonMarked` | string | Причина пометки | | `comments` | string | Комментарий менеджера | | `userDescription` | string | Комментарий покупателя | | `responsibleId` | number | Ответственный сотрудник | | `userId` | number | Пользователь Битрикс24 — покупатель | | `companyId` | number | CRM-компания, связанная с заказом | | `xmlId` | string | Внешний идентификатор | Полный список редактируемых полей — [`GET /v1/orders/fields`](./fields.md) (поля без флага `readonly`). ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/orders/845" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "statusId": "F", "payed": true, "comments": "Закрыт после полной оплаты" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/orders/845" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "statusId": "F", "payed": true, "comments": "Закрыт после полной оплаты" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/845', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ statusId: 'F', payed: true, comments: 'Закрыт после полной оплаты', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/orders/845', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ statusId: 'F', payed: true, comments: 'Закрыт после полной оплаты', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект заказа со всеми полями (см. [Поля заказа](./fields.md)) | ## Пример ответа ```json { "success": true, "data": { "id": 845, "accountNumber": "443", "statusId": "F", "price": 100, "currency": "RUB", "payed": true, "canceled": false, "comments": "Закрыт после полной оплаты", "dateInsert": "2026-04-21T06:48:16.000Z", "dateUpdate": "2026-05-13T11:45:32.000Z", "dateStatus": "2026-05-13T11:45:32.000Z", "userId": 1, "companyId": 15, "clients": [ { "entityTypeId": 3, "entityId": 2471, "isPrimary": "Y", "roleId": 0, "sort": 0 }, { "entityTypeId": 4, "entityId": 15, "isPrimary": "Y", "roleId": 0, "sort": 0 } ], "responsibleId": 1 } } ``` ## Пример ответа при ошибке 422 — заказ не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "order is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Заказ с таким ID не найден | | 400 | `BITRIX_ERROR` | Некорректное значение поля — например, неизвестный `statusId` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Дата `dateStatus` обновляется автоматически.** При изменении `statusId` поле `dateStatus` получает текущее время — не передавайте его в запросе. **Поля `accountNumber`, `dateInsert`, `personTypeXmlId`, `statusXmlId` доступны только для чтения.** Битрикс24 проставляет их при создании; попытка изменить — игнорируется. ## Смотрите также - [Получить заказ](./get.md) — текущие значения полей перед обновлением - [Список заказов](./list.md) — найти заказ по фильтру - [Удалить заказ](./delete.md) — необратимое удаление - [Поля заказа](./fields.md) — какие поля можно обновлять - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Pages: Create ## Создать страницу `POST /v1/pages` Создаёт новую страницу на указанном сайте. Поля передаются плоско в корне JSON — без обёртки `fields`. Минимум для создания: `title` + `siteId`. Новая страница создаётся неактивной (`active: false`); активировать её можно в интерфейсе портала Битрикс24, в разделе «Сайты». ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `title` | string | да | Название страницы, до 255 символов | | `siteId` | number | да | Идентификатор сайта. Источник: [`GET /v1/sites`](/docs/entities/sites/list) | | `code` | string | нет | Символьный код страницы в URL. Не должен содержать `/`. Если оставить пустым или не передать — генерируется из `title`. Если код уже занят на сайте — добавляется числовой суффикс | | `description` | string | нет | Произвольное описание страницы | | `public` | string | нет | Публичность (`Y`/`N`) | | `sitemap` | string | нет | Включить в карту сайта (`Y`/`N`) | | `xmlId` | string | нет | Внешний код | | `folderId` | number | нет | ID папки-раздела сайта | | `tplId` | number | нет | ID шаблона | > Полный список записываемых полей — `GET /v1/pages/fields` (любое поле без `readonly`). Перечисленные выше дополнительные write-поля применяются при создании наравне с `title`/`siteId`/`code`/`description`. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/pages" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Весенняя акция", "code": "spring-sale", "siteId": 3, "description": "Лендинг сезонной акции на скидки" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/pages" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Весенняя акция", "code": "spring-sale", "siteId": 3, "description": "Лендинг сезонной акции на скидки" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Весенняя акция', code: 'spring-sale', siteId: 3, description: 'Лендинг сезонной акции на скидки', }), }) const { success, data } = await res.json() console.log('Page ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Весенняя акция', code: 'spring-sale', siteId: 3, description: 'Лендинг сезонной акции на скидки', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданной страницы. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор созданной страницы | | `title` | string | Название страницы | | `code` | string | Фактический символьный код (с авто-суффиксом, если код запроса был занят) | | `siteId` | number | Идентификатор сайта | | `active` | boolean | Всегда `false` для только что созданной страницы | | `description` | string \| null | Описание страницы | | `createdById` | number | Идентификатор создавшего сотрудника | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | URL страницы в Битрикс24 строится из `id` и `siteId`: ``` https://.bitrix24.ru/sites/site//view// ``` `` — ID сайта, которому принадлежит страница (поле `siteId` в ответе). `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 2295, "title": "Весенняя акция", "code": "spring-sale", "siteId": 3, "active": false, "description": "Лендинг сезонной акции на скидки", "createdById": 1, "dateCreate": "08.05.2026 11:49:33", "dateModify": "08.05.2026 11:49:33" } } ``` ## Пример ответа при ошибке 422 — не передано обязательное поле `title`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Не заполнено обязательное поле «Название страницы»" } } ``` ## Ошибки | HTTP | `error.code` | Маркер в `error.message` | Описание | |------|--------------|--------------------------|---------| | 422 | `BITRIX_ERROR` | `Не заполнено обязательное поле` | Пропущено `title` или `siteId` | | 422 | `BITRIX_ERROR` | `Слеш запрещен в адресе лендинга` | В `code` передан символ `/` — слеши в коде запрещены | | 422 | `BITRIX_ERROR` | `Адрес страницы не может быть пустым` | В `code` передана пустая строка без указания, что создаётся папка | | 422 | `BITRIX_ERROR` | `Недопустимый адрес страницы` | В `code` передано значение в формате `__`, например `code_12_34` | | 404 | `ENTITY_NOT_FOUND` | `Сайт не найден` | В `siteId` передан несуществующий идентификатор сайта | | 403 | `BITRIX_ACCESS_DENIED` | — | У пользователя нет права «редактирование» для указанного сайта | | 403 | `SCOPE_DENIED` | — | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | — | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список страниц](/docs/entities/pages/list) — посмотреть существующие страницы перед созданием - [Получить страницу](/docs/entities/pages/get) — данные созданной страницы по ID - [Обновить страницу](/docs/entities/pages/update) — изменить параметры созданной страницы - [Удалить страницу](/docs/entities/pages/delete) — удалить страницу - [Сайты](/docs/entities/sites) — родительские контейнеры страниц - [Batch](/docs/batch) — массовое создание - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Pages: Delete ## Удалить страницу `DELETE /v1/pages/:id` Удаляет страницу по идентификатору. Восстановить удалённую страницу через API нельзя — создавайте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор страницы | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/pages/2295" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/pages/2295" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/2295', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Страница удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/2295', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Страница удалена') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — страница не найдена или уже удалена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Лендинг не найден." } } ``` ## Ошибки | HTTP | `error.code` | Описание | |------|--------------|---------| | 404 | `ENTITY_NOT_FOUND` | Страница с таким ID не найдена или уже удалена | | 403 | `BITRIX_ACCESS_DENIED` | У пользователя нет права на удаление этой страницы | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Удаление освобождает код страницы.** После удаления символьный код снова свободен — новую страницу с тем же `code` на том же сайте можно создать сразу. ## Смотрите также - [Список страниц](/docs/entities/pages/list) — найти ID нужной страницы перед удалением, в том числе через `?filter[siteId]=:id` - [Получить страницу](/docs/entities/pages/get) — проверить страницу перед удалением - [Удалить сайт](/docs/entities/sites/delete) — удаление сайта после очистки страниц - [Batch](/docs/batch) — массовое удаление страниц одного сайта - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Pages: Get ## Получить страницу `GET /v1/pages/:id` Возвращает одну страницу по идентификатору. Удалённые страницы этим эндпоинтом не возвращаются — на запрос вернётся `404 ENTITY_NOT_FOUND`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор страницы | | `scope` (query) | string | нет | Внутренняя область лендингов: `KNOWLEDGE` / `GROUP` / `MAINPAGE`. Указывайте, если страница принадлежит соответствующей области; иначе возвращается `404 ENTITY_NOT_FOUND`. Пример: `GET /v1/pages/9?scope=KNOWLEDGE` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/pages/9" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/pages/9" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/9', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Страница:', data.title, '— сайт:', data.siteId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/9', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор страницы | | `title` | string | Название страницы | | `code` | string | Символьный код страницы | | `siteId` | number | Идентификатор сайта | | `active` | boolean | Активна ли страница | | `description` | string \| null | Произвольное описание | | `createdById` | number | Идентификатор создавшего сотрудника | | `dateCreate` | datetime | Дата создания. Формат Битрикс24 `ДД.ММ.ГГГГ ЧЧ:ММ:СС` (не ISO 8601) | | `dateModify` | datetime | Дата последнего изменения. Формат Битрикс24 `ДД.ММ.ГГГГ ЧЧ:ММ:СС` (не ISO 8601) | > **Формат дат — локаль-зависимый, НЕ ISO 8601.** `landing.landing.*` возвращает `dateCreate`/`dateModify` строкой в локальном формате Битрикс24, и **конкретный шаблон зависит от региональных настроек портала**: на RU-локали это `ДД.ММ.ГГГГ ЧЧ:ММ:СС` (`30.12.2021 12:30:52`), на EN-локали — `MM/DD/YYYY hh:mm:ss am/pm` (`04/22/2020 02:39:17 pm`). Вайбкод отдаёт значение Битрикс24 как есть (без нормализации в ISO). `new Date(value)` вернёт `Invalid Date` либо тихо перепутает день/месяц — **не парсьте фиксированным шаблоном и не доверяйте `new Date()`**; ориентируйтесь на региональные настройки конкретного портала. ## Пример ответа ```json { "success": true, "data": { "id": 9, "title": "Тест переноса страниц", "code": "change1", "siteId": 3, "active": true, "description": null, "createdById": 1, "dateCreate": "30.12.2021 12:30:52", "dateModify": "30.12.2021 12:30:53" } } ``` ## Пример ответа при ошибке 404 — страница не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "landingPage 999999999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Страница с таким ID не найдена, удалена или недоступна пользователю | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Параметр `select` не применяется.** В отличие от [списка страниц](./list.md), `GET /v1/pages/:id` всегда возвращает все доступные поля. Чтобы получить только ключевые поля в camelCase, используйте список с фильтром по ID: `GET /v1/pages?filter[id]=:id&select=id,title,code,siteId,active,description,createdById,dateCreate,dateModify`. ## Смотрите также - [Список страниц](/docs/entities/pages/list) — получить несколько страниц с фильтрами - [Обновить страницу](/docs/entities/pages/update) — изменение полей - [Удалить страницу](/docs/entities/pages/delete) — удаление по ID - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Pages: List ## Список страниц `GET /v1/pages` Возвращает список страниц лендингов и интернет-магазинов с поддержкой фильтрации и автопагинации. По умолчанию возвращаются только не удалённые страницы. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод запрашивает несколько страниц у Битрикс24 и собирает результат | | `select` | string | — | Выборка полей: `?select=id,title,code,siteId,active`. Без `select` ответ содержит полный набор полей страницы в camelCase (как в карточке) | | `filter` | object | — | Фильтрация по ключевым полям страницы.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[siteId]=3`. Булево `active` принимается как `true`/`false`, `1`/`0` или `Y`/`N` | | `scope` | string | — | Внутренняя область лендингов. Допустимые значения: `KNOWLEDGE` (страницы базы знаний), `GROUP` (страницы рабочих групп), `MAINPAGE` (главные страницы). Без параметра возвращаются страницы обычных сайтов-лендингов. Принимается как `?scope=KNOWLEDGE` или `?filter[scope]=KNOWLEDGE` — обе формы дают одинаковый запрос к Битрикс24 | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/pages?filter[siteId]=3&limit=10&select=id,title,code,siteId,active,dateCreate,dateModify" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/pages?filter[siteId]=3&limit=10&select=id,title,code,siteId,active,dateCreate,dateModify" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const params = new URLSearchParams({ 'filter[siteId]': '3', limit: '10', select: 'id,title,code,siteId,active,dateCreate,dateModify', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/pages?${params}`, { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} страниц`) ``` ### JavaScript — OAuth-приложение ```javascript const params = new URLSearchParams({ 'filter[siteId]': '3', limit: '10', select: 'id,title,code,siteId,active,dateCreate,dateModify', }) const res = await fetch(`https://vibecode.bitrix24.tech/v1/pages?${params}`, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив страниц | | `data[].id` | number | Идентификатор страницы | | `data[].title` | string | Название страницы | | `data[].code` | string | Символьный код страницы | | `data[].siteId` | number | Идентификатор сайта | | `data[].active` | boolean | Активна ли страница | | `data[].description` | string \| null | Произвольное описание | | `data[].createdById` | number | Идентификатор создавшего сотрудника | | `data[].dateCreate` | datetime | Дата создания | | `data[].dateModify` | datetime | Дата последнего изменения | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | URL любой страницы из массива `data` строится из её `id` и `siteId`: ``` https://.bitrix24.ru/sites/site//view// ``` `` — ID сайта, которому принадлежит страница (поле `siteId` каждого элемента). `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 9, "title": "Тест переноса страниц", "code": "change1", "siteId": 3, "active": true, "description": null, "createdById": 1, "dateCreate": "26.05.2020 17:24:02", "dateModify": "10.10.2022 15:25:30" }, { "id": 7, "title": "Test page", "code": "test", "siteId": 3, "active": true, "description": null, "createdById": 1, "dateCreate": "25.05.2020 17:34:17", "dateModify": "10.10.2022 15:25:30" } ], "meta": { "total": 13, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'landing' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Передан параметр, не поддерживаемый Битрикс24. `offset` приводит к `422 Unknown parameter: start` (Битрикс24 называет смещение `start`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Постраничный переход через `offset` не работает.** Метод получения списка не принимает параметр смещения. Передача `offset` приводит к ошибке `BITRIX_ERROR: Unknown parameter: start`. Для больших выборок используйте `limit > 50` — Вайбкод сам запрашивает у Битрикс24 несколько страниц и собирает результат в одном ответе. **Сортировка не применяется.** Параметр `order` принимается без ошибки, но порядок результата не меняется — выборка всегда возвращается в порядке возрастания идентификатора. **База знаний и другие внутренние области.** Параметр `scope` переключает источник: `KNOWLEDGE` — страницы базы знаний, `GROUP` — страницы рабочих групп, `MAINPAGE` — главные страницы. Без параметра возвращаются страницы обычных сайтов-лендингов (источник по умолчанию). Пример: `GET /v1/pages?scope=KNOWLEDGE` возвращает страницы базы знаний. ## Смотрите также - [Получить страницу](/docs/entities/pages/get) — данные одной страницы по ID - [Поиск страниц](/docs/entities/pages/search) — POST-аналог для сложных фильтров - [Создать страницу](/docs/entities/pages/create) — создание новой страницы - [Обновить страницу](/docs/entities/pages/update) — изменение полей - [Удалить страницу](/docs/entities/pages/delete) — удаление по ID - [Сайты](/docs/entities/sites) — родительские контейнеры страниц - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Pages: Search ## Поиск страниц `POST /v1/pages/search` Возвращает список страниц по фильтру в теле запроса. По сравнению с [`GET /v1/pages`](./list.md) удобнее для сложных условий: параметры передаются в JSON, можно использовать вложенные операторы (`>=`, `<=`, `!`, `in`) в стиле MongoDB. ## Поля запроса (body) | Поле | Тип | По умолч. | Описание | |------|-----|-----------|---------| | `filter` | object | — | Фильтр по ключевым полям страницы.
[Синтаксис фильтрации](/docs/filtering). Пример: `{"filter": {"siteId": 3}}` | | `select` | string[] | — | Список полей для возврата. Без `select` ответ содержит полный набор полей страницы в camelCase (как в карточке) | | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод запрашивает несколько страниц у Битрикс24 и собирает результат | | `scope` | string | — | Внутренняя область лендингов: `KNOWLEDGE` / `GROUP` / `MAINPAGE`. Без параметра возвращаются страницы обычных сайтов-лендингов. Принимается на верхнем уровне тела (`"scope": "KNOWLEDGE"`) или внутри `filter.scope` — обе формы дают одинаковый запрос к Битрикс24 | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/pages/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "siteId": 3 }, "select": ["id", "title", "code", "siteId", "active", "dateModify"], "limit": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/pages/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "siteId": 3 }, "select": ["id", "title", "code", "siteId", "active", "dateModify"], "limit": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { siteId: 3 }, select: ['id', 'title', 'code', 'siteId', 'active', 'dateModify'], limit: 10, }), }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} страниц за ${meta.durationMs} мс`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { siteId: 3 }, select: ['id', 'title', 'code', 'siteId', 'active', 'dateModify'], limit: 10, }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив найденных страниц | | `data[].id` | number | Идентификатор страницы | | `data[].title` | string | Название страницы | | `data[].code` | string | Символьный код страницы | | `data[].siteId` | number | Идентификатор сайта | | `data[].active` | boolean | Активна ли страница | | `data[].description` | string \| null | Произвольное описание | | `data[].createdById` | number | Идентификатор создавшего сотрудника | | `data[].dateCreate` | datetime | Дата создания | | `data[].dateModify` | datetime | Дата последнего изменения | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | | `meta.durationMs` | number | Время выполнения запроса (мс) | URL любой страницы из массива `data` строится из её `id` и `siteId`: ``` https://.bitrix24.ru/sites/site//view// ``` `` — ID сайта, которому принадлежит страница (поле `siteId` каждого элемента). `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 3, "title": "Смена названия", "code": "fotografiya", "siteId": 3, "active": true, "description": null, "createdById": 1, "dateCreate": "22.04.2020 14:39:17", "dateModify": "06.05.2024 15:43:27" }, { "id": 7, "title": "Test page", "code": "test", "siteId": 3, "active": true, "description": null, "createdById": 1, "dateCreate": "25.05.2020 17:34:17", "dateModify": "10.10.2022 15:25:30" } ], "meta": { "total": 13, "hasMore": true, "durationMs": 171 } } ``` ## Пример ответа при ошибке 422 — несуществующее поле в фильтре: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Unknown field definition `nonsense` (nonsense) for \\Bitrix\\Landing\\Internals\\Landing Entity." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Передан неизвестный филд в `filter` или неподдерживаемый параметр (например, `offset`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Когда выбирать `search`, а когда `list`.** Оба эндпоинта возвращают одинаковый набор страниц по фильтру. Используйте `POST /v1/pages/search`, когда фильтр сложнее равенства (например, `id in [3, 7, 9]`) — JSON-тело удобнее экранирует вложенные операторы. Для простых `filter[field]=value` достаточно `GET /v1/pages`. **Формат дат в фильтре.** `landing.landing.getList` принимает даты только в формате Битрикс24 `ДД.ММ.ГГГГ ЧЧ:ММ:СС`, **не** ISO 8601. `{">=dateModify": "06.06.2026 00:00:00"}` работает; ISO-значение `{">=dateModify": "2026-06-06"}` принимается без ошибки, но даёт неверный результат (Битрикс24 его не парсит). Тот же формат `ДД.ММ.ГГГГ ЧЧ:ММ:СС` возвращается и в ответе (см. поля `dateCreate`/`dateModify`). **`meta.durationMs`.** В отличие от list, search всегда возвращает длительность запроса в миллисекундах — полезно при отладке производительности. ## Смотрите также - [Список страниц](/docs/entities/pages/list) — `GET`-аналог для простых фильтров - [Получить страницу](/docs/entities/pages/get) — данные одной страницы по ID - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) --- # Pages: Update ## Обновить страницу `PATCH /v1/pages/:id` Обновляет поля существующей страницы. Передавайте только изменяемые поля плоско в корне JSON — без обёртки `fields`. Не переданные поля сохраняют текущие значения. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор страницы | ## Поля для обновления (body) | Поле | Тип | Описание | |------|-----|---------| | `title` | string | Название страницы, до 255 символов | | `code` | string | Символьный код страницы. Не должен содержать `/`. Если код уже занят на сайте — добавляется числовой суффикс | | `description` | string | Произвольное описание | | `siteId` | number | Перенести страницу на другой сайт. Список сайтов: [`GET /v1/sites`](/docs/entities/sites/list) | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/pages/2295" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Весенняя акция — обновлено", "description": "Скидки до 50%" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/pages/2295" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Весенняя акция — обновлено", "description": "Скидки до 50%" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/2295', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Весенняя акция — обновлено', description: 'Скидки до 50%', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/pages/2295', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Весенняя акция — обновлено', description: 'Скидки до 50%', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект обновлённой страницы. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор страницы | | `title` | string | Название страницы | | `code` | string | Символьный код страницы | | `siteId` | number | Идентификатор сайта | | `active` | boolean | Активна ли страница | | `description` | string \| null | Описание страницы | | `createdById` | number | Идентификатор создавшего сотрудника | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения (после обновления) | ## Пример ответа ```json { "success": true, "data": { "id": 2295, "title": "Весенняя акция — обновлено", "code": "spring-sale", "siteId": 3, "active": false, "description": "Скидки до 50%", "createdById": 1, "dateCreate": "08.05.2026 11:49:33", "dateModify": "08.05.2026 12:14:08" } } ``` ## Пример ответа при ошибке 422 — слеш в `code`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Слеш запрещен в адресе лендинга." } } ``` ## Ошибки | HTTP | `error.code` | Маркер в `error.message` | Описание | |------|--------------|--------------------------|---------| | 401 | `TOKEN_MISSING` | — | API-ключ не имеет настроенных токенов | | 403 | `BITRIX_ACCESS_DENIED` | — | У пользователя нет права на изменение этой страницы | | 403 | `SCOPE_DENIED` | — | API-ключ не имеет скоупа `landing` | | 404 | `ENTITY_NOT_FOUND` | — | Страница с таким `id` не найдена или удалена | | 422 | `BITRIX_ERROR` | `Слеш запрещен в адресе лендинга` | В `code` передан символ `/` | | 422 | `BITRIX_ERROR` | `Адрес страницы не может быть пустым` | В `code` передана пустая строка | | 422 | `BITRIX_ERROR` | `Недопустимый адрес страницы` | В `code` передано значение в формате `__` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить страницу](/docs/entities/pages/get) — текущие значения полей - [Список страниц](/docs/entities/pages/list) — найти страницу по фильтру - [Создать страницу](/docs/entities/pages/create) — создание новой - [Удалить страницу](/docs/entities/pages/delete) — удаление по ID - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Payments: Aggregate ## Агрегация оплат `POST /v1/payments/aggregate` Подсчёт количества оплат и числовые агрегации (`sum`, `avg`, `min`, `max`) по полю `sum`. Поддерживает фильтрацию и группировку по `paySystemId`, `orderId`, `currency`, `paid`, `responsibleId`. ## Стандартные поля | Поле | Назначение | |------|------------| | `sum` | Единственное числовое поле — подходит для `sum` / `avg` / `min` / `max` (название поля и функции совпадают, но это разные сущности) | | `paySystemId`, `orderId`, `responsibleId` | Идентификаторы — используются в `groupBy` (по платёжной системе, заказу, ответственному) | | `currency` | Категориальное — используется в `groupBy` (по валюте) | | `paid` | Логическое — используется в `groupBy` (оплачено / не оплачено) | Полный список агрегируемых полей перечислен в таблице выше. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций: `[{ "field": "sum", "function": "sum" }]`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без параметра — только `count` (один запрос в Битрикс24, записи не выгружаются) | | `filter` | object | нет | Фильтрация — те же поля, что в [`GET /v1/payments`](./list.md). [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5) | | `groupOrderBy` | array | нет | Сортировка групп: `[{ "field": "sum:sum", "direction": "desc" }]` | | `groupLimit` | number | нет | Ограничение количества возвращаемых групп (1-1000) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/payments/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [{ "field": "sum", "function": "sum" }], "groupBy": "paySystemId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/payments/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [{ "field": "sum", "function": "sum" }], "groupBy": "paySystemId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'sum', function: 'sum' }], groupBy: 'paySystemId', }), }) const { success, data } = await res.json() console.log(data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'sum', function: 'sum' }], groupBy: 'paySystemId', }), }) const { success, data } = await res.json() ``` ## Другие сценарии Общее количество оплат без выгрузки записей: ```json {} ``` Сумма всех принятых оплат: ```json { "aggregate": [{ "field": "sum", "function": "sum" }], "filter": { "paid": true } } ``` Топ-3 платёжных систем по сумме с сортировкой: ```json { "aggregate": [{ "field": "sum", "function": "sum" }], "groupBy": "paySystemId", "groupOrderBy": [{ "field": "sum:sum", "direction": "desc" }], "groupLimit": 3 } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество оплат, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций: `{ "sum": { "sum": ..., "avg": ... } }` | | `data.groups` | array | Группы (только при `groupBy`) | | `data.meta.totalRecords` | number | Общее количество записей | | `data.meta.recordsProcessed` | number | Количество обработанных записей (до 5000) | | `data.meta.truncated` | boolean | `true`, если записей больше 5000 | | `data.meta.groupTotal` | number | Количество групп до `groupLimit` | | `data.meta.groupsTruncated` | boolean | Был ли список групп обрезан `groupLimit` | ## Пример ответа ```json { "success": true, "data": { "count": 99, "aggregates": { "sum": { "sum": 8475.87 } }, "groups": [ { "paySystemId": 11, "count": 87, "aggregates": { "sum": { "sum": 5870.5 } } }, { "paySystemId": 6, "count": 8, "aggregates": { "sum": { "sum": 2025.37 } } }, { "paySystemId": 25, "count": 4, "aggregates": { "sum": { "sum": 580 } } } ], "meta": { "totalRecords": 99, "recordsProcessed": 99, "truncated": false, "groupTotal": 3, "groupsTruncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неизвестное поле в `groupBy`: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Unknown field 'foo'. Available: sum, currency, paid, paySystemId, orderId, responsibleId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Неизвестная функция или несуществующее поле — сообщение содержит список допустимых полей | | 400 | `INVALID_PARAMS` | Передано больше 5 полей в `groupBy` | | 400 | `INVALID_PARAMS` | Зарезервированные ключевые слова в `groupBy`: `count`, `aggregates`, `meta`, `groups` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` против числовых функций.** `count` считается одним запросом в Битрикс24 — записи не выгружаются, ответ возвращается быстро на любом объёме. `sum` / `avg` / `min` / `max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод. При более чем 5000 записях `meta.truncated` будет `true`. **Группировка по `currency` важна на мультивалютных порталах.** Сумма всех оплат в `data.aggregates.sum.sum` без `groupBy: "currency"` смешивает разные валюты — реальный смысл получается только при разделении. ## Смотрите также - [Список оплат](./list.md) — `meta.total` даёт точное число записей - [Поиск оплат](./search.md) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Payments: Create ## Создать оплату `POST /v1/payments` Регистрирует новую оплату для существующего заказа. Тело запроса плоское — без обёртки `fields`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `orderId` | number | да | Идентификатор заказа. Источник: [`GET /v1/orders`](../orders/list.md) | | `paySystemId` | number | да | Идентификатор платёжной системы. На каждом портале свой набор систем. REST API не выставляет эндпоинт для перечисления; ID можно увидеть в существующих оплатах через [`GET /v1/payments`](./list.md) или [`POST /v1/payments/aggregate`](./aggregate.md) с `groupBy: "paySystemId"` | | `sum` | number | нет | Сумма оплаты. Если не передать — Битрикс24 берёт остаток от суммы заказа | | `currency` | string | нет | Валюта оплаты. По умолчанию — валюта заказа. Список: [`GET /v1/currencies`](/docs/entities/currencies) | | `paid` | boolean | нет | Помечена ли оплата как поступившая. По умолчанию `false` | | `datePaid` | datetime | нет | Дата отметки оплаты (в формате ISO 8601) | | `dateBill` | datetime | нет | Дата выставления счёта | | `datePayBefore` | datetime | нет | Срок оплаты | | `responsibleId` | number | нет | Ответственный сотрудник. Источник: [`GET /v1/users`](/docs/entities/users) | | `comments` | string | нет | Комментарий к оплате | | `xmlId` | string | нет | Внешний идентификатор (например, ID транзакции платёжного шлюза) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/payments" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "orderId": 19, "paySystemId": 11, "sum": 1500, "currency": "RUB", "paid": true, "comments": "Оплата через платёжный шлюз", "xmlId": "txn_abc123" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/payments" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "orderId": 19, "paySystemId": 11, "sum": 1500, "currency": "RUB", "paid": true, "comments": "Оплата через платёжный шлюз", "xmlId": "txn_abc123" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ orderId: 19, paySystemId: 11, sum: 1500, currency: 'RUB', paid: true, comments: 'Оплата через платёжный шлюз', xmlId: 'txn_abc123', }), }) const { success, data } = await res.json() console.log('Payment ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ orderId: 19, paySystemId: 11, sum: 1500, currency: 'RUB', paid: true, comments: 'Оплата через платёжный шлюз', xmlId: 'txn_abc123', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданной оплаты. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор созданной оплаты | | `accountNumber` | string | Порядковый номер оплаты на портале (генерируется автоматически) | | `paySystemName` | string | Название платёжной системы (берётся из карточки `paySystemId`) | Остальные поля совпадают с переданными в запросе + `datePaid` / `dateBill` могут быть проставлены автоматически. ## Пример ответа ```json { "success": true, "data": { "id": 217, "accountNumber": "98/2", "orderId": 19, "paySystemId": 11, "paySystemName": "Наличные", "sum": 1500, "currency": "RUB", "paid": true, "datePaid": "2026-05-13T11:50:24.000Z", "dateBill": "2026-05-13T11:50:24.000Z", "responsibleId": 1, "comments": "Оплата через платёжный шлюз", "xmlId": "txn_abc123", "isReturn": "N", "marked": false } } ``` ## Пример ответа при ошибке 400 — не передан обязательный `orderId`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Required fields: orderId" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `BITRIX_ERROR` | Не переданы обязательные поля — сообщение содержит их список (`Required fields: orderId` или `paySystemId`) | | 400 | `BITRIX_ERROR` | Несуществующий `orderId` или `paySystemId` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Номер оплаты генерируется автоматически.** Поле `accountNumber` присваивается Битрикс24 при создании в формате `/` (например, `19/1`) и не может быть передано в запросе. **Несколько оплат на один заказ.** У одного заказа может быть несколько оплат — например, частичная предоплата и доплата при доставке. Каждая регистрируется отдельным `POST /v1/payments` с тем же `orderId` и разными `paySystemId` или `sum`. **Статус заказа не обновляется автоматически.** После регистрации оплаты статус заказа (`orders.payed`, `orders.statusId`) остаётся прежним — обновите его отдельным вызовом [`PATCH /v1/orders/:id`](../orders/update.md). ## Смотрите также - [Список оплат](./list.md) — посмотреть существующие оплаты заказа - [Получить оплату](./get.md) — полные данные после создания - [Обновить оплату](./update.md) — изменить статус или сумму - [Обновить заказ](../orders/update.md) — обновить `payed` и `statusId` заказа после оплаты - [Batch](/docs/batch) — массовое создание - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Payments: Delete ## Удалить оплату `DELETE /v1/payments/:id` Удаляет оплату по идентификатору. Восстановить удалённую оплату через API нельзя — создавайте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор оплаты | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/payments/217" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/payments/217" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/217', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Оплата удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/217', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Оплата удалена') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — оплата не найдена: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "payment is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Оплата с таким ID не найдена или уже удалена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Заказ не удаляется.** Удаление оплаты не затрагивает родительский заказ — заказ остаётся, поле `sumPaid` пересчитывается автоматически. **Альтернатива — пометка возврата.** Чтобы сохранить запись о платеже, используйте [`PATCH /v1/payments/:id`](./update.md) с `{"isReturn": "Y", "comments": "..."}` — оплата останется в выборках с `filter[isReturn]=Y`. ## Смотрите также - [Обновить оплату](./update.md) — пометить возврат вместо удаления (`isReturn: "Y"`) - [Список оплат](./list.md) — найти ID оплаты перед удалением - [Получить оплату](./get.md) — проверить состояние перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Payments: Get ## Получить оплату `GET /v1/payments/:id` Возвращает одну оплату по идентификатору со всеми полями. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор оплаты | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/payments/17" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/payments/17" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/17', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Оплата:', data.sum, data.currency, '—', data.paySystemName) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/17', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор оплаты | | `accountNumber` | string | Порядковый номер оплаты на портале | | `orderId` | number | Идентификатор заказа | | `paySystemId` | number | Идентификатор платёжной системы | | `paySystemName` | string | Название платёжной системы | | `sum` | number | Сумма оплаты | | `currency` | string | Валюта оплаты | | `paid` | boolean | Помечена ли оплата как поступившая | | `datePaid` | datetime | Дата отметки оплаты | | `dateBill` | datetime | Дата выставления счёта | | `datePayBefore` | datetime | Срок оплаты | | `responsibleId` | number | Ответственный сотрудник | | `comments` | string | Комментарий к оплате | | `xmlId` | string | Внешний идентификатор | | `isReturn` | string | Признак возврата: `"N"`, `"Y"`, `"P"` | | `marked` | boolean | Помечена ли оплата как проблемная | | `priceCod` | number | Стоимость наложенного платежа | | `companyId` | number | Идентификатор компании-получателя | | `psStatus` | string | Статус от платёжной системы | | `payVoucherNum` | string | Номер платёжного документа | | `payVoucherDate` | datetime | Дата платёжного документа | ## Пример ответа ```json { "success": true, "data": { "id": 17, "accountNumber": "19/1", "orderId": 19, "paySystemId": 11, "paySystemName": "Наличные", "paySystemIsCash": "Y", "paySystemXmlId": "bx_61372545d32ae", "sum": 0, "currency": "RUB", "paid": false, "datePaid": "2020-05-14T20:00:00.000Z", "dateBill": "2020-05-14T20:00:00.000Z", "datePayBefore": null, "dateMarked": null, "dateResponsibleId": "2020-05-15T15:08:16+03:00", "responsibleId": 1, "empPaidId": null, "empResponsibleId": 1, "empMarkedId": null, "empReturnId": null, "comments": "", "reasonMarked": null, "xmlId": "bx_5ebe943aacfa0", "id1c": null, "version1c": null, "updated1c": false, "externalPayment": false, "isReturn": "N", "marked": false, "priceCod": 0, "companyId": null, "payReturnNum": null, "payReturnDate": null, "payReturnComment": null, "payVoucherNum": null, "payVoucherDate": null, "psStatus": null, "psStatusCode": null, "psStatusDescription": null, "psStatusMessage": null, "psSum": null, "psCurrency": null, "psInvoiceId": null, "psResponseDate": null } } ``` ## Пример ответа при ошибке 422 — оплата не найдена: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "payment is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Оплата с таким ID не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить оплату](./update.md) — изменение полей - [Удалить оплату](./delete.md) — удаление по ID - [Список оплат](./list.md) — поиск с фильтрами - [Заказ](../orders/get.md) — родительская сущность по `orderId` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Payments: List ## Список оплат `GET /v1/payments` Возвращает список оплат заказов с поддержкой фильтрации и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `offset` | number | `0` | Пропустить N записей. При `offset ≥ 2500` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,orderId,sum,paid` | | `order` | object | — | Сортировка: `?order[id]=desc` | | `filter` | object | — | Фильтрация по ключевым полям оплаты.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[orderId]=19` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/payments?limit=10&filter[paid]=true&order[id]=desc" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/payments?limit=10&filter[paid]=true&order[id]=desc" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments?limit=10&filter[paid]=true&order[id]=desc', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} оплат`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments?limit=10&filter[paid]=true&order[id]=desc', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив оплат (каждая содержит все поля оплаты) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 17, "accountNumber": "19/1", "orderId": 19, "paySystemId": 11, "paySystemName": "Наличные", "sum": 0, "currency": "RUB", "paid": false, "datePaid": "2020-05-14T20:00:00.000Z", "dateBill": "2020-05-14T20:00:00.000Z", "responsibleId": 1, "isReturn": "N", "comments": "", "xmlId": "bx_5ebe943aacfa0" }, { "id": 19, "accountNumber": "21/1", "orderId": 21, "paySystemId": 11, "paySystemName": "Наличные", "sum": 0, "currency": "RUB", "paid": false, "datePaid": "2020-05-17T20:00:00.000Z", "dateBill": "2020-05-17T20:00:00.000Z", "responsibleId": 1, "isReturn": "N", "comments": "", "xmlId": "bx_5ec2368b6e74d" } ], "meta": { "total": 99, "hasMore": true } } ``` Показаны основные поля. Полный ответ оплаты — см. [`GET /v1/payments/:id`](./get.md). ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'sale' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме оплаты | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 и возвращает все записи в одном ответе. **Когда использовать `search` вместо `list`:** для сложных фильтров с множеством условий удобнее [`POST /v1/payments/search`](./search.md) — параметры передаются в body. **Поле `isReturn` — строка с тремя значениями.** Принимает `"N"` (обычная оплата), `"Y"` (возврат) и `"P"` (частичный возврат) — фильтр по нему работает по этим строковым значениям. ## Смотрите также - [Поиск оплат](./search.md) — POST-запрос для сложных фильтров - [Получить оплату](./get.md) — одна оплата по ID - [Создать оплату](./create.md) — регистрация платежа - [Заказ](../orders/get.md) — родительская сущность (`filter[orderId]=:id`) - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Payments: Search ## Поиск оплат `POST /v1/payments/search` Поиск оплат с фильтрацией и авто-пагинацией. Аналогичен [`GET /v1/payments`](./list.md), но через POST — удобнее для сложных запросов с большим количеством условий. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям оплаты.
[Синтаксис фильтрации](/docs/filtering) | | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string[] | — | Выборка полей: `["id", "orderId", "sum", "paid"]` | | `order` | object | — | Сортировка: `{ "id": "desc" }` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/payments/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "orderId": 19, "paid": true }, "limit": 10, "select": ["id", "orderId", "sum", "currency", "paid", "datePaid"] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/payments/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "orderId": 19, "paid": true }, "limit": 10, "select": ["id", "orderId", "sum", "currency", "paid", "datePaid"] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { orderId: 19, paid: true }, limit: 10, select: ['id', 'orderId', 'sum', 'currency', 'paid', 'datePaid'], }), }) const { success, data, meta } = await res.json() console.log('Найдено:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { orderId: 19, paid: true }, limit: 10, select: ['id', 'orderId', 'sum', 'currency', 'paid', 'datePaid'], }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив оплат | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 17, "orderId": 19, "sum": 0, "currency": "RUB", "paid": false, "datePaid": "2020-05-14T20:00:00.000Z" } ], "meta": { "total": 1, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — фильтр по несуществующему полю: ```json { "success": false, "error": { "code": "UNKNOWN_FILTER_FIELD", "message": "Unknown field 'foo'. Available: id, orderId, paySystemId, sum, currency, paid, ..." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `UNKNOWN_FILTER_FIELD` | Фильтр по полю, которого нет в схеме оплаты | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`select` ограничивает поля в ответе.** Если передан `select`, в каждом элементе `data[]` будут только перечисленные поля. Без `select` возвращаются все поля оплаты. **Поле `isReturn` — строка.** Принимает `"N"`, `"Y"` и `"P"` — фильтр и обновление работают по этим значениям. ## Смотрите также - [Список оплат](./list.md) — GET-запрос с query-параметрами (для простых фильтров) - [Получить оплату](./get.md) — данные одной оплаты по ID - [Заказ](../orders/get.md) — родительская сущность (фильтр `orderId`) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Payments: Update ## Обновить оплату `PATCH /v1/payments/:id` Обновляет поля существующей оплаты. Передавайте только изменяемые поля плоско в корне JSON — без обёртки `fields`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор оплаты | ## Поля для обновления (body) | Параметр | Тип | Описание | |----------|-----|---------| | `sum` | number | Новая сумма оплаты | | `currency` | string | Валюта оплаты | | `paid` | boolean | Помечена ли оплата как поступившая | | `datePaid` | datetime | Дата отметки оплаты | | `dateBill` | datetime | Дата выставления счёта | | `comments` | string | Комментарий к оплате | | `xmlId` | string | Внешний идентификатор | | `responsibleId` | number | Ответственный сотрудник | | `marked` | boolean | Помечена ли оплата как проблемная | | `reasonMarked` | string | Причина пометки | | `isReturn` | string | Признак возврата: `"N"`, `"Y"`, `"P"` | Редактируются все поля оплаты, кроме служебных (`id`, `accountNumber`, `paySystemName`, `empPaidId`, `empResponsibleId`, `empMarkedId`, `empReturnId`). Полный набор доступных полей виден в ответе [`GET /v1/payments/:id`](./get.md). ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/payments/17" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "paid": true, "datePaid": "2026-05-13T12:00:00", "comments": "Подтверждено банком" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/payments/17" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "paid": true, "datePaid": "2026-05-13T12:00:00", "comments": "Подтверждено банком" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/17', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ paid: true, datePaid: '2026-05-13T12:00:00', comments: 'Подтверждено банком', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/payments/17', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ paid: true, datePaid: '2026-05-13T12:00:00', comments: 'Подтверждено банком', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект оплаты со всеми полями | ## Пример ответа ```json { "success": true, "data": { "id": 17, "accountNumber": "19/1", "orderId": 19, "paySystemId": 11, "paySystemName": "Наличные", "sum": 0, "currency": "RUB", "paid": true, "datePaid": "2026-05-13T09:00:00.000Z", "dateBill": "2020-05-14T20:00:00.000Z", "responsibleId": 1, "comments": "Подтверждено банком", "xmlId": "bx_5ebe943aacfa0", "isReturn": "N", "marked": false } } ``` ## Пример ответа при ошибке 422 — оплата не найдена: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "payment is not exists" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Оплата с таким ID не найдена | | 400 | `BITRIX_ERROR` | Некорректное значение поля — например, неизвестный `paySystemId` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sale` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поле `paySystemId` подтягивается автоматически.** Вайбкод перед обновлением оплаты получает текущее значение `paySystemId` через `GET /v1/payments/:id` и автоматически добавляет его в запрос, если оно не передано. Это даёт привычную семантику `PATCH` с одним полем — без необходимости каждый раз указывать платёжную систему. **Поля `accountNumber`, `orderId`, `paySystemName` доступны только для чтения.** Их значения проставляются Битрикс24 (`accountNumber` — при создании, `paySystemName` — из карточки `paySystemId`); попытка изменить — игнорируется. ## Смотрите также - [Получить оплату](./get.md) — текущие значения полей перед обновлением - [Список оплат](./list.md) — найти оплату по фильтру - [Удалить оплату](./delete.md) — необратимое удаление - [Обновить заказ](../orders/update.md) — обновить `payed` и `statusId` заказа после оплаты - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Products: Aggregate ## Агрегация продуктов CRM `POST /v1/products/aggregate` Агрегация данных: подсчёт количества, сумма, среднее, минимум, максимум. Поддерживает фильтрацию и группировку по любому полю из списка `aggregatable`. **Поля, доступные для агрегации:** - `price` - `sectionId` - `catalogId` - `active` ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `filter` | object | нет | Фильтрация — те же поля, что в `GET /v1/products`. [Синтаксис фильтрации](/docs/filtering) | | `aggregate` | array | нет | Агрегации: `[{ "field": "price", "function": "sum" }]`. Функции: `sum`, `avg`, `min`, `max`, `count`. Без параметра — только count | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (max 5). Допустимые значения из списка выше | ## Примеры ### curl — без группировки ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/products/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "price", "function": "sum" }, { "field": "price", "function": "avg" } ] }' ``` ### curl — с группировкой по одному полю ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/products/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [{ "field": "price", "function": "sum" }], "groupBy": "active" }' ``` ### JavaScript ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/products/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'price', function: 'sum' }], groupBy: 'active', }), }) const { success, data } = await res.json() // data.groups — массив групп по active console.log(data.groups) ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `count` | number | Общее количество записей, соответствующих фильтру | | `aggregates` | object | Результаты агрегаций: `{ "price": { "sum": 0 } }` | | `groups` | array | Группы (присутствует только при использовании `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `meta.totalRecords` | number | Общее количество записей | | `meta.recordsProcessed` | number | Количество обработанных записей (max 5000) | | `meta.truncated` | boolean | `true`, если записей больше 5000 — агрегация по выборке | ## Пример ответа — без группировки ```json { "success": true, "data": { "count": 41, "aggregates": { "price": { "sum": 100000, "avg": 2439 } }, "meta": { "totalRecords": 41, "recordsProcessed": 41, "truncated": false } } } ``` ## Пример ответа — с группировкой (`groupBy: "active"`) ```json { "success": true, "data": { "count": 41, "aggregates": { "price": { "sum": 100000, "avg": 2439 } }, "groups": [ { "active": "Y", "count": 25, "aggregates": { "price": { "sum": 60000 } } }, { "active": "N", "count": 16, "aggregates": { "price": { "sum": 40000 } } } ], "meta": { "totalRecords": 41, "recordsProcessed": 41, "truncated": false } } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Неизвестное поле агрегации или недопустимая функция | | 400 | `INVALID_PARAMS` | Передано более 5 полей в `groupBy` (максимум 5) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Без `aggregate` — только count.** Если не передать массив `aggregate`, метод вернёт только `count` записей с учётом фильтра. **`groupBy` принимает строку или массив.** Для группировки по одному полю передайте строку: `"groupBy": "active"`. Для нескольких — массив: `"groupBy": ["active", "price"]`. Максимум 5 полей. **Плоская структура групп.** Поля группировки выводятся как прямые ключи в каждом элементе `groups`, не вложены: `{ "active": "...", "count": N, "aggregates": {...} }`. **Ограничение 5000 записей.** Если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true` — агрегация и подсчёт групп выполняются по первым 5000 записям выборки. ## Смотрите также - [Список продуктов](/docs/entities/products/list) — получить записи с фильтрацией - [Поиск продуктов](/docs/entities/products/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Aggregate ## Агрегация предложений `POST /v1/quotes/aggregate` Подсчёт количества, сумма, среднее, минимум и максимум по коммерческим предложениям с фильтрацией и группировкой. **Стандартные поля:** - `amount` — сумма предложения (числовое агрегирование имеет смысл) - `stageId` — стадия (для `groupBy`) - `assignedById` — ответственный (для `groupBy`) **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "amount", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без массива — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/quotes/fields`. [Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Допустимые значения — из списка выше | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/quotes/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "assignedById": 1 }, "groupBy": "stageId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/quotes/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "amount", "function": "sum" }, { "field": "amount", "function": "avg" } ], "filter": { "assignedById": 1 }, "groupBy": "stageId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'amount', function: 'sum' }, { field: 'amount', function: 'avg' }, ], filter: { assignedById: 1 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() console.log('Всего предложений:', data.count) console.log('По стадиям:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [ { field: 'amount', function: 'sum' }, { field: 'amount', function: 'avg' }, ], filter: { assignedById: 1 }, groupBy: 'stageId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["stageId", "assignedById"]` (максимум 5). ## Другие сценарии Только `count` — самый быстрый запрос, без выгрузки записей: ```json { "filter": { "assignedById": 1 } } ``` Работа с пользовательскими полями (UF) — `sum` по UF + группировка по другому UF: ```json { "aggregate": [{ "field": "UF_CRM_DISCOUNT", "function": "sum" }], "groupBy": "UF_CRM_PRIORITY" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Общее количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций: `{ "amount": { "sum": 90000, "avg": 2500 } }` | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Сколько записей обработано для числовых агрегаций (максимум 5000) | | `data.meta.truncated` | boolean | `true`, если под фильтр попало больше 5000 записей | ## Пример ответа Ответ на основной запрос (агрегации + `groupBy: "stageId"`): ```json { "success": true, "data": { "count": 36, "aggregates": { "amount": { "sum": 90000, "avg": 2500 } }, "groups": [ { "stageId": "DRAFT", "count": 20, "aggregates": { "amount": { "sum": 50000 } } }, { "stageId": "APPROVED", "count": 16, "aggregates": { "amount": { "sum": 40000 } } } ], "meta": { "totalRecords": 36, "recordsProcessed": 36, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — неверное имя функции, несуществующее поле или `groupBy` по неаггрегируемому полю: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Field 'foo' not found. Available numeric fields: amount, stageId, assignedById" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Невалидное имя функции, несуществующее поле, нечисловое поле в `sum`/`avg`/`min`/`max`, `groupBy` по неаггрегируемому полю или больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` vs числовые функции.** `count` считается одним вызовом в Битрикс24 на любом объёме данных. Функции `sum`/`avg`/`min`/`max` подгружают записи постранично (максимум 5000) и считают на стороне Вайбкод — если под фильтр попадает больше 5000 записей, `meta.truncated` будет `true`, агрегация выполнится по первым 5000. Для точных счётчиков на больших выборках используйте `count` или сужайте фильтр. **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "ufCrm_1234": "value" } }` вернёт количество предложений с этим значением UF. ## Смотрите также - [Список предложений](/docs/entities/quotes/list) — получить записи с фильтрацией - [Поиск предложений](/docs/entities/quotes/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Create ## Создать предложение `POST /v1/quotes` Создаёт новое коммерческое предложение в CRM. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название предложения | | `opportunity` | number | Сумма. Чтобы сумма не пересчитывалась из товарных позиций, передайте вместе с `isManualOpportunity: "Y"` | | `isManualOpportunity` | string | `"Y"` — ручной режим суммы (обязателен, если задаёте `opportunity` напрямую) | | `currencyId` | string | Валюта. Список: `GET /v1/currencies` | | `stageId` | string | Статус: `DRAFT`, `SENT`, `APPROVED`. Список: `GET /v1/statuses?filter[entityId]=QUOTE_STATUS` | | `dealId` | number | ID сделки. Поиск: `GET /v1/deals` | | `contactId` | number | ID контакта. Поиск: `GET /v1/contacts` | | `companyId` | number | ID компании. Поиск: `GET /v1/companies` | | `assignedById` | number | ID ответственного. Список сотрудников: `GET /v1/users` | | `comments` | string | Комментарий | | `begindate` | datetime | Дата начала (имя поля в нижнем регистре — как в ответах API) | | `closedate` | datetime | Дата закрытия | > **Важно:** слой записи принимает только имена полей из ответов API: `opportunity`, `currencyId`, `begindate`, `closedate`. Алиасы `amount` / `currency` / `beginDate` / `closeDate` при записи молча игнорируются Битрикс24. Полный список полей: [GET /v1/quotes/fields](/docs/entities/quotes/fields). Пользовательские поля (`ufCrm_*`) также принимаются. ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/quotes \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "КП на серверное оборудование", "opportunity": 150000, "isManualOpportunity": "Y", "currencyId": "RUB", "stageId": "DRAFT", "dealId": 741, "assignedById": 1 }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/quotes \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "КП на серверное оборудование", "opportunity": 150000, "isManualOpportunity": "Y", "currencyId": "RUB", "stageId": "DRAFT", "dealId": 741, "assignedById": 1 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'КП на серверное оборудование', opportunity: 150000, isManualOpportunity: 'Y', currencyId: 'RUB', stageId: 'DRAFT', dealId: 741, assignedById: 1, }), }) const { success, data } = await res.json() console.log('Quote ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'КП на серверное оборудование', opportunity: 150000, isManualOpportunity: 'Y', currencyId: 'RUB', stageId: 'DRAFT', dealId: 741, assignedById: 1, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного предложения | | `title` | string | Название | | `opportunity` | number | Сумма | | `currencyId` | string | Валюта | | `stageId` | string | Статус | | `dealId` | number | ID сделки | | `assignedById` | number | Ответственный | | `createdBy` | number | Создатель | | `createdAt` | datetime | Дата создания | | `updatedAt` | datetime | Дата изменения | Ответ содержит все поля предложения, включая пользовательские (`ufCrm_*`). Выше показаны основные. URL карточки предложения в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/crm/type/7/details// ``` `7` — `entityTypeId` коммерческого предложения в Битрикс24. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 412, "title": "КП на серверное оборудование", "opportunity": 150000, "isManualOpportunity": "Y", "currencyId": "RUB", "stageId": "DRAFT", "dealId": 741, "contactId": 0, "companyId": 0, "assignedById": 1, "createdBy": 1, "comments": "", "begindate": "2026-04-15T00:00:00.000Z", "closedate": "2026-05-15T00:00:00.000Z", "createdAt": "2026-04-15T10:30:00.000Z", "updatedAt": "2026-04-15T10:30:00.000Z" } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_REQUEST` | Невалидные поля | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список предложений](/docs/entities/quotes/list) — получение с фильтрами - [Поля предложения](/docs/entities/quotes/fields) — полный список полей - [Entity API](/docs/entity-api) — общие принципы (пагинация, select, order) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение операций - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Delete ## Удалить предложение `DELETE /v1/quotes/:id` Удаляет коммерческое предложение по ID. Восстановить удалённое предложение через API нельзя — создавайте новое при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/quotes/412" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/quotes/412" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Предложение удалено') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — предложение не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение не найдено | | 403 | `ACCESS_DENIED` | Нет доступа к предложению | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список предложений](/docs/entities/quotes/list) — найти предложение перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Fields ## Поля предложения `GET /v1/quotes/fields` Возвращает полный список доступных полей, включая пользовательские (`ufCrm_*`). ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `id` | number | да | ID предложения | | `title` | `title` | string | | Название | | `amount` | `opportunity` | number | | Сумма | | `currency` | `currencyId` | string | | Валюта. Список: `GET /v1/currencies` | | `stageId` | `stageId` | string | | Статус: `DRAFT`, `SENT`, `APPROVED`. Список: `GET /v1/statuses?filter[entityId]=QUOTE_STATUS` | | `dealId` | `dealId` | number | | ID сделки. Поиск: `GET /v1/deals` | | `contactId` | `contactId` | number | | ID контакта. Поиск: `GET /v1/contacts` | | `companyId` | `companyId` | number | | ID компании. Поиск: `GET /v1/companies` | | `assignedById` | `assignedById` | number | | Ответственный. Список: `GET /v1/users` | | `createdBy` | `createdBy` | number | да | Создатель. Поиск: `GET /v1/users` | | `comments` | `comments` | string | | Комментарий | | `beginDate` | `begindate` | datetime | | Дата начала | | `closeDate` | `closedate` | datetime | | Дата закрытия | | `createdAt` | `createdTime` | datetime | да | Дата создания | | `updatedAt` | `updatedTime` | datetime | да | Дата изменения | **Пользовательские поля** (`ufCrm_*`) также возвращаются в ответах и принимаются при создании/обновлении. ## Доступные include Эндпоинт `GET /v1/quotes/fields` возвращает список доступных include: `deal`, `contact`, `company`. Пример использования: [Получить quotes](/docs/entities/quotes/get#связанные-данные). Подробнее об include: [Связанные данные](/docs/includes). ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "title": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название" }, "assignedById": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Ответственный" } } } } ``` Показаны 3 из множества полей. Полный список в таблице выше. ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать предложение](/docs/entities/quotes/create) — какие поля передавать - [Пользовательские поля](/docs/userfields) — создание и управление `ufCrm_*` - [Entity API](/docs/entity-api) — select для выборки нужных полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Get ## Получить предложение `GET /v1/quotes/:id` Возвращает коммерческое предложение по ID со всеми полями, включая пользовательские (`ufCrm_*`). ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/412" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/412" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Предложение:', data.title, '—', data.amount, data.currency) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` Подробнее об include: [Связанные данные](/docs/includes). ## Поля ответа Объект предложения со всеми полями — см. [Поля предложения](/docs/entities/quotes/fields). ## Связанные данные Получить связанные сущности вместе с предложением — параметр `include` в GET-запросе: ``` GET /v1/quotes/412?include=deal,contact,company ``` Доступные include: `deal`, `contact`, `company`. Результат в поле `_included`: ```json { "success": true, "data": { "id": 412, "title": "КП на серверное оборудование", "_included": { "deal": { "id": 741, "title": "Поставка оборудования", "amount": 50000 }, "contact": { "id": 71, "name": "Иван Петров" }, "company": { "id": 15, "title": "ООО Ромашка" } } } } ``` Подробнее об include: [Связанные данные](/docs/includes). ## Пример ответа ```json { "success": true, "data": { "id": 412, "title": "КП на серверное оборудование", "amount": 150000, "currency": "RUB", "stageId": "SENT", "dealId": 741, "contactId": 71, "companyId": 15, "assignedById": 29, "createdBy": 1, "comments": "", "beginDate": "2026-04-15T00:00:00.000Z", "closeDate": "2026-05-15T00:00:00.000Z", "createdAt": "2026-04-15T10:30:00.000Z", "updatedAt": "2026-04-15T14:22:00.000Z", "_included": { "deal": { "id": 741, "title": "Поставка оборудования", "amount": 50000 }, "contact": { "id": 71, "name": "Иван Петров" }, "company": { "id": 15, "title": "ООО Ромашка" } } } } ``` ## Пример ответа при ошибке 404 — предложение не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` Подробнее об include: [Связанные данные](/docs/includes). ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение с таким ID не найдено | | 403 | `ACCESS_DENIED` | Нет доступа к предложению | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Обновить предложение](/docs/entities/quotes/update) — изменение полей - [Список предложений](/docs/entities/quotes/list) — поиск с фильтрами - [Поля предложения](/docs/entities/quotes/fields) — описание всех полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: List ## Список предложений `GET /v1/quotes` Возвращает список коммерческих предложений с поддержкой фильтрации, сортировки и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у B24 | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit <= 500` | | `select` | string | — | Выборка полей: `?select=id,title,amount` | | `order` | object | — | Сортировка: `?order[createdAt]=desc` | | `filter` | object | — | Фильтрация по полям `GET /v1/quotes/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[stageId]=DRAFT` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/quotes?limit=10&order[amount]=desc&filter[stageId]=DRAFT" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/quotes?limit=10&order[amount]=desc&filter[stageId]=DRAFT" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes?limit=10&order[amount]=desc&filter[stageId]=DRAFT', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, total } = await res.json() console.log(`Найдено ${total} предложений`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes?limit=10&order[amount]=desc&filter[stageId]=DRAFT', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, total } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив предложений (каждое содержит все поля — см. [Поля](/docs/entities/quotes/fields)) | | `total` | number | Общее количество записей, соответствующих фильтру | | `page` | number | Текущая страница | | `limit` | number | Размер страницы | URL карточки любого предложения из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/type/7/details// ``` `7` — `entityTypeId` коммерческого предложения в Битрикс24. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 412, "title": "КП на серверное оборудование", "amount": 150000, "currency": "RUB", "stageId": "DRAFT", "dealId": 741, "assignedById": 1, "createdAt": "2026-04-15T10:30:00.000Z", "contactId": 71, "companyId": 15 } ], "total": 48, "page": 1, "limit": 10 } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-пагинация:** при `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Bitrix24 и возвращает все записи в одном ответе. **Ограничение offset:** при `offset >= 2500` Bitrix24 может вернуть `INTERNAL_ERROR`. Используйте `limit <= 500` при больших offset. **Когда использовать search вместо list:** для сложных фильтров с множеством условий удобнее `POST /v1/quotes/search` — параметры передаются в body, а не в query-строке. Также search поддерживает [оконный поиск по датам](/docs/batch) для больших выборок. См. [Поиск предложений](/docs/entities/quotes/search). ## Смотрите также - [Поиск предложений](/docs/entities/quotes/search) — POST-запрос для сложных фильтров - [Создать предложение](/docs/entities/quotes/create) — создание нового - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Products Add ## Добавить товар в предложение `POST /v1/quotes/:id/products` Добавляет одну товарную позицию в предложение. В отличие от `PUT /v1/quotes/:id/products`, не заменяет существующие позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | | `productId` | number | нет | ID товара из каталога. Если задан без `productName`, имя подставляется из каталога. Каталог: `GET /v1/products` | | `productName` | string | нет | Название товарной позиции — для произвольной строки без товара из каталога. Укажите хотя бы одно из `productId` / `productName`. | | `price` | number | нет | Цена за единицу | | `quantity` | number | нет | Количество | | `discount` | number | нет | Сумма скидки | | `taxRate` | number | нет | Ставка налога (%) | | `taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/quotes/52/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/quotes/52/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productId": 1, "price": 25000, "quantity": 2 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/52/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() console.log('ID строки:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/52/products', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: 1, price: 25000, quantity: 2 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID созданной товарной строки | ## Пример ответа ```json { "success": true, "data": { "id": 1465 } } ``` ## Пример ответа при ошибке 404 — предложение не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение не найдено | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/quotes/products-get) — получить текущий список - [Установить товары](/docs/entities/quotes/products-set) — заменить все позиции - [Удалить товар](/docs/entities/quotes/products-delete) — удалить одну позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Quotes: Products Delete ## Удалить товар из предложения `DELETE /v1/quotes/:id/products/:rowId` Удаляет одну товарную позицию из предложения по ID строки. Восстановить удалённую позицию через API нельзя — добавляйте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/quotes/52/products/1465" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/quotes/52/products/1465" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/52/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Товар удалён из предложения') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/52/products/1465', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — предложение не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение или товарная строка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/quotes/products-get) — получить текущий список - [Добавить товар](/docs/entities/quotes/products-add) — добавить позицию - [Установить товары](/docs/entities/quotes/products-set) — заменить все позиции - [Товары каталога](/docs/entities/products) — справочник товаров --- # Quotes: Products Fields ## Поля товаров предложения `GET /v1/quotes/:id/products/fields` Возвращает описание полей товарных позиций предложения: названия, типы, доступность для чтения и записи. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/741/products/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/741/products/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Обяз. | Описание | |------|-----|:--:|:-----:|---------| | `id` | integer | да | | ID позиции | | `productId` | integer | | да | ID товара. Каталог: `GET /v1/products` | | `productName` | string | | | Название товара | | `price` | double | | | Цена | | `quantity` | double | | | Количество | | `discountSum` | double | | | Сумма скидки | | `discountRate` | double | | | Величина скидки (%) | | `discountTypeId` | integer | | | Тип скидки | | `taxRate` | double | | | Налог (%) | | `taxIncluded` | char | | | Налог включён в цену (`Y`/`N`) | | `priceExclusive` | double | да | | Цена без налога со скидкой | | `priceNetto` | double | да | | Цена нетто | | `priceBrutto` | double | да | | Цена брутто | | `measureCode` | integer | | | Код единицы измерения | | `measureName` | string | | | Единица измерения | | `customized` | char | | | Изменён (`Y`/`N`) | | `sort` | integer | | | Сортировка | | `type` | integer | да | | Тип | | `storeId` | integer | да | | ID склада | | `ownerId` | integer | | да | ID владельца (предложения) | | `ownerType` | string | | да | Тип владельца | ## Пример ответа ```json { "success": true, "data": { "id": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "ID" }, "ownerId": { "type": "integer", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "ID владельца" }, "ownerType": { "type": "string", "isRequired": true, "isReadOnly": false, "isImmutable": true, "title": "Тип владельца" }, "productId": { "type": "integer", "isRequired": true, "isReadOnly": false, "title": "Товар" }, "productName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Название товара" }, "price": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Цена" }, "priceExclusive": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "Цена без налога со скидкой" }, "priceNetto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_NETTO" }, "priceBrutto": { "type": "double", "isRequired": false, "isReadOnly": true, "title": "PRICE_BRUTTO" }, "quantity": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Количество" }, "discountTypeId": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Тип скидки" }, "discountRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Величина скидки" }, "discountSum": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Сумма скидки" }, "taxRate": { "type": "double", "isRequired": false, "isReadOnly": false, "title": "Налог" }, "taxIncluded": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Налог включен в цену" }, "customized": { "type": "char", "isRequired": false, "isReadOnly": false, "title": "Изменен" }, "measureCode": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Код единицы измерения" }, "measureName": { "type": "string", "isRequired": false, "isReadOnly": false, "title": "Единица измерения" }, "sort": { "type": "integer", "isRequired": false, "isReadOnly": false, "title": "Сортировка" }, "type": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "TYPE" }, "storeId": { "type": "integer", "isRequired": false, "isReadOnly": true, "title": "STORE_ID" } } } ``` ## Пример ответа при ошибке 404 — предложение не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение не найдено | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/quotes/products-get) — получить товары предложения - [Добавить товар](/docs/entities/quotes/products-add) — добавить позицию - [Установить товары](/docs/entities/quotes/products-set) — заменить все позиции - [Поля предложения](/docs/entities/quotes/fields) — описание полей предложения --- # Quotes: Products Get ## Товарные позиции предложения `GET /v1/quotes/:id/products` Возвращает список товарных позиций, привязанных к предложению. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/741/products" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/quotes/741/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Товаров:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив товарных позиций | | `data[].productId` | number | ID товара. Каталог: `GET /v1/products` | | `data[].productName` | string | Название товара | | `data[].price` | number | Цена за единицу | | `data[].quantity` | number | Количество | | `data[].discount` | number | Сумма скидки | | `data[].taxRate` | number/null | Ставка налога (%) | | `data[].taxIncluded` | boolean | Налог включён в цену | Показаны основные поля. Полный список (20 полей, включая priceAccount, measureCode и др.): [Поля товаров](/docs/entities/quotes/products-fields). ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 1000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 404 — предложение не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение не найдено | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Установить товары](/docs/entities/quotes/products-set) — заменить товарные позиции - [Получить предложение](/docs/entities/quotes/get) — основные данные предложения - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Products Get Single ## Получить товар из предложения `GET /v1/quotes/:id/products/:rowId` Возвращает одну товарную позицию предложения по ID строки. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | | `rowId` (path) | number | да | ID товарной строки (из ответа add или list) | `rowId` — это ID товарной строки, а не `productId` из каталога товаров. ## Примеры ### curl — личный ключ ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/quotes/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X GET "https://vibecode.bitrix24.tech/v1/quotes/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Цена:', data.price) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products/1471', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data.id` | number | ID товарной строки | | `data.productId` | number | ID товара из каталога | | `data.productName` | string | Название товара | | `data.price` | number | Цена за единицу | | `data.quantity` | number | Количество | | `data.discount` | number | Сумма скидки | | `data.discountRate` | number | Процент скидки | | `data.discountTypeId` | number | Тип скидки (1 — сумма, 2 — процент) | | `data.taxRate` | number \| null | Ставка налога (%) | | `data.taxIncluded` | boolean | Налог включён в цену | | `data.priceExclusive` | number | Цена без скидки | | `data.priceNetto` | number | Цена нетто | | `data.priceBrutto` | number | Цена брутто | | `data.priceAccount` | number | Цена в валюте учёта | | `data.measureCode` | number | Код единицы измерения | | `data.measureName` | string | Название единицы измерения | | `data.sort` | number | Сортировка | ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "День добрый!", "price": 5000, "priceAccount": 5000, "priceExclusive": 5000, "priceNetto": 5000, "priceBrutto": 5000, "quantity": 3, "discountTypeId": 2, "discountRate": 0, "discount": 0, "taxRate": null, "taxIncluded": false, "customized": "Y", "measureCode": 796, "measureName": "шт", "sort": 0, "xmlId": "sale_basket_995", "type": 1 } } ``` ## Пример ответа при ошибке 404 — предложение или товарная строка не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение или товарная строка не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Товарные позиции](/docs/entities/quotes/products-get) — получить все позиции - [Обновить товар](/docs/entities/quotes/products-update) — обновить позицию - [Добавить товар](/docs/entities/quotes/products-add) — добавить позицию - [Удалить товар](/docs/entities/quotes/products-delete) — удалить позицию - [Товары каталога](/docs/entities/products) — справочник товаров --- # Quotes: Products Set ## Установить товары предложения `PUT /v1/quotes/:id/products` Устанавливает товарные позиции коммерческого предложения. Полностью заменяет текущий список — передайте все нужные позиции. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `items` | array | да | Массив товарных позиций | | `items[].productId` | number | да | ID товара. Каталог: `GET /v1/products` | | `items[].price` | number | да | Цена за единицу | | `items[].quantity` | number | да | Количество | | `items[].discount` | number | нет | Сумма скидки | | `items[].taxRate` | number | нет | Ставка налога (%) | | `items[].taxIncluded` | boolean | нет | Налог включён в цену | ## Примеры ### curl — личный ключ ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/quotes/412/products" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 75000, "quantity": 2 }, { "productId": 5, "price": 10000, "quantity": 1, "discount": 1000 } ] }' ``` ### curl — OAuth-приложение ```bash curl -X PUT "https://vibecode.bitrix24.tech/v1/quotes/412/products" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "productId": 1, "price": 75000, "quantity": 2 }, { "productId": 5, "price": 10000, "quantity": 1, "discount": 1000 } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 75000, quantity: 2 }, { productId: 5, price: 10000, quantity: 1, discount: 1000 }, ], }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412/products', { method: 'PUT', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ items: [ { productId: 1, price: 75000, quantity: 2 }, { productId: 5, price: 10000, quantity: 1, discount: 1000 }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив установленных позиций с полями productId, productName, price, quantity, discount, taxRate, taxIncluded | Массив установленных позиций с полями `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": [ { "productId": 1, "productName": "Серверное оборудование", "price": 75000, "quantity": 2, "discount": 0, "taxRate": null, "taxIncluded": false }, { "productId": 5, "productName": "Установка и настройка", "price": 10000, "quantity": 1, "discount": 1000, "taxRate": null, "taxIncluded": false } ] } ``` ## Пример ответа при ошибке 400 — неверный формат: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "items must be an array" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `items` не является массивом | | 404 | `ENTITY_NOT_FOUND` | Предложение не найдено | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Полная замена:** PUT заменяет весь список товаров. Чтобы добавить позицию — сначала получите текущие (`GET`), добавьте новую в массив, отправьте всё (`PUT`). ## Смотрите также - [Товарные позиции](/docs/entities/quotes/products-get) — получить текущий список - [Получить предложение](/docs/entities/quotes/get) — основные данные предложения - [Товары каталога](/docs/entities/products) — справочник товаров - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Products Update ## Обновить товар предложения `PATCH /v1/quotes/:id/products/:rowId` Обновляет товарную позицию предложения. Передайте только изменяемые поля. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID предложения | | `rowId` (path) | number | да | ID товарной позиции (из ответа list или add, не productId из каталога) | ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `price` | number | Цена за единицу | | `quantity` | number | Количество | | `productId` | number | ID товара. Каталог: `GET /v1/products` | | `discount` | number | Сумма скидки | | `taxRate` | number | Ставка налога (%) | | `taxIncluded` | boolean | Налог включён в цену | | `sort` | number | Сортировка | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/quotes/741/products/1471" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/quotes/741/products/1471" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "price": 9999, "quantity": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() console.log('Обновлено:', data.price, 'x', data.quantity) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/741/products/1471', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ price: 9999, quantity: 10 }), }) const { success, data } = await res.json() ``` ## Поля ответа Обновлённый объект товарной позиции: `id`, `productId`, `productName`, `price`, `quantity`, `discount`, `taxRate`, `taxIncluded`. ## Пример ответа ```json { "success": true, "data": { "id": 1471, "productId": 1, "productName": "Серверное оборудование", "price": 9999, "quantity": 10, "discount": 0, "taxRate": null, "taxIncluded": false } } ``` ## Пример ответа при ошибке 404 — позиция не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Позиция не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить товар](/docs/entities/quotes/products-get-single) — получение одной позиции - [Получить товары](/docs/entities/quotes/products-get) — список всех позиций - [Добавить товар](/docs/entities/quotes/products-add) — добавление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Search ## Поиск предложений `POST /v1/quotes/search` Поиск коммерческих предложений с фильтрами и авто-пагинацией. Аналогичен `GET /v1/quotes` с фильтрами, но через POST — удобнее для сложных запросов с большим количеством условий. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/quotes/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[stageId]=DRAFT` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "createdAt": "desc" }` | | `select` | string[] | — | Выборка полей: `["id", "title", "amount"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/quotes/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "stageId": "DRAFT" }, "limit": 10, "order": { "amount": "desc" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/quotes/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "stageId": "DRAFT" }, "limit": 10, "order": { "amount": "desc" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { stageId: 'DRAFT' }, limit: 10, order: { amount: 'desc' }, }), }) const { success, data } = await res.json() console.log('Найдено:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { stageId: 'DRAFT' }, limit: 10, order: { amount: 'desc' }, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив предложений (все поля — см. [Поля](/docs/entities/quotes/fields)) | URL карточки любого предложения из массива `data` — его `id`: ``` https://.bitrix24.ru/crm/type/7/details// ``` `7` — `entityTypeId` коммерческого предложения в Битрикс24. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 412, "title": "КП на серверное оборудование", "amount": 150000, "currency": "RUB", "stageId": "DRAFT", "dealId": 741, "assignedById": 29, "createdAt": "2026-04-15T10:30:00.000Z" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список предложений](/docs/entities/quotes/list) — GET-запрос с query-параметрами (для простых фильтров) - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Quotes: Update ## Обновить предложение `PATCH /v1/quotes/:id` Обновляет поля существующего коммерческого предложения. Передайте только изменяемые поля. Полный список в [справочнике полей](/docs/entities/quotes/fields), включая пользовательские (`ufCrm_*`). ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `stageId` | string | Статус: `DRAFT`, `SENT`, `APPROVED`. Список: `GET /v1/statuses?filter[entityId]=QUOTE_STATUS` | | `opportunity` | number | Сумма предложения. Передавайте вместе с `isManualOpportunity: "Y"`, иначе Битрикс24 пересчитает сумму из товарных позиций | | `assignedById` | number | Ответственный. Список: `GET /v1/users` | | `title` | string | Название | | `closedate` | datetime | Дата закрытия (имя поля в нижнем регистре — как в ответах API) | > **Важно:** слой записи принимает только имена полей из ответов API: `opportunity`, `currencyId`, `begindate`, `closedate`. Алиасы `amount` / `currency` / `beginDate` / `closeDate` при записи молча игнорируются Битрикс24 — запрос вернёт 200, но значение не изменится. ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/quotes/412" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stageId": "APPROVED", "isManualOpportunity": "Y", "opportunity": 145000 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/quotes/412" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "stageId": "APPROVED", "isManualOpportunity": "Y", "opportunity": 145000 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'APPROVED', isManualOpportunity: 'Y', opportunity: 145000, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/quotes/412', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ stageId: 'APPROVED', isManualOpportunity: 'Y', opportunity: 145000, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект предложения со всеми полями — см. [Поля](/docs/entities/quotes/fields) | Обновлённый объект предложения со всеми полями — см. [Поля предложения](/docs/entities/quotes/fields). ## Пример ответа ```json { "success": true, "data": { "id": 412, "title": "КП на серверное оборудование", "opportunity": 145000, "currencyId": "RUB", "stageId": "APPROVED", "dealId": 741, "assignedById": 1, "updatedAt": "2026-04-15T15:10:00.000Z" } } ``` ## Пример ответа при ошибке 404 — предложение не найдено: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Предложение не найдено | | 403 | `ACCESS_DENIED` | Нет доступа к предложению | | 400 | `INVALID_REQUEST` | Невалидные поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить предложение](/docs/entities/quotes/get) — текущие значения полей - [Поля предложения](/docs/entities/quotes/fields) — какие поля можно изменять - [Batch](/docs/batch) — массовое обновление предложений - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: Aggregate ## Агрегация реквизитов `POST /v1/requisites/aggregate` Подсчёт количества реквизитов с фильтрацией и группировкой. **Стандартные поля:** - `entityTypeId` — тип владельца (1 — лид, 3 — контакт, 4 — компания) — для `groupBy` - `presetId` — пресет реквизита (для `groupBy`) Все поля в `aggregatable` — идентификаторы и категориальные коды, поэтому по стандартным полям работают `count` и `groupBy`. Для числовых функций (`sum`/`avg`/`min`/`max`) используйте пользовательские поля. **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` — для числовых функций; UF любого типа — для `groupBy`. На практике у реквизита обычно UF-поля строкового типа (ИНН, номер телефона, адрес) — их можно использовать только в `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "*", "function": "count" }`. Без параметра — только count | | `filter` | object | нет | Фильтрация по полям `GET /v1/requisites/fields`.
[Синтаксис фильтрации](/docs/filtering) | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Принимает UF-поля любого типа | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/requisites/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true }, "groupBy": "entityTypeId" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/requisites/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true }, "groupBy": "entityTypeId" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, groupBy: 'entityTypeId', }), }) const { success, data } = await res.json() console.log('Всего активных реквизитов:', data.count) console.log('По типам владельцев:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, groupBy: 'entityTypeId', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["entityTypeId", "presetId"]` (максимум 5). ## Другие сценарии Общее количество реквизитов в портале — самый быстрый запрос, без выгрузки записей: ```json {} ``` Группировка по UF-полю (любой тип — например, пользовательский классификатор): ```json { "groupBy": "UF_CRM_CLASSIFIER" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Количество записей, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций (для реквизитов обычно пустой) | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` | | `data.meta.totalRecords` | number | Общее количество записей | | `data.meta.recordsProcessed` | number | Количество обработанных записей | | `data.meta.truncated` | boolean | Был ли результат ограничен (`true` при более 5000 записей) | ## Пример ответа Ответ на основной запрос (`groupBy: "entityTypeId"`): ```json { "success": true, "data": { "count": 164, "aggregates": {}, "groups": [ { "entityTypeId": 4, "count": 120 }, { "entityTypeId": 3, "count": 40 }, { "entityTypeId": 1, "count": 4 } ], "meta": { "totalRecords": 164, "recordsProcessed": 164, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "Requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Невалидное имя функции агрегации или несуществующее поле | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"1500|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. **Без массива `aggregate` — только count.** Если не передать `aggregate`, метод вернёт `count` записей с учётом фильтра. **Фильтрация по UF работает.** В `filter` можно передавать любые поля — стандартные и пользовательские, любого типа. Например, `{ "filter": { "UF_CRM_1234": "value" } }` вернёт количество реквизитов с этим значением UF. **Ограничение 5000 записей.** Если под фильтр попадает больше 5000 записей, результат будет помечен `meta.truncated: true`. Для точного подсчёта больших выборок используйте `meta.total` в ответе `GET /v1/requisites` с `limit=1` — там хранится реальное количество. ## Смотрите также - [Список реквизитов](/docs/entities/requisites/list) — `meta.total` даёт точное число записей - [Поиск реквизитов](/docs/entities/requisites/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: Create ## Создать реквизит `POST /v1/requisites` Создаёт новый реквизит и привязывает его к контакту или компании CRM. ## Обязательные поля Битрикс24 требует четыре поля для создания реквизита: | Поле | Тип | Допустимые значения | Описание | |------|-----|--------------------|---------| | `entityTypeId` | number | `3` (контакт), `4` (компания) | Тип родительской сущности | | `entityId` | number | любой существующий ID | ID родительской сущности. Поиск: `GET /v1/contacts` или `GET /v1/companies` | | `presetId` | number | любой существующий ID пресета | ID пресета реквизита (определяет набор полей) | | `name` | string | непустая строка | Название реквизита. Без него Битрикс24 отклоняет создание: 422 `BITRIX_ERROR` «Не заполнено обязательное поле „Название"» | ## Популярные поля Все поля в camelCase. Полный список — [`GET /v1/requisites/fields`](./fields.md). ### Общие | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `active` | boolean | `true` | Активен ли реквизит | | `sort` | number | `500` | Порядок сортировки (чем меньше — тем выше) | | `code` / `xmlId` / `originatorId` | string | — | Внешние идентификаторы для синхронизации | | `addressOnly` | boolean | `false` | Признак «только адрес» (для адресных справочников) | ### Юрлица (российский пресет) | Параметр | Тип | Описание | |----------|-----|---------| | `rqName` | string | Полное наименование | | `rqCompanyName` | string | Сокращённое название | | `rqCompanyFullName` | string | Полное название юрлица | | `rqCompanyRegDate` | date | Дата регистрации | | `rqInn` | string | ИНН | | `rqKpp` | string | КПП | | `rqOgrn` | string | ОГРН | | `rqOgrnip` | string | ОГРНИП (для ИП) | | `rqOkpo` / `rqOkved` / `rqOktmo` | string | Классификаторы | | `rqDirector` | string | ФИО директора | | `rqAccountant` | string | ФИО главного бухгалтера | | `rqCeoName` / `rqCeoWorkPos` | string | ФИО и должность руководителя | | `rqContact` / `rqEmail` / `rqPhone` / `rqFax` | string | Контакты организации | | `rqVatPayer` | boolean | Плательщик НДС | | `rqVatId` | string | ИНН для НДС (иностранные) | | `rqBaseDoc` | string | Документ-основание деятельности (например, «Устав») | | `rqResidenceCountry` | string | Страна регистрации | ### Физлица | Параметр | Тип | Описание | |----------|-----|---------| | `rqFirstName` / `rqLastName` / `rqSecondName` | string | Имя / Фамилия / Отчество | | `rqIdentDocType` | string | Название документа, удостоверяющего личность | | `rqIdentDocSer` / `rqIdentDocNum` | string | Серия / Номер документа | | `rqIdentDocDate` | date | Дата выдачи | | `rqIdentDocIssuedBy` | string | Кем выдан | | `rqIdentDocDepCode` | string | Код подразделения | ### Международные пресеты Поля для пресетов других стран (`RQ_EDRPOU`/Украина, `RQ_KBE`/Казахстан, `RQ_REGON`/Польша, `RQ_SIRET`/Франция, `RQ_CNPJ`/Бразилия) передаются в исходном `UPPER_SNAKE_CASE` — они не включены в Вайбкод-схему, но Битрикс24 их принимает. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/requisites" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityTypeId": 4, "entityId": 15, "presetId": 1, "name": "Основной", "rqName": "ООО «Ромашка»", "rqInn": "7701234567", "rqKpp": "770101001", "rqOgrn": "1027700123456", "rqCompanyName": "Ромашка", "rqDirector": "Иванов Иван Иванович", "rqVatPayer": true }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/requisites" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "entityTypeId": 4, "entityId": 15, "presetId": 1, "name": "Основной", "rqName": "ООО «Ромашка»", "rqInn": "7701234567" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ entityTypeId: 4, entityId: 15, presetId: 1, name: 'Основной', rqName: 'ООО «Ромашка»', rqInn: '7701234567', rqKpp: '770101001', rqOgrn: '1027700123456', rqCompanyName: 'Ромашка', rqDirector: 'Иванов Иван Иванович', rqVatPayer: true, }), }) const { success, data } = await res.json() console.log('Создан реквизит ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ entityTypeId: 4, entityId: 15, presetId: 1, name: 'Основной', rqName: 'ООО «Ромашка»', rqInn: '7701234567', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Созданный реквизит | | `data.id` | number | Идентификатор новой записи | | `data.entityTypeId` / `data.entityId` / `data.presetId` | number | Переданные значения | | `data.name` | string \| null | Название реквизита | | `data.active` | boolean | Активен ли реквизит (`true` по умолчанию) | | `data.sort` | number | Порядок сортировки (`500` по умолчанию) | | `data.createdAt` / `data.updatedAt` | datetime | Совпадают при создании | | `data.createdBy` | number | ID создателя | | `data.modifyBy` | number \| null | `null` сразу после создания | Ответ содержит все поля пресета реквизита в camelCase. Незаполненные поля — `null`. Полный список полей — [Поля реквизита](/docs/entities/requisites/fields). ## Пример ответа HTTP-статус: `201 Created` ```json { "success": true, "data": { "id": 42, "entityTypeId": 4, "entityId": 15, "presetId": 1, "name": "Основной", "active": true, "sort": 500, "createdAt": "2026-04-19T14:30:00+03:00", "updatedAt": "2026-04-19T14:30:00+03:00", "createdBy": 1, "modifyBy": null, "rqName": "ООО «Ромашка»", "rqInn": "7701234567", "rqKpp": "770101001", "rqOgrn": "1027700123456", "rqCompanyName": "Ромашка", "rqDirector": "Иванов Иван Иванович", "rqVatPayer": true, "rqAccountant": null, "rqCeoName": null, "rqOkpo": null, "rqOkved": null } } ``` ## Пример ответа при ошибке 400 — не указан `presetId`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "PRESET_ID field value is not specified" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Не указано обязательное поле — Битрикс24 отвечает текстом вида `PRESET_ID is not defined or invalid` / «Не заполнено обязательное поле „Название"» | | 422 | `BITRIX_ERROR` | Битрикс24 отклонил значение одного из полей (например, несуществующий `presetId`) | | 403 | `ACCESS_DENIED` | Нет доступа к родительской компании/контакту | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поля, которых нет в пресете, игнорируются.** Если передать поле, которого нет в выбранном пресете, Битрикс24 молча его проигнорирует — ошибка не возникнет, но и значение не сохранится. ## Смотрите также - [Список реквизитов](/docs/entities/requisites/list) — получить существующие - [Поля реквизита](/docs/entities/requisites/fields) — полный перечень - [Обновить реквизит](/docs/entities/requisites/update) — изменить после создания - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — массовое создание - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: Delete ## Удалить реквизит `DELETE /v1/requisites/:id` Удаляет реквизит по ID. Привязанные к реквизиту адреса и банковские реквизиты удаляются вместе с ним на уровне Битрикс24. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID реквизита | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/requisites/42" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/requisites/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Реквизит удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — реквизит не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "The Requisite with ID '999999999' is not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Реквизит с таким ID не найден | | 403 | `ACCESS_DENIED` | Нет доступа к родительской сущности | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Удаление каскадное.** Вместе с реквизитом удаляются привязанные к нему адреса и банковские реквизиты — это поведение Битрикс24, оно не настраивается. **Мягкое удаление отсутствует.** После удаления восстановить реквизит нельзя — создавайте новый. Если нужен временный «отказ от использования», используйте поле `active: false` через [обновление](/docs/entities/requisites/update). ## Смотрите также - [Список реквизитов](/docs/entities/requisites/list) — найти реквизит перед удалением - [Получить реквизит](/docs/entities/requisites/get) — посмотреть данные перед удалением - [Обновить реквизит](/docs/entities/requisites/update) — деактивация вместо удаления (`active: false`) - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: Fields ## Поля реквизита `GET /v1/requisites/fields` Возвращает полный перечень полей реквизита — 60 полей в Вайбкод-схеме (camelCase) + исходные поля Битрикс24 (`UPPER_SNAKE_CASE`) для международных пресетов, редких служебных полей и пользовательских `UF_CRM_*`. Каждый конкретный реквизит хранит значения только тех полей, которые есть в его пресете. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/requisites/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/requisites/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() console.log('Всего полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Формат ответа Ответ — объект `{ success, data: { fields: {...} } }`. Каждое поле описано объектом: - **Поля из схемы Вайбкод** (camelCase): `{ type, readonly }`. Возвращаются в `list/get/create/update/search` в camelCase. - **Поля Битрикс24 вне схемы** (`UPPER_SNAKE_CASE`): `{ type, readonly, label }` — `label` на языке портала. ## Поля из схемы Вайбкод (60 полей) Все возвращаются в camelCase, фильтруются и сортируются по camelCase-имени. ### Служебные | Вайбкод-имя | Битрикс24 | Тип | RO | Описание | |----------|----------|-----|:--:|---------| | `id` | `ID` | number | да | ID реквизита | | `entityTypeId` | `ENTITY_TYPE_ID` | number | | `3` — контакт, `4` — компания | | `entityId` | `ENTITY_ID` | number | | ID родительской сущности | | `presetId` | `PRESET_ID` | number | | ID пресета (неизменяем после создания) | | `name` | `NAME` | string | | Название в интерфейсе Битрикс24 | | `code` | `CODE` | string | | Символьный код для внешних интеграций | | `xmlId` | `XML_ID` | string | | Внешний идентификатор для синхронизации | | `originatorId` | `ORIGINATOR_ID` | string | | ID системы-источника | | `active` | `ACTIVE` | boolean | | Активен ли реквизит | | `sort` | `SORT` | number | | Порядок сортировки (меньше — выше) | | `createdAt` | `DATE_CREATE` | datetime | да | Дата создания | | `updatedAt` | `DATE_MODIFY` | datetime | да | Дата последнего изменения | | `createdBy` | `CREATED_BY_ID` | number | да | ID создателя | | `modifyBy` | `MODIFY_BY_ID` | number | да | ID последнего редактора | | `addressOnly` | `ADDRESS_ONLY` | boolean | | Признак «только адрес» | ### Юрлица (российский пресет) | Вайбкод-имя | Битрикс24 | Тип | Описание | |----------|----------|-----|---------| | `rqName` | `RQ_NAME` | string | Полное наименование | | `rqCompanyName` | `RQ_COMPANY_NAME` | string | Сокращённое название | | `rqCompanyFullName` | `RQ_COMPANY_FULL_NAME` | string | Полное название | | `rqCompanyRegDate` | `RQ_COMPANY_REG_DATE` | date | Дата регистрации | | `rqDirector` | `RQ_DIRECTOR` | string | ФИО директора | | `rqAccountant` | `RQ_ACCOUNTANT` | string | ФИО главного бухгалтера | | `rqCeoName` | `RQ_CEO_NAME` | string | ФИО руководителя | | `rqCeoWorkPos` | `RQ_CEO_WORK_POS` | string | Должность руководителя | | `rqContact` | `RQ_CONTACT` | string | Контактное лицо | | `rqEmail` | `RQ_EMAIL` | string | Email организации | | `rqPhone` | `RQ_PHONE` | string | Телефон организации | | `rqFax` | `RQ_FAX` | string | Факс | | `rqInn` | `RQ_INN` | string | ИНН | | `rqKpp` | `RQ_KPP` | string | КПП | | `rqUsn` | `RQ_USN` | string | УСН | | `rqOgrn` | `RQ_OGRN` | string | ОГРН | | `rqOgrnip` | `RQ_OGRNIP` | string | ОГРНИП (для ИП) | | `rqOkpo` | `RQ_OKPO` | string | ОКПО | | `rqOkved` | `RQ_OKVED` | string | ОКВЭД | | `rqOktmo` | `RQ_OKTMO` | string | ОКТМО | | `rqVatPayer` | `RQ_VAT_PAYER` | boolean | Плательщик НДС | | `rqVatId` | `RQ_VAT_ID` | string | ИНН для НДС | | `rqVatCertDate` | `RQ_VAT_CERT_DATE` | date | Дата свидетельства НДС | | `rqVatCertNum` | `RQ_VAT_CERT_NUM` | string | Номер свидетельства НДС | | `rqResidenceCountry` | `RQ_RESIDENCE_COUNTRY` | string | Страна регистрации | | `rqBaseDoc` | `RQ_BASE_DOC` | string | Документ-основание | | `rqBaseDocDate` | `RQ_BASE_DOC_DATE` | date | Дата документа-основания | | `rqBaseDocNum` | `RQ_BASE_DOC_NUM` | string | Номер документа-основания | | `rqRegCertNum` | `RQ_REG_CERT_NUM` | string | Свидетельство о регистрации — номер | | `rqRegCertDate` | `RQ_REG_CERT_DATE` | date | Свидетельство о регистрации — дата | | `rqRegOrganization` | `RQ_REG_ORGANIZATION` | string | Регистрирующий орган | | `rqStateReg` | `RQ_STATE_REG` | string | Государственная регистрация | | `rqMnplReg` | `RQ_MNPL_REG` | string | Муниципальная регистрация | | `rqStampPresent` | `RQ_STAMP_PRESENT` | boolean | Наличие печати | ### Физлица | Вайбкод-имя | Битрикс24 | Тип | Описание | |----------|----------|-----|---------| | `rqFirstName` | `RQ_FIRST_NAME` | string | Имя | | `rqLastName` | `RQ_LAST_NAME` | string | Фамилия | | `rqSecondName` | `RQ_SECOND_NAME` | string | Отчество | | `rqIdentDocType` | `RQ_IDENT_DOC` | string | Название документа, удостоверяющего личность | | `rqIdentDocSer` | `RQ_IDENT_DOC_SER` | string | Серия документа | | `rqIdentDocNum` | `RQ_IDENT_DOC_NUM` | string | Номер документа | | `rqIdentDocDate` | `RQ_IDENT_DOC_DATE` | date | Дата выдачи | | `rqIdentDocIssuedBy` | `RQ_IDENT_DOC_ISSUED_BY` | string | Кем выдан | | `rqIdentDocDepCode` | `RQ_IDENT_DOC_DEP_CODE` | string | Код подразделения | ## Поля Битрикс24 вне схемы (в `UPPER_SNAKE_CASE`) Эти поля возвращаются в ответах в исходном регистре Битрикс24. Фильтрация работает только по `UPPER_SNAKE_CASE`-имени. ### Международные пресеты Намеренно не включены в Вайбкод-схему — будут мусором на российских порталах. Используются по мере настройки пресетов соответствующих стран. | Поле | Страна | Описание | |------|--------|---------| | `RQ_EDRPOU` | 🇺🇦 Украина | ЕДРПОУ | | `RQ_DRFO` | 🇺🇦 Украина | ДРФО | | `RQ_KBE` | 🇰🇿 Казахстан | КБе | | `RQ_IIN` | 🇰🇿 Казахстан | ИИН | | `RQ_BIN` | 🇰🇿 Казахстан | БИН | | `RQ_REGON` | 🇵🇱 Польша | REGON | | `RQ_KRS` | 🇵🇱 Польша | KRS | | `RQ_PESEL` | 🇵🇱 Польша | PESEL | | `RQ_SIRET` | 🇫🇷 Франция | SIRET | | `RQ_SIREN` | 🇫🇷 Франция | SIREN | | `RQ_RCS` | 🇫🇷 Франция | RCS | | `RQ_CAPITAL` | 🇫🇷 Франция | Capital | | `RQ_CNPJ` | 🇧🇷 Бразилия | CNPJ (юрлица) | | `RQ_CPF` | 🇧🇷 Бразилия | CPF (физлица) | | `RQ_LEGAL_FORM` | общее | Форма юрлица | ### Редкие служебные поля `RQ_USRLE`, `RQ_IFNS`, `RQ_COMPANY_ID`, `RQ_IDENT_TYPE`, `RQ_IDENT_DOC_PERS_NUM`, `RQ_ST_CERT_SER/NUM/DATE`, `RQ_VAT_CERT_SER` — используются редкими пресетами, оставлены в исходном регистре. ### Пользовательские поля `UF_CRM_*` — кастомные поля, настроенные на портале (через UI Битрикс24). Возвращаются в ответах в исходном виде. ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "entityTypeId": { "type": "number", "readonly": false }, "presetId": { "type": "number", "readonly": false }, "rqInn": { "type": "string", "readonly": false }, "rqKpp": { "type": "string", "readonly": false }, "rqCompanyName": { "type": "string", "readonly": false }, "rqDirector": { "type": "string", "readonly": false }, "createdAt": { "type": "datetime", "readonly": true }, "createdBy": { "type": "number", "readonly": true }, "RQ_EDRPOU": { "type": "string", "readonly": false, "label": "ЕДРПОУ" }, "RQ_REGON": { "type": "string", "readonly": false, "label": "REGON" }, "UF_CRM_1698325419": { "type": "string", "readonly": false, "label": "Внутренний код" } } } } ``` Показана небольшая часть полей. Реальное количество зависит от портала: 60 полей из Вайбкод-схемы + 30+ международных/служебных + пользовательские. ## Пример ответа при ошибке 401 — нет токенов: ```json { "success": false, "error": { "code": "TOKEN_MISSING", "message": "API key has no OAuth tokens configured" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Все активные пресеты в одном ответе.** Метод возвращает полный список полей со всех активных пресетов портала. **Пустые значения нормализованы.** Для строковых/числовых/date/datetime полей Вайбкод приводит `""` к `null` в ответах `list/get/create/update/search`. На метод `fields` это не влияет — он возвращает только метаданные поля. **Метки (`label`) на языке портала.** У `UPPER_SNAKE_CASE`-полей возвращается `label` с переводом имени на язык портала (для RU-портала — русский, для EN — английский). ## Смотрите также - [Создать реквизит](/docs/entities/requisites/create) — какие поля передавать - [Список реквизитов](/docs/entities/requisites/list) — получение записей - [Entity API](/docs/entity-api) — select для выборки нужных полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: Get ## Получить реквизит `GET /v1/requisites/:id` Возвращает реквизит по ID со всеми полями, которые доступны в его пресете (пресет задаёт набор полей: наименование, ИНН/КПП/ОГРН, директор, бухгалтер и т. д.). ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID реквизита | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/requisites/42" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/requisites/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/42', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Реквизит:', data.rqName, '— ИНН', data.rqInn) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/42', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект реквизита | | `data.id` | number | Идентификатор реквизита | | `data.entityTypeId` | number | Тип родительской сущности: `3` — контакт, `4` — компания | | `data.entityId` | number | ID родительской сущности | | `data.presetId` | number | ID пресета | | `data.name` | string | Название реквизита в интерфейсе | | `data.active` | boolean | Активен ли реквизит | | `data.sort` | number | Порядок сортировки | | `data.createdAt` / `data.updatedAt` | datetime | Даты создания и изменения (ISO 8601) | | `data.createdBy` / `data.modifyBy` | number \| null | ID создателя / последнего редактора | | `data.rqName` / `data.rqInn` / `data.rqKpp` / `data.rqOgrn` | string \| null | Основные реквизиты юрлица | Поля пресета, которые не заполнены, возвращаются как `null`. Полный список всех 60 полей — [Поля реквизита](/docs/entities/requisites/fields). ## Пример ответа ```json { "success": true, "data": { "id": 42, "entityTypeId": 4, "entityId": 15, "presetId": 1, "name": "Основной реквизит", "active": true, "sort": 500, "code": null, "xmlId": null, "addressOnly": false, "createdAt": "2025-01-15T09:30:00+03:00", "updatedAt": "2026-03-20T14:00:00+03:00", "createdBy": 1, "modifyBy": 1, "rqName": "ООО «Ромашка»", "rqInn": "7701234567", "rqKpp": "770101001", "rqOgrn": "1027700123456", "rqOkpo": "12345678", "rqOkved": "62.01", "rqOktmo": null, "rqVatPayer": false, "rqCompanyName": "Ромашка", "rqCompanyFullName": "Общество с ограниченной ответственностью «Ромашка»", "rqDirector": "Иванов Иван Иванович", "rqAccountant": "Петрова Анна Сергеевна", "rqCeoName": null, "rqCeoWorkPos": null, "rqContact": null, "rqEmail": null, "rqPhone": null, "rqBaseDoc": "Устав" } } ``` ## Пример ответа при ошибке 404 — реквизит не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "The Requisite with ID '999999999' is not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Реквизит с таким ID не найден | | 403 | `ACCESS_DENIED` | Нет доступа к родительской сущности (контакту/компании) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Набор полей зависит от пресета.** Реквизит хранит только поля, которые определены в его пресете (`presetId`). Например, у пресета «ООО» будет `rqCompanyName`, `rqCompanyFullName`, `rqDirector`, а у пресета «Физическое лицо» — `rqFirstName`, `rqLastName`, `rqSecondName` и т. д. Поля пресета, которые не заполнены, возвращаются как `null`. **60 популярных полей — camelCase, международные — UPPER_SNAKE_CASE.** Схема Вайбкод покрывает 60 российских и общих полей — они возвращаются в camelCase. Поля пресетов других стран (`RQ_EDRPOU`, `RQ_KBE`, `RQ_REGON`, `RQ_SIRET`, `RQ_CNPJ` и др.) и редкие служебные поля (`RQ_USRLE`, `RQ_IFNS`, `UF_CRM_*`) возвращаются в исходном `UPPER_SNAKE_CASE`. ## Смотрите также - [Поля реквизита](/docs/entities/requisites/fields) — все возможные поля - [Обновить реквизит](/docs/entities/requisites/update) — изменить значения - [Удалить реквизит](/docs/entities/requisites/delete) — удалить запись - [Список реквизитов](/docs/entities/requisites/list) — поиск с фильтрами - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: List ## Список реквизитов `GET /v1/requisites` Возвращает список реквизитов CRM с поддержкой фильтрации, сортировки и авто-пагинации. Реквизиты всегда принадлежат конкретному контакту или компании — почти всегда вам нужен фильтр по `entityTypeId` и `entityId`. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,rqName,rqInn` | | `order` | object | — | Сортировка: `?order[sort]=asc` или `?sort=-id` | | `filter` | object | — | Фильтрация по полям `GET /v1/requisites/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[entityTypeId]=4&filter[entityId]=15` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/requisites?filter[entityTypeId]=4&filter[entityId]=15" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/requisites?filter[entityTypeId]=4&filter[entityId]=15" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites?filter[entityTypeId]=4&filter[entityId]=15', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} реквизитов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites?filter[entityTypeId]=4&filter[entityId]=15', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив реквизитов (все поля — см. [Поля реквизита](/docs/entities/requisites/fields)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами limit | ## Пример ответа ```json { "success": true, "data": [ { "id": 42, "entityTypeId": 4, "entityId": 15, "presetId": 1, "name": "Основной реквизит", "active": true, "sort": 500, "code": null, "xmlId": null, "addressOnly": false, "createdAt": "2025-01-15T09:30:00+03:00", "updatedAt": "2026-03-20T14:00:00+03:00", "createdBy": 1, "modifyBy": 1, "rqName": "ООО «Ромашка»", "rqInn": "7701234567", "rqKpp": "770101001", "rqOgrn": "1027700123456", "rqOkpo": "12345678", "rqOkved": "62.01", "rqCompanyName": "Ромашка", "rqCompanyFullName": "Общество с ограниченной ответственностью «Ромашка»", "rqDirector": "Иванов Иван Иванович", "rqAccountant": "Петрова Анна Сергеевна", "rqVatPayer": false } ], "meta": { "total": 1, "hasMore": false } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "Requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_FILTER` | Ошибка в синтаксисе фильтра | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **60 популярных полей — camelCase, международные — UPPER_SNAKE_CASE.** В схеме описаны 60 самых ходовых полей (российские и общие) — они возвращаются в camelCase, фильтруются и сортируются по camelCase-имени. Поля пресетов других стран (`RQ_EDRPOU`/Украина, `RQ_KBE`/Казахстан, `RQ_REGON`/Польша, `RQ_SIRET`/Франция, `RQ_CNPJ`/Бразилия) и неописанные служебные поля возвращаются в `UPPER_SNAKE_CASE` — для фильтра по ним тоже используйте исходное имя. **Пустые значения нормализованы.** Битрикс24 возвращает `""` для очищенных полей и `null` для никогда не заполненных. Вайбкод приводит их к `null` для string/number/date/datetime типов — клиенту достаточно проверки `if (v)` без дополнительных условий. **Фильтр обычно обязателен.** В портале могут быть десятки тысяч реквизитов. Для получения реквизитов конкретной компании или контакта всегда передавайте `entityTypeId` + `entityId`. **Коды `entityTypeId`:** `3` — контакт, `4` — компания. Для смарт-процессов и других сущностей CRM реквизиты не поддерживаются на уровне Битрикс24. **Авто-пагинация.** При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 и возвращает все записи в одном ответе. **Ограничение offset.** При `offset ≥ 2500` Битрикс24 может вернуть `INTERNAL_ERROR`. Используйте `limit ≤ 500` при больших offset. ## Смотрите также - [Получить реквизит](/docs/entities/requisites/get) — получение одной записи по ID - [Поиск реквизитов](/docs/entities/requisites/search) — POST-запрос для сложных фильтров - [Поля реквизита](/docs/entities/requisites/fields) — полный список полей - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: Search ## Поиск реквизитов `POST /v1/requisites/search` Поиск реквизитов с фильтрами и авто-пагинацией. Аналогичен `GET /v1/requisites`, но параметры передаются в теле запроса — удобнее для сложных фильтров с большим количеством условий и для программной сборки запросов. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/requisites/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `{ "entityTypeId": 4, "entityId": 15 }` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "sort": "asc" }` | | `select` | string[] | — | Выборка полей: `["id", "rqName", "rqInn"]` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/requisites/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "entityTypeId": 4, "active": true }, "limit": 20, "order": { "sort": "asc" } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/requisites/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "entityTypeId": 4, "active": true }, "limit": 20, "order": { "sort": "asc" } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { entityTypeId: 4, active: true }, limit: 20, order: { sort: 'asc' }, }), }) const { success, data } = await res.json() console.log('Найдено:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { entityTypeId: 4, active: true }, limit: 20, order: { sort: 'asc' }, }), }) const { success, data } = await res.json() ``` ### Другие сценарии Поиск по ИНН: ```json { "filter": { "rqInn": "7701234567" } } ``` Поиск по полю вне схемы (французский SIRET): ```json { "filter": { "RQ_SIRET": "73282932000074" } } ``` Международные поля (`RQ_SIRET`, `RQ_SIREN`, `RQ_REGON`, `RQ_KBE`, `RQ_CNPJ`) не входят в Вайбкод-схему — используйте их исходные `UPPER_SNAKE_CASE`-имена. Все реквизиты одной компании: ```json { "filter": { "entityTypeId": 4, "entityId": 15 }, "order": { "sort": "asc" } } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив реквизитов (все поля — см. [Поля реквизита](/docs/entities/requisites/fields)) | ## Пример ответа ```json { "success": true, "data": [ { "id": 42, "entityTypeId": 4, "entityId": 15, "presetId": 1, "name": "Основной реквизит", "active": true, "sort": 500, "rqName": "ООО «Ромашка»", "rqInn": "7701234567", "rqKpp": "770101001", "rqOgrn": "1027700123456", "rqCompanyName": "Ромашка", "rqDirector": "Иванов Иван Иванович", "createdAt": "2025-01-15T09:30:00+03:00" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "Requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 400 | `INVALID_FILTER` | Ошибка в синтаксисе фильтра | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Имена полей в фильтре.** 60 полей из Вайбкод-схемы передавайте в camelCase (`rqInn`, `rqKpp`, `entityTypeId`, `rqCompanyName`, `rqDirector`, `rqOkpo`). Поля международных пресетов (`RQ_EDRPOU`, `RQ_KBE`, `RQ_REGON`, `RQ_SIRET`, `RQ_CNPJ`) и редкие служебные (`RQ_USRLE`, `RQ_IFNS`, `UF_CRM_*`) — в `UPPER_SNAKE_CASE`. **Пагинация.** При `limit > 50` запрос автоматически разбивается на несколько вызовов к Битрикс24. Для больших выборок используйте `offset` и постраничные запросы. ## Смотрите также - [Список реквизитов](/docs/entities/requisites/list) — GET-запрос с query-параметрами - [Поля реквизита](/docs/entities/requisites/fields) — какие поля есть в фильтре - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Requisites: Update ## Обновить реквизит `PATCH /v1/requisites/:id` Обновляет поля существующего реквизита. Передавайте только те поля, которые нужно изменить. Полный список — [`GET /v1/requisites/fields`](/docs/entities/requisites/fields). ## Часто обновляемые поля | Параметр | Тип | Описание | |----------|-----|---------| | `name` | string | Название реквизита в интерфейсе Битрикс24 | | `active` | boolean | Активен ли реквизит | | `sort` | number | Порядок сортировки | | `rqName` | string | Полное наименование | | `rqInn` | string | ИНН | | `rqKpp` | string | КПП | | `rqOgrn` | string | ОГРН | | `rqCompanyName` | string | Сокращённое название юрлица | | `rqDirector` | string | ФИО директора | | `rqAccountant` | string | ФИО главного бухгалтера | | `rqVatPayer` | boolean | Плательщик НДС | Все поля в camelCase. Международные поля (`RQ_EDRPOU`, `RQ_KBE`, `RQ_REGON`, `RQ_SIRET`, `RQ_CNPJ`) передаются в `UPPER_SNAKE_CASE` — они не включены в Вайбкод-схему. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID реквизита | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/requisites/42" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "rqInn": "7701234567", "rqKpp": "770101001", "rqDirector": "Иванов Иван Иванович" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/requisites/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "rqInn": "7701234567", "rqKpp": "770101001" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ rqInn: '7701234567', rqKpp: '770101001', rqDirector: 'Иванов Иван Иванович', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/requisites/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ rqInn: '7701234567', rqKpp: '770101001', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Обновлённый реквизит с актуальными значениями полей | | `data.id` | number | Идентификатор реквизита | | `data.updatedAt` | datetime | Новая дата изменения | | `data.modifyBy` | number | ID пользователя, выполнившего обновление | Объект содержит все поля пресета в camelCase — включая неизменённые. Незаполненные поля — `null`. Полный список — [Поля реквизита](/docs/entities/requisites/fields). ## Пример ответа ```json { "success": true, "data": { "id": 42, "entityTypeId": 4, "entityId": 15, "presetId": 1, "name": "Основной реквизит", "active": true, "sort": 500, "rqName": "ООО «Ромашка»", "rqInn": "7701234567", "rqKpp": "770101001", "rqOgrn": "1027700123456", "rqDirector": "Иванов Иван Иванович", "updatedAt": "2026-04-19T15:00:00+03:00", "modifyBy": 1 } } ``` ## Пример ответа при ошибке 404 — реквизит не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "The Requisite with ID '999999999' is not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Реквизит с таким ID не найден | | 403 | `ACCESS_DENIED` | Нет доступа к родительской сущности | | 400 | `INVALID_REQUEST` | Невалидные поля | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Сменить пресет нельзя.** Поле `presetId` задаётся при создании и его нельзя изменить обновлением. Если нужен другой пресет — создайте новый реквизит и удалите старый. **Перенос между сущностями невозможен.** `entityTypeId` и `entityId` также неизменяемы: реквизит привязан к конкретному контакту или компании на всю жизнь. **Поля вне пресета игнорируются.** Битрикс24 молча отбрасывает значения полей, которых нет в пресете реквизита. Ошибка не возникает, но и данные не сохраняются. Проверить результат — `GET /v1/requisites/:id`. **Пустое значение очищает поле.** Чтобы очистить поле, передайте пустую строку `""`. В ответах Вайбкод приводит очищенные строки к `null` для консистентности. ## Смотрите также - [Получить реквизит](/docs/entities/requisites/get) — текущие значения - [Поля реквизита](/docs/entities/requisites/fields) — какие поля можно изменять - [Удалить реквизит](/docs/entities/requisites/delete) — удалить запись - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Sites: Aggregate ## Агрегация сайтов `POST /v1/sites/aggregate` Подсчёт количества сайтов с учётом фильтра. Поддерживает функцию `count`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Для сайтов поддерживается только `{ "field": "*", "function": "count" }` — другие функции вернут пустой `aggregates` (нет числовых полей в `aggregatable`). Без параметра — `count` записей с учётом фильтра | | `filter` | object | нет | Фильтрация по ключевым полям сайта.
[Синтаксис фильтрации](/docs/filtering) | | `scope` | string | нет | Внутренняя область лендингов: `KNOWLEDGE` / `GROUP` / `MAINPAGE`. Без параметра подсчитываются обычные сайты-лендинги | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/sites/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "type": "PAGE", "active": true } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/sites/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "type": "PAGE", "active": true } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { type: 'PAGE', active: true }, }), }) const { success, data } = await res.json() console.log('Активных лендингов:', data.count) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { type: 'PAGE', active: true }, }), }) const { success, data } = await res.json() ``` ## Другие сценарии Общее количество сайтов в портале — самый быстрый запрос, без выгрузки записей: ```json {} ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Количество сайтов, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций. Для сайтов остаётся пустым: схема сущности не объявляет числовых полей в `aggregatable` | | `data.meta.totalRecords` | number | Общее количество записей | | `data.meta.recordsProcessed` | number | Количество обработанных записей | | `data.meta.truncated` | boolean | Был ли результат ограничен (`true` при более 5000 записей) | ## Пример ответа ```json { "success": true, "data": { "count": 18, "aggregates": {}, "meta": { "totalRecords": 18, "recordsProcessed": 18, "truncated": false } } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'landing' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Невалидное имя функции агрегации или несуществующее поле | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Видимость по правам пользователя.** В подсчёт попадают только те сайты, к которым у владельца API-ключа есть право «просмотр». Если ожидается ненулевой результат, но `count` равен нулю — проверьте права пользователя, под которым выпущен ключ. ## Смотрите также - [Список сайтов](/docs/entities/sites/list) — `total` в ответе даёт точное число записей - [Поиск сайтов](/docs/entities/sites/search) — POST-запрос с фильтрами - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Sites: Create ## Создать сайт `POST /v1/sites` Создаёт новый сайт на портале. Тип сайта определяется полем `type`. Поля передаются плоско в корне JSON — без обёртки `fields`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `title` | string | да | Название сайта, до 255 символов | | `type` | string | нет | Тип сайта: `PAGE` (лендинг, по умолчанию) или `STORE` (интернет-магазин) | | `code` | string | нет | Символьный код сайта в URL. Если оставить пустым или не передать — генерируется из `title`. Если код состоит только из цифр, добавляется префикс `site`. Если код уже занят на домене — добавляется числовой суффикс (`code2`, `code3`) | | `domainId` | number | нет | Идентификатор домена. Если не передавать — адрес сгенерируется автоматически | | `active` | boolean | нет | Активен ли сайт. По умолчанию `true` | | `description` | string | нет | Описание сайта, до 255 символов | | `xmlId` | string | нет | Внешний идентификатор, до 255 символов | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/sites" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Лендинг конференции", "code": "conf-2026", "type": "PAGE" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/sites" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Лендинг конференции", "code": "conf-2026", "type": "PAGE" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Лендинг конференции', code: 'conf-2026', type: 'PAGE', }), }) const { success, data } = await res.json() console.log('Site ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Лендинг конференции', code: 'conf-2026', type: 'PAGE', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданного сайта. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор созданного сайта | | `title` | string | Название сайта | | `code` | string | Фактический символьный код (с авто-суффиксом, если код запроса был занят) | | `type` | string | Тип сайта | | `active` | boolean | Активен ли сайт | | `domainId` | number | Идентификатор домена (выданного автоматически или переданного) | | `createdById` | number | Идентификатор создавшего пользователя | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | URL сайта в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/sites/site// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 173, "title": "Лендинг конференции", "code": "/conf-2026/", "type": "PAGE", "active": true, "domainId": 28, "createdById": 1, "dateCreate": "2026-05-07T12:14:08.000Z", "dateModify": "2026-05-07T12:14:08.000Z" } } ``` ## Пример ответа при ошибке 400 — некорректный код сайта: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Адрес сайта введен неверно. Вы можете использовать только следующие символы: \"a-z\", \"0-9\", \"-\", \".\"." } } ``` ## Ошибки | HTTP | `error.code` | Маркер в `error.message` | Описание | |------|--------------|--------------------------|---------| | 400 | `BITRIX_ERROR` | `SLASH_IS_NOT_ALLOWED` | В `code` передан символ `/` — слеши в коде запрещены | | 400 | `BITRIX_ERROR` | `DOMAIN_IS_INCORRECT` | Адрес сайта введён неверно: разрешены только символы `a-z`, `0-9`, `-`, `.` | | 400 | `BITRIX_ERROR` | `DOMAIN_EXIST` | Указанный домен уже занят другим сайтом | | 400 | `BITRIX_ERROR` | `DOMAIN_EXIST_TRASH` | Домен привязан к сайту в корзине — сначала отвяжите его | | 400 | `BITRIX_ERROR` | `DOMAIN_NOT_FOUND` | Домен с указанным `domainId` не существует | | 400 | `BITRIX_ERROR` | `SITE_LIMIT_REACHED` | Достигнут лимит количества сайтов на текущем тарифе | | 403 | `BITRIX_ACCESS_DENIED` | — | У пользователя нет права на создание сайтов | | 403 | `SCOPE_DENIED` | — | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | — | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Слеши в ответе.** Поле `code` в ответе возвращается с обрамляющими слешами (`/conf-2026/`) — это представление пути сайта в URL. В запросе слеши передавать нельзя. **Адрес по умолчанию.** Если `domainId` не передавать, для сайта будет сгенерирован адрес на `bitrix24site.ru` (например, `b24-xxxxx.bitrix24site.ru`). **Главная страница и страницы ошибок.** Поля `landingIdIndex`, `landingId404`, `landingId503` при создании не задаются — страниц ещё нет. Назначьте их через [обновление](/docs/entities/sites/update) после создания страниц сайта. ## Смотрите также - [Список сайтов](/docs/entities/sites/list) — посмотреть существующие сайты перед созданием - [Обновить сайт](/docs/entities/sites/update) — изменить параметры созданного сайта - [Удалить сайт](/docs/entities/sites/delete) — удалить пустой сайт - [Batch](/docs/batch) — массовое создание - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Sites: Delete ## Удалить сайт `DELETE /v1/sites/:id` Удаляет сайт по идентификатору. **Удалить можно только пустой сайт** — без страниц (включая страницы в корзине). Если на сайте есть хотя бы одна страница, запрос вернёт ошибку. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор сайта | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/sites/173" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/sites/173" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/173', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Сайт удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/173', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Сайт удалён') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 400 — на сайте есть страницы: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Сайт содержит страницы." } } ``` ## Ошибки | HTTP | `error.code` | Маркер в `error.message` | Описание | |------|--------------|--------------------------|---------| | 400 | `BITRIX_ERROR` | `SITE_IS_NOT_EMPTY` | На сайте есть страницы (включая страницы в корзине) | | 400 | `BITRIX_ERROR` | `SITE_IS_LOCK` | Сайт заблокирован на удаление | | 403 | `BITRIX_ACCESS_DENIED` | — | У пользователя нет права на удаление этого сайта | | 403 | `BITRIX_ACCESS_DENIED` | `ACCESS_DENIED_DELETED` | На портале подключён доменный провайдер — удаление сайта через API недоступно, удалите через интерфейс портала | | 404 | `ENTITY_NOT_FOUND` | — | Сайт с таким ID не найден | | 403 | `SCOPE_DENIED` | — | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | — | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Корзина не освобождает сайт.** Сайт нельзя удалить, пока на нём остаются страницы в корзине, — сначала очистите корзину страниц. ## Смотрите также - [Список страниц сайта](/docs/entities/pages) — `GET /v1/pages?filter[siteId]=:id` перед удалением сайта - [Список сайтов](/docs/entities/sites/list) — найти ID нужного сайта - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Sites: Get ## Получить сайт `GET /v1/sites/:id` Возвращает один сайт по идентификатору. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор сайта | | `scope` (query) | string | нет | Внутренняя область лендингов: `KNOWLEDGE` / `GROUP` / `MAINPAGE`. Указывайте, если сайт принадлежит соответствующей области; иначе возвращается `404 ENTITY_NOT_FOUND`. Пример: `GET /v1/sites/42?scope=KNOWLEDGE` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/sites/157" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/sites/157" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/157', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Сайт:', data.title, '—', data.type) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/157', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект сайта со всеми полями — см. [Поля](/docs/entities/sites#поля). ## Пример ответа ```json { "success": true, "data": { "id": 157, "title": "Вилла Ранду", "code": "/villa-randu/", "type": "PAGE", "active": true, "domainId": 5, "createdById": 1, "dateCreate": "2024-09-12T10:23:14.000Z", "dateModify": "2025-11-04T08:51:20.000Z" } } ``` ## Пример ответа при ошибке 404 — сайт не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Сайт с таким ID не найден или недоступен пользователю | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список сайтов](/docs/entities/sites/list) — получить несколько сайтов с фильтрами - [Обновить сайт](/docs/entities/sites/update) — изменение полей - [Удалить сайт](/docs/entities/sites/delete) — удаление по ID - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Sites: List ## Список сайтов `GET /v1/sites` Возвращает список сайтов портала с поддержкой фильтрации и авто-пагинации. По умолчанию возвращаются только не удалённые сайты — для получения сайтов из корзины передайте `filter[deleted]=Y`. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `select` | string | — | Выборка полей: `?select=id,title,type` | | `filter` | object | — | Фильтрация по ключевым полям сайта.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[type]=PAGE` | | `scope` | string | — | Внутренняя область лендингов. Допустимые значения: `KNOWLEDGE` (база знаний), `GROUP` (страницы рабочих групп), `MAINPAGE` (главные страницы). Без параметра возвращаются обычные сайты-лендинги. Принимается как `?scope=KNOWLEDGE` или `?filter[scope]=KNOWLEDGE` — обе формы дают одинаковый запрос к Битрикс24 | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/sites?limit=10&filter[type]=PAGE" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/sites?limit=10&filter[type]=PAGE" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites?limit=10&filter[type]=PAGE', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} сайтов`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites?limit=10&filter[type]=PAGE', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив сайтов (каждая запись содержит ключевые поля сайта) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | URL любого сайта из массива `data` — его `id`: ``` https://.bitrix24.ru/sites/site// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 157, "title": "Вилла Ранду", "code": "/villa-randu/", "type": "PAGE", "active": true, "domainId": 5, "createdById": 1, "dateCreate": "2024-09-12T10:23:14.000Z", "dateModify": "2025-11-04T08:51:20.000Z" }, { "id": 3, "title": "Музей вилок", "code": "/fotografiya/", "type": "PAGE", "active": true, "domainId": 5, "createdById": 1, "dateCreate": "2020-04-22T14:39:17.000Z", "dateModify": "2024-05-06T15:43:34.000Z" } ], "meta": { "total": 25, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'landing' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Видимость по правам пользователя.** В список попадают только сайты, к которым у владельца API-ключа есть право «просмотр». Если на портале есть сайты, но ответ пустой — проверьте права пользователя, под которым выпущен ключ. **Корзина.** Чтобы получить удалённые сайты, передайте `filter[deleted]=Y` (значения `"Y"` / `"N"`). **Сортировка не применяется.** Параметр `order` принимается без ошибки, но порядок результата не меняется — выборка всегда возвращается в порядке возрастания идентификатора. **База знаний и другие внутренние области.** Параметр `scope` переключает источник: `KNOWLEDGE` — сайты базы знаний, `GROUP` — сайты внутри рабочих групп, `MAINPAGE` — главные страницы. Без параметра возвращаются обычные сайты-лендинги (источник по умолчанию). Пример: `GET /v1/sites?scope=KNOWLEDGE` возвращает сайты базы знаний и игнорирует обычные лендинги. ## Смотрите также - [Получить сайт](/docs/entities/sites/get) — данные одного сайта по ID - [Поиск сайтов](/docs/entities/sites/search) — POST-запрос для сложных фильтров - [Создать сайт](/docs/entities/sites/create) — создание нового - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, order, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Sites: Search ## Поиск сайтов `POST /v1/sites/search` Поиск сайтов с фильтрацией и авто-пагинацией. Аналогичен `GET /v1/sites` с фильтрами, но через POST — удобнее для сложных запросов с большим количеством условий. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по ключевым полям сайта.
[Синтаксис фильтрации](/docs/filtering) | | `limit` | number | `50` | Количество записей (до 5000) | | `select` | string[] | — | Выборка полей: `["id", "title", "type"]` | | `scope` | string | — | Внутренняя область лендингов: `KNOWLEDGE` / `GROUP` / `MAINPAGE`. Без параметра возвращаются обычные сайты-лендинги. Принимается на верхнем уровне тела (`"scope": "KNOWLEDGE"`) или внутри `filter.scope` — обе формы лифтятся в одинаковый запрос к Битрикс24 | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/sites/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "type": "PAGE", "active": true }, "limit": 10, "select": ["id", "title", "type", "active"] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/sites/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "type": "PAGE", "active": true }, "limit": 10, "select": ["id", "title", "type", "active"] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { type: 'PAGE', active: true }, limit: 10, select: ['id', 'title', 'type', 'active'], }), }) const { success, data, meta } = await res.json() console.log('Найдено:', meta.total) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { type: 'PAGE', active: true }, limit: 10, select: ['id', 'title', 'type', 'active'], }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив сайтов с ключевыми полями | URL любого сайта из массива `data` — его `id`: ``` https://.bitrix24.ru/sites/site// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 157, "title": "Вилла Ранду", "code": "/villa-randu/", "type": "PAGE", "active": true, "domainId": 5, "createdById": 1, "dateCreate": "2024-09-12T10:23:14.000Z", "dateModify": "2025-11-04T08:51:20.000Z" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'landing' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Видимость по правам пользователя.** Поиск возвращает только те сайты, к которым у владельца API-ключа есть право «просмотр». Если ожидается результат, но `data` пустой — проверьте права пользователя. **Удалённые сайты.** По умолчанию исключаются. Чтобы включить их в результат, передайте `{"filter": {"deleted": "Y"}}` (значения `"Y"` / `"N"`). **Сортировка не применяется.** Параметр `order` принимается без ошибки, но порядок результата не меняется — выборка всегда возвращается в порядке возрастания идентификатора. ## Смотрите также - [Список сайтов](/docs/entities/sites/list) — GET-запрос с query-параметрами (для простых фильтров) - [Получить сайт](/docs/entities/sites/get) — данные одного сайта по ID - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение нескольких search в один запрос - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Sites: Update ## Обновить сайт `PATCH /v1/sites/:id` Обновляет поля существующего сайта. Передавайте только изменяемые поля плоско в корне JSON — без обёртки `fields`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | Идентификатор сайта | ## Поля для обновления (body) | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название сайта, до 255 символов | | `code` | string | Символьный код сайта в URL. Слеши запрещены. Если код состоит только из цифр, добавится префикс `site` | | `active` | boolean | Активен ли сайт | | `domainId` | number | Идентификатор домена | | `type` | string | Тип сайта: `PAGE` или `STORE` | | `description` | string | Описание сайта, до 255 символов | | `xmlId` | string | Внешний идентификатор, до 255 символов | | `landingIdIndex` | number | Идентификатор главной страницы сайта | | `landingId404` | number | Идентификатор страницы ошибки 404 | | `landingId503` | number | Идентификатор страницы ошибки 503 | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/sites/157" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Вилла Ранду — обновлено", "active": false }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/sites/157" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Вилла Ранду — обновлено", "active": false }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/157', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Вилла Ранду — обновлено', active: false, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/sites/157', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Вилла Ранду — обновлено', active: false, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект сайта со всеми ключевыми полями | ## Пример ответа ```json { "success": true, "data": { "id": 157, "title": "Вилла Ранду — обновлено", "code": "/villa-randu/", "type": "PAGE", "active": false, "domainId": 5, "createdById": 1, "dateCreate": "2024-09-12T10:23:14.000Z", "dateModify": "2026-05-07T12:18:42.000Z" } } ``` ## Пример ответа при ошибке 403 — нет прав на обновление этого сайта: ```json { "success": false, "error": { "code": "BITRIX_ACCESS_DENIED", "message": "Access denied" } } ``` ## Ошибки | HTTP | `error.code` | Маркер в `error.message` | Описание | |------|--------------|--------------------------|---------| | 404 | `ENTITY_NOT_FOUND` | — | Сайт с таким ID не найден | | 403 | `BITRIX_ACCESS_DENIED` | — | У пользователя нет права на изменение этого сайта или указанных полей | | 400 | `BITRIX_ERROR` | `SLASH_IS_NOT_ALLOWED` | В `code` передан символ `/` — слеши в коде запрещены | | 400 | `BITRIX_ERROR` | `DOMAIN_IS_INCORRECT` | Передан некорректный формат доменного имени | | 400 | `BITRIX_ERROR` | `DOMAIN_EXIST` | Указанный домен уже занят другим сайтом | | 400 | `BITRIX_ERROR` | `DOMAIN_EXIST_TRASH` | Домен привязан к сайту в корзине — сначала отвяжите его | | 400 | `BITRIX_ERROR` | `DOMAIN_NOT_FOUND` | Домен с указанным `domainId` не существует | | 400 | `BITRIX_ERROR` | `CODE_IS_NOT_UNIQUE` | Код сайта не уникален в рамках домена | | 403 | `SCOPE_DENIED` | — | API-ключ не имеет скоупа `landing` | | 401 | `TOKEN_MISSING` | — | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить сайт](/docs/entities/sites/get) — текущие значения полей - [Список сайтов](/docs/entities/sites/list) — найти сайт по фильтру - [Удалить сайт](/docs/entities/sites/delete) — удаление пустого сайта - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Smart Processes: Create ## Создать тип смарт-процесса `POST /v1/smart-processes` Создаёт новый тип смарт-процесса с автоматически назначенным `entityTypeId`. После создания тип доступен в `/v1/items/:entityTypeId` для CRUD операций по элементам. ## Поля запроса (body) | Поле | Тип | Обяз. | По умолч. | Описание | |------|-----|:-----:|:---------:|---------| | `title` | string | **да** | — | Название смарт-процесса | | `isCategoriesEnabled` | boolean | | `false` | Использовать в смарт-процессе свои воронки и туннели продаж | | `isStagesEnabled` | boolean | | `false` | Использовать в смарт-процессе свои стадии и канбан | | `isBeginCloseDatesEnabled` | boolean | | `false` | Поля «Дата начала» и «Дата завершения» | | `isClientEnabled` | boolean | | `false` | Поле «Клиент» с привязкой к контактам и компаниям | | `isLinkWithProductsEnabled` | boolean | | `false` | Привязка товаров каталога | | `isMycompanyEnabled` | boolean | | `false` | Поле «Реквизиты вашей компании» | | `isObserversEnabled` | boolean | | `false` | Поле «Наблюдатели» | | `isSourceEnabled` | boolean | | `false` | Поля «Источник» и «Дополнительно об источнике» | | `isAutomationEnabled` | boolean | | `false` | Роботы и триггеры | | `isBizProcEnabled` | boolean | | `false` | Дизайнер бизнес-процессов | | `isDocumentsEnabled` | boolean | | `false` | Печать документов | | `isRecyclebinEnabled` | boolean | | `false` | Использование корзины | | `isSetOpenPermissions` | boolean | | **`true`** | Делать новые воронки доступными для всех | | `isUseInUserfieldEnabled` | boolean | | `false` | Использовать смарт-процесс в пользовательском поле | | `isRecurringEnabled` | boolean | | `false` | Поле «Регулярность» | | `isPaymentsEnabled` | boolean | | `false` | Онлайн-оплата | | `isCountersEnabled` | boolean | | `false` | Счётчики (уведомления и бейджи) | | `relations` | object | | `{}` | Связи с другими сущностями CRM — см. «Связи и пользовательские поля» ниже | | `linkedUserFields` | object | | `{}` | Набор пользовательских полей, в которых будет отображаться смарт-процесс — см. «Связи и пользовательские поля» ниже | Полный список полей: [GET /v1/smart-processes/fields](/docs/entities/smart-processes/fields). ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/smart-processes \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Договоры поставки", "isStagesEnabled": true, "isCategoriesEnabled": true, "isAutomationEnabled": true, "isBizProcEnabled": true, "isLinkWithProductsEnabled": true }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/smart-processes \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Договоры поставки", "isStagesEnabled": true, "isCategoriesEnabled": true, "isAutomationEnabled": true, "isBizProcEnabled": true, "isLinkWithProductsEnabled": true }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Договоры поставки', isStagesEnabled: true, isCategoriesEnabled: true, isAutomationEnabled: true, isBizProcEnabled: true, isLinkWithProductsEnabled: true, }), }) const { success, data } = await res.json() console.log('Создан тип, entityTypeId:', data.entityTypeId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Договоры поставки', isStagesEnabled: true, isCategoriesEnabled: true, isAutomationEnabled: true, isBizProcEnabled: true, isLinkWithProductsEnabled: true, }), }) const { success, data } = await res.json() ``` ## Связи и пользовательские поля Поля `relations` и `linkedUserFields` не описаны в `/fields`, но принимаются при создании и сохраняются Битрикс24. ### `relations` — связи с сущностями CRM Объект с двумя массивами: `parent` (родительские типы) и `child` (дочерние типы). ```json { "title": "Договоры поставки", "relations": { "parent": [ { "entityTypeId": 2, "isChildrenListEnabled": "Y" } ], "child": [ { "entityTypeId": 3, "isChildrenListEnabled": "Y" } ] } } ``` | Поле записи | Тип | Описание | |---|---|---| | `entityTypeId` | number | ID связанного типа (2 = сделки, 3 = контакты, 4 = компании, 7 = коммерческие предложения, 31 = счета, 1030+ = смарт-процессы) | | `isChildrenListEnabled` | string (`"Y"`/`"N"`) | Отображать ли список записей этого смарт-процесса в карточке связанного типа | **Побочный эффект от `isClientEnabled: true`:** Битрикс24 автоматически добавит в `relations.parent` связи с контактами (`entityTypeId: 3`) и компаниями (`entityTypeId: 4`) с флагом `isPredefined: "Y"` — передавать их вручную не нужно. ### `linkedUserFields` — отображение в пользовательских полях Объект, где ключ — идентификатор поля из другой сущности в формате `{ENTITY_CODE}|{FIELD_NAME}`, значение — `"Y"` (включить отображение) или `"N"` (выключить). ```json { "title": "Договоры поставки", "linkedUserFields": { "TASKS_TASK|UF_CRM_TASK": "Y", "TASKS_TASK_TEMPLATE|UF_CRM_TASK": "Y", "CALENDAR_EVENT|UF_CRM_CAL_EVENT": "Y" } } ``` Поддерживаются 3 фиксированных ключа: | Ключ | Где отобразится смарт-процесс | |------|------------------------------| | `TASKS_TASK\|UF_CRM_TASK` | Поле «Элемент CRM» в задачах | | `TASKS_TASK_TEMPLATE\|UF_CRM_TASK` | Поле «Элемент CRM» в шаблонах задач | | `CALENDAR_EVENT\|UF_CRM_CAL_EVENT` | Поле «Элемент CRM» в событиях календаря | ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Внутренний ID записи типа | | `entityTypeId` | number | **Назначенный `entityTypeId`** — используется в `/v1/items/:entityTypeId` | | `title` | string | Название | | `createdBy` | number | Создатель | | `createdTime` | datetime | Дата создания | | `updatedTime` | datetime | Дата изменения | | `customSectionId` | number \| null | ID цифрового рабочего места (если привязан) | Плюс все `isXxxEnabled` флаги в том состоянии, которое было передано (или `false` по умолчанию). Полный список — [Поля типа](/docs/entities/smart-processes/fields). Список элементов созданного типа открывается в Битрикс24 по `entityTypeId`: ``` https://.bitrix24.ru/crm/type//list/category/0/ ``` `0` — основная воронка. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 31, "entityTypeId": 1050, "title": "Договоры поставки", "createdBy": 1, "createdTime": "2026-04-21T13:46:45+03:00", "updatedTime": "2026-04-21T13:46:45+03:00", "updatedBy": 1, "customSectionId": null, "isCategoriesEnabled": true, "isStagesEnabled": true, "isBeginCloseDatesEnabled": false, "isClientEnabled": false, "isLinkWithProductsEnabled": true, "isMycompanyEnabled": false, "isObserversEnabled": false, "isSourceEnabled": false, "isAutomationEnabled": true, "isBizProcEnabled": true, "isDocumentsEnabled": false, "isRecyclebinEnabled": false, "isSetOpenPermissions": true, "isUseInUserfieldEnabled": false, "isRecurringEnabled": false, "isPaymentsEnabled": false, "isCountersEnabled": false, "isInitialized": false } } ``` ## Пример ответа при ошибке 422 — не передано обязательное поле: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Не заполнено обязательное поле \"Название\"" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `INVALID_API_KEY` | Ключ не найден или отозван | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 422 | `BITRIX_ERROR` | Любая ошибка от Битрикс24: не передано `title`, `entityTypeId` вне диапазона, превышен лимит смарт-процессов на портале и т. д. Конкретная причина — в поле `message` | Типичные сообщения в `message` при `BITRIX_ERROR`: - `Не заполнено обязательное поле "Название"` — пропущен `title` - `EntityTypeId should be more or equal than 128 and less than 192` — передан `entityTypeId` вне диапазона - `Превышено максимальное количество смарт-процессов` — достигнут лимит портала Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Авто-генерация `entityTypeId`.** Битрикс24 сам назначает свободный идентификатор. Если вы хотите передать собственный, значение должно быть **уникальным** и попадать в один из диапазонов: `128-192` включительно, либо чётное число `≥ 1030`. Значение возвращается в поле `entityTypeId` ответа — сохраните его и используйте во всех запросах к типу и его элементам. **После создания `isInitialized: false`.** Битрикс24 ещё не сгенерировал стандартные стадии и воронки. Они создаются при первом обращении к типу в интерфейсе или программно — через `/v1/statuses` и `/v1/categories/:entityTypeId`. **`relations` двунаправленные.** Если вы указали `parent: [{entityTypeId: 2, ...}]`, то в сделках (тип 2) в поле `relations.child` автоматически появится ссылка на ваш новый тип с флагом `isPredefined: "N"` (пользовательская связь). **`isSetOpenPermissions` по умолчанию `true`** — это единственный флаг с положительным дефолтом. Если нужны приватные воронки, передавайте `false` явно. ## Смотрите также - [Обновить тип](/docs/entities/smart-processes/update) — частичное обновление полей - [Удалить тип](/docs/entities/smart-processes/delete) - [Список типов](/docs/entities/smart-processes/list) — все типы на портале - [Поля типа](/docs/entities/smart-processes/fields) — полный список полей - [Элементы смарт-процессов](/docs/entities/items) — CRUD по элементам созданного типа - [Стадии и воронки](/docs/entities/categories) — настройка после создания - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Smart Processes: Delete ## Удалить тип смарт-процесса `DELETE /v1/smart-processes/:entityTypeId` Удаляет тип смарт-процесса по `entityTypeId`. Вместе с типом удаляются все связанные с ним метаданные: воронки, стадии, права доступа, настройки бизнес-процессов. **Удалить можно только тип, у которого нет элементов.** Если в типе есть хотя бы один элемент — сначала удалите элементы через `DELETE /v1/items/:entityTypeId/:id` или перенесите их в другой тип. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` (path) | number | **да** | ID типа сущности. Список: `GET /v1/smart-processes` | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/smart-processes/1050" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/smart-processes/1050" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/1050', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Тип удалён') } else { const { error } = await res.json() console.error('Ошибка:', error.code, error.message) } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/1050', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Тип удалён') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — тип не найден: ```json { "success": false, "error": { "code": "SMART_PROCESS_NOT_FOUND", "message": "Smart process with entityTypeId=99999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `INVALID_API_KEY` | Ключ не найден или отозван | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 404 | `SMART_PROCESS_NOT_FOUND` | Тип с таким `entityTypeId` не найден. Сообщение: `Smart process with entityTypeId=X not found` | | 422 | `BITRIX_ERROR` | В типе есть элементы (сообщение: `Вы не можете удалить тип сущности, у которого есть элементы`) или другая ошибка от Битрикс24 | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Удаление необратимо.** Нет корзины и отката — удалённый тип восстановить нельзя. Связанные метаданные (воронки, стадии, права) удаляются вместе с типом. **Перед удалением проверьте количество элементов.** Если есть сомнения, получите количество: ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/items/1050/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"count": true}' ``` Если `count > 0` — сначала удалите элементы или перенесите в другой тип. **`entityTypeId` не переиспользуется.** После удаления Битрикс24 не выдаст этот же `entityTypeId` новому типу — при следующем создании вы получите новое значение из диапазона `≥ 1030`. **Связи в других типах остаются.** Если другой тип ссылается на удалённый через `relations.parent` или `relations.child`, связь в его настройках сохранится, но станет «висячей». Настройте связи в оставшихся типах после удаления. ## Смотрите также - [Список типов](/docs/entities/smart-processes/list) — проверить, какие типы есть на портале - [Получить тип](/docs/entities/smart-processes/get) — проверить состояние перед удалением - [Обновить тип](/docs/entities/smart-processes/update) — альтернатива удалению: снять флаги, чтобы тип «остыл» - [Агрегация элементов](/docs/entities/items/aggregate) — проверить количество элементов перед удалением - [Удалить элемент](/docs/entities/items) — удалить элементы типа перед удалением самого типа - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Smart Processes: Fields ## Поля типа смарт-процесса `GET /v1/smart-processes/fields` Возвращает описание полей типа смарт-процесса: какие можно передавать при создании и обновлении, какие доступны только на чтение. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/smart-processes/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/smart-processes/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | Внутренний ID записи типа | | `entityTypeId` | number | | ID типа сущности. Передаётся в `/v1/items/:entityTypeId` для работы с элементами. Если не передан при создании — Битрикс24 назначает свободное значение автоматически | | `title` | string | | Название типа смарт-процесса | | `code` | string \| null | | Символьный код типа (для программной идентификации). `null`, если не задан | | `customSectionId` | number \| null | | ID цифрового рабочего места, к которому привязан тип. `null`, если не привязан. Записывается при создании, но не обновляется | | `isCategoriesEnabled` | boolean | | Использовать в смарт-процессе свои воронки и туннели продаж | | `isStagesEnabled` | boolean | | Использовать в смарт-процессе свои стадии и канбан | | `isBeginCloseDatesEnabled` | boolean | | Поля «Дата начала» и «Дата завершения» | | `isClientEnabled` | boolean | | Поле «Клиент» с привязкой к контактам и компаниям | | `isLinkWithProductsEnabled` | boolean | | Привязка товаров каталога | | `isMycompanyEnabled` | boolean | | Поле «Реквизиты вашей компании» | | `isObserversEnabled` | boolean | | Поле «Наблюдатели» | | `isSourceEnabled` | boolean | | Поля «Источник» и «Дополнительно об источнике» | | `isAutomationEnabled` | boolean | | Роботы и триггеры | | `isBizProcEnabled` | boolean | | Дизайнер бизнес-процессов | | `isDocumentsEnabled` | boolean | | Печать документов | | `isRecyclebinEnabled` | boolean | | Использование корзины | | `isSetOpenPermissions` | boolean | | Делать новые воронки доступными для всех | | `isUseInUserfieldEnabled` | boolean | | Использовать смарт-процесс в пользовательском поле | | `isRecurringEnabled` | boolean | | Поле «Регулярность» | | `isPaymentsEnabled` | boolean | | Онлайн-оплата | | `isCountersEnabled` | boolean | | Счётчики (уведомления и бейджи) | | `isInitialized` | boolean | да | Тип полностью инициализирован в портале | | `createdBy` | number | да | Кем создан. Поиск: `GET /v1/users` | | `updatedBy` | number | да | Кем изменён. Поиск: `GET /v1/users` | | `createdTime` | datetime | да | Дата создания | | `updatedTime` | datetime | да | Дата изменения | Ответ также содержит массив `batch` со списком операций, доступных для пакетной обработки: `create`, `update`, `delete`. > **Формат datetime.** `createdTime`/`updatedTime` приходят в ISO 8601, но конкретное представление (со смещением `+03:00` либо UTC `…Z` с миллисекундами) зависит от портала — парсьте как ISO 8601, не сравнивайте строки побайтно. ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "entityTypeId": { "type": "number", "readonly": false }, "title": { "type": "string", "readonly": false }, "isCategoriesEnabled": { "type": "boolean", "readonly": false }, "isStagesEnabled": { "type": "boolean", "readonly": false }, "isLinkWithProductsEnabled": { "type": "boolean", "readonly": false }, "code": { "type": "string", "readonly": false, "label": "Символьный код" }, "createdBy": { "type": "number", "readonly": true, "label": "Кем создан" }, "customSectionId": { "type": "number", "readonly": false, "label": "Цифровое рабочее место" }, "createdTime": { "type": "datetime", "readonly": true, "label": "Дата создания" } }, "batch": ["create", "update", "delete"] } } ``` Показаны 10 полей из 27. Полный список — в таблице выше. ## Пример ответа при ошибке 401 — ключ не передан: ```json { "success": false, "error": { "code": "MISSING_API_KEY", "message": "API key required. Pass via X-Api-Key header." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `INVALID_API_KEY` | Ключ не найден или отозван | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Вложенные структуры.** При создании и обновлении можно передавать поля `relations` (связи с другими типами CRM) и `linkedUserFields` (связанные пользовательские поля). Они не описаны в ответе `/fields`, но принимаются и сохраняются Битрикс24 без изменений. Подробнее — в [Создать тип](/docs/entities/smart-processes/create). **`label` — локализованное название из Битрикс24.** Для части полей возвращается поле `label` с русской надписью, которую Битрикс24 показывает в интерфейсе (например, `createdBy.label = "Кем создан"`). Удобно для построения собственных форм и списков. **Отличие от `GET /v1/{entity}/fields` у стандартных сущностей.** Этот эндпоинт описывает поля **типа смарт-процесса** (`crm.type.*`), а не элементов внутри него. Для полей элементов используйте `GET /v1/items/:entityTypeId/fields`. ## Смотрите также - [Список типов](/docs/entities/smart-processes/list) — все типы на портале - [Создать тип](/docs/entities/smart-processes/create) — какие поля передавать - [Обновить тип](/docs/entities/smart-processes/update) — частичное обновление - [Элементы смарт-процессов](/docs/entities/items) — CRUD по элементам - [Поля элементов](/docs/entities/items/fields) — `GET /v1/items/:entityTypeId/fields` - [Пользовательские поля](/docs/userfields) — управление `ufCrm_*` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Smart Processes: Get ## Получить тип смарт-процесса `GET /v1/smart-processes/:entityTypeId` Возвращает тип смарт-процесса по `entityTypeId`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` (path) | number | **да** | ID типа сущности. Список: `GET /v1/smart-processes` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/smart-processes/174" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/smart-processes/174" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/174', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Тип:', data.title, 'entityTypeId:', data.entityTypeId) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/174', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Тип смарт-процесса. Полный список полей — см. [Поля типа](/docs/entities/smart-processes/fields) | ## Пример ответа ```json { "success": true, "data": { "id": 3, "entityTypeId": 174, "title": "Договоры", "code": null, "customSectionId": null, "isCategoriesEnabled": true, "isStagesEnabled": true, "isClientEnabled": true, "isLinkWithProductsEnabled": true, "isObserversEnabled": true, "isSourceEnabled": true, "isAutomationEnabled": true, "isBizProcEnabled": true, "isDocumentsEnabled": true, "isRecyclebinEnabled": true, "isSetOpenPermissions": true, "isUseInUserfieldEnabled": true, "createdBy": 1, "updatedBy": 1, "createdTime": "2021-07-20T16:04:10+03:00", "updatedTime": "2024-07-19T14:27:27+03:00" } } ``` > **Карточка возвращает больше полей, чем список и `/fields`.** В дополнение к полям выше `GET /v1/smart-processes/:entityTypeId` отдаёт `relations` (объект с массивами `parent`/`child`), `linkedUserFields` (map) и `customSections` (массив) — это сквозной проброс от Битрикс24 `crm.type.get`, которого нет ни в списке, ни в `/fields`. `relations`/`linkedUserFields` документированы как входные поля create/update; `customSections` — только в ответе карточки. > > **`id` ≠ ключ карточки.** В ответе есть внутренний `id` (напр. 3), но карточка адресуется по `entityTypeId` (напр. 174): `GET /v1/smart-processes/`. `GET /v1/smart-processes/` вернёт `404 ENTITY_NOT_FOUND` — не путайте поле `id` с ключом пути. ## Пример ответа при ошибке 404 — тип не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Смарт-процесс не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `INVALID_API_KEY` | Ключ не найден или отозван | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 404 | `ENTITY_NOT_FOUND` | Тип с таким `entityTypeId` не найден | | 422 | `BITRIX_ERROR` | Ошибка от Битрикс24. Конкретная причина — в поле `message` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список типов](/docs/entities/smart-processes/list) — все типы на портале - [Создать тип](/docs/entities/smart-processes/create) — `POST /v1/smart-processes` - [Обновить тип](/docs/entities/smart-processes/update) — частичное обновление - [Удалить тип](/docs/entities/smart-processes/delete) - [Поля типа](/docs/entities/smart-processes/fields) — полный список полей - [Элементы смарт-процессов](/docs/entities/items) — CRUD по элементам этого типа - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Smart Processes: List ## Список типов смарт-процессов `GET /v1/smart-processes` Возвращает типы смарт-процессов на портале. Каждый тип имеет `entityTypeId` — используйте его для работы с элементами через [/v1/items/:entityTypeId](/docs/entities/items). ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям. Пример: `?filter[isStagesEnabled]=true`. [Синтаксис фильтрации](/docs/filtering) | | `select` | string | — | Выборка полей: `?select=id,title,entityTypeId` | | `sort` | string | — | Сортировка по полю: `?sort=title` (по возрастанию), `?sort=-createdTime` (по убыванию) | | `limit` | number | — | Ограничить количество записей в ответе | Список полей для `filter` и `select` — [Поля типа](/docs/entities/smart-processes/fields). Для сложных условий фильтрации (несколько полей одновременно) удобнее [Поиск типов](/docs/entities/smart-processes/search) — POST с body вместо query-строки. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/smart-processes" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/smart-processes" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() for (const sp of data) { console.log(`${sp.title}: entityTypeId=${sp.entityTypeId}`) } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив типов смарт-процессов. Поля каждого типа — см. [Поля типа](/docs/entities/smart-processes/fields) | Список элементов любого типа из массива `data` открывается в Битрикс24 по `entityTypeId`: ``` https://.bitrix24.ru/crm/type//list/category/0/ ``` `0` — основная воронка. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 3, "entityTypeId": 174, "title": "Договоры", "code": null, "customSectionId": null, "isCategoriesEnabled": true, "isStagesEnabled": true, "isClientEnabled": true, "isLinkWithProductsEnabled": true, "isObserversEnabled": true, "isSourceEnabled": true, "isAutomationEnabled": true, "isBizProcEnabled": true, "isDocumentsEnabled": true, "isRecyclebinEnabled": true, "isSetOpenPermissions": true, "isUseInUserfieldEnabled": true, "createdBy": 1, "updatedBy": 1, "createdTime": "2021-07-20T16:04:10+03:00", "updatedTime": "2024-07-19T14:27:27+03:00" } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `INVALID_API_KEY` | Ключ не найден или отозван | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 422 | `BITRIX_ERROR` | Ошибка от Битрикс24. Конкретная причина — в поле `message` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`entityTypeId` — ключевое поле.** Сохраняйте его и передавайте в `/v1/items/:entityTypeId` для работы с элементами этого типа. **Пагинации нет.** Ответ содержит все типы смарт-процессов портала одним массивом. На практике типов обычно десятки, не тысячи — это не проблема. ## Смотрите также - [Создать тип](/docs/entities/smart-processes/create) — `POST /v1/smart-processes` - [Получить тип](/docs/entities/smart-processes/get) — один тип по `entityTypeId` - [Поля типа](/docs/entities/smart-processes/fields) — полный список полей - [Поиск типов](/docs/entities/smart-processes/search) — POST с фильтрами - [Элементы смарт-процессов](/docs/entities/items) — CRUD по элементам - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Smart Processes: Search ## Поиск типов смарт-процессов `POST /v1/smart-processes/search` Поиск типов смарт-процессов с фильтрами через POST. Удобно, когда нужно передать несколько условий фильтрации, не нагромождая query-строку. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | `{}` | Фильтрация по любым полям типа (`title`, `entityTypeId`, `isStagesEnabled`, `isClientEnabled`, `isAutomationEnabled` и т. д.). [Синтаксис фильтрации](/docs/filtering) | | `limit` | number | `50` | Количество записей в ответе | Полный список полей, по которым можно фильтровать: [Поля типа](/docs/entities/smart-processes/fields). ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/smart-processes/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "isClientEnabled": true, "isStagesEnabled": true }, "limit": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/smart-processes/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "isClientEnabled": true, "isStagesEnabled": true }, "limit": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { isClientEnabled: true, isStagesEnabled: true }, limit: 10, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { isClientEnabled: true, isStagesEnabled: true }, limit: 10, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | array | Массив типов, удовлетворяющих фильтру. Поля каждого типа — см. [Поля типа](/docs/entities/smart-processes/fields) | Список элементов любого типа из массива `data` открывается в Битрикс24 по `entityTypeId`: ``` https://.bitrix24.ru/crm/type//list/category/0/ ``` `0` — основная воронка. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 3, "entityTypeId": 174, "title": "Договоры", "isStagesEnabled": true, "isClientEnabled": true, "isCategoriesEnabled": true, "isLinkWithProductsEnabled": true } ] } ``` Показаны 7 полей. Полный ответ содержит все поля типа. ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `INVALID_API_KEY` | Ключ не найден или отозван | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 422 | `BITRIX_ERROR` | Ошибка от Битрикс24. Конкретная причина — в поле `message` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Boolean-фильтры передавайте как `true`/`false`**, не как `"Y"`/`"N"` — Вайбкод сам преобразует их для Битрикс24. **Когда использовать search вместо list:** когда нужно несколько условий фильтрации одновременно — body запроса читаемее длинной query-строки. Для простого получения всех типов подойдёт `GET /v1/smart-processes`. ## Смотрите также - [Список типов](/docs/entities/smart-processes/list) — GET-запрос без фильтров - [Поля типа](/docs/entities/smart-processes/fields) — полный список полей для фильтрации - [Получить тип](/docs/entities/smart-processes/get) — один тип по `entityTypeId` - [Элементы смарт-процессов](/docs/entities/items) — CRUD по элементам - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Smart Processes: Update ## Обновить тип смарт-процесса `PATCH /v1/smart-processes/:entityTypeId` Обновляет поля существующего типа смарт-процесса. Передавайте только те поля, которые нужно изменить — остальные остаются прежними. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `entityTypeId` (path) | number | **да** | ID типа сущности. Список: `GET /v1/smart-processes` | ## Поля запроса (body) Все поля опциональны. Не переданные поля остаются без изменений. | Поле | Тип | Описание | |------|-----|---------| | `title` | string | Название смарт-процесса | | `code` | string | Символьный код типа (для программной идентификации) | | `isCategoriesEnabled` | boolean | Использовать свои воронки и туннели продаж | | `isStagesEnabled` | boolean | Использовать свои стадии и канбан | | `isBeginCloseDatesEnabled` | boolean | Поля «Дата начала» и «Дата завершения» | | `isClientEnabled` | boolean | Поле «Клиент» с привязкой к контактам и компаниям | | `isLinkWithProductsEnabled` | boolean | Привязка товаров каталога | | `isMycompanyEnabled` | boolean | Поле «Реквизиты вашей компании» | | `isObserversEnabled` | boolean | Поле «Наблюдатели» | | `isSourceEnabled` | boolean | Поля «Источник» и «Дополнительно об источнике» | | `isAutomationEnabled` | boolean | Роботы и триггеры | | `isBizProcEnabled` | boolean | Дизайнер бизнес-процессов | | `isDocumentsEnabled` | boolean | Печать документов | | `isRecyclebinEnabled` | boolean | Использование корзины | | `isSetOpenPermissions` | boolean | Делать новые воронки доступными для всех | | `isUseInUserfieldEnabled` | boolean | Использовать смарт-процесс в пользовательском поле | | `isRecurringEnabled` | boolean | Поле «Регулярность» | | `isPaymentsEnabled` | boolean | Онлайн-оплата | | `isCountersEnabled` | boolean | Счётчики (уведомления и бейджи) | | `relations` | object | Связи с другими сущностями CRM. **Полностью заменяет** существующие связи — см. «Известные особенности» | | `linkedUserFields` | object | Пользовательские поля, в которых отображается смарт-процесс. Формат — см. [Создать тип](/docs/entities/smart-processes/create#связи-и-пользовательские-поля) | Полный список полей: [GET /v1/smart-processes/fields](/docs/entities/smart-processes/fields). **Сменить `entityTypeId` нельзя** — он устанавливается при создании и остаётся неизменным. ## Часто обновляемые поля - `title` — переименование типа - `isStagesEnabled`, `isCategoriesEnabled`, `isAutomationEnabled`, `isBizProcEnabled` — включение/выключение основных возможностей - `code` — назначение программного идентификатора - `relations` — настройка связей с другими типами CRM ## Примеры ### curl — личный ключ ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/smart-processes/1050 \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Договоры поставки (обновлённое название)", "code": "supply_contracts", "isAutomationEnabled": false }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH https://vibecode.bitrix24.tech/v1/smart-processes/1050 \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Договоры поставки (обновлённое название)", "code": "supply_contracts", "isAutomationEnabled": false }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/1050', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Договоры поставки (обновлённое название)', code: 'supply_contracts', isAutomationEnabled: false, }), }) const { success, data } = await res.json() console.log('Обновлено в:', data.updatedTime) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/smart-processes/1050', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Договоры поставки (обновлённое название)', code: 'supply_contracts', isAutomationEnabled: false, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Полный объект типа после обновления. Список полей — см. [Поля типа](/docs/entities/smart-processes/fields) | ## Пример ответа ```json { "success": true, "data": { "id": 31, "entityTypeId": 1050, "title": "Договоры поставки (обновлённое название)", "code": "supply_contracts", "createdBy": 1, "createdTime": "2026-04-21T13:46:45+03:00", "updatedBy": 1, "updatedTime": "2026-04-21T14:50:13+03:00", "customSectionId": null, "isCategoriesEnabled": true, "isStagesEnabled": true, "isBeginCloseDatesEnabled": false, "isClientEnabled": false, "isLinkWithProductsEnabled": true, "isMycompanyEnabled": false, "isObserversEnabled": false, "isSourceEnabled": false, "isAutomationEnabled": false, "isBizProcEnabled": true, "isDocumentsEnabled": false, "isRecyclebinEnabled": false, "isSetOpenPermissions": true, "isUseInUserfieldEnabled": false, "isRecurringEnabled": false, "isPaymentsEnabled": false, "isCountersEnabled": false, "isInitialized": true } } ``` ## Пример ответа при ошибке 404 — тип не найден: ```json { "success": false, "error": { "code": "SMART_PROCESS_NOT_FOUND", "message": "Smart process with entityTypeId=99999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан | | 401 | `INVALID_API_KEY` | Ключ не найден или отозван | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 404 | `SMART_PROCESS_NOT_FOUND` | Тип с таким `entityTypeId` не найден. Сообщение: `Smart process with entityTypeId=X not found` | | 422 | `BITRIX_ERROR` | Ошибка валидации от Битрикс24. Конкретная причина — в поле `message` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`relations` полностью заменяет существующие связи.** Если передать `relations: {parent: [{entityTypeId: 3}]}`, все прежние `parent`-связи **будут удалены** и заменены на один новый массив. Чтобы добавить связь, не потеряв текущие, — сначала получите текущее состояние через `GET /v1/smart-processes/:entityTypeId`, добавьте новую запись в массив и передайте весь обновлённый список. Аналогично для `child` и `linkedUserFields` — это «перезапись», не «патч по записям». **Пустой body (`{}`) допустим.** PATCH с пустым объектом возвращает HTTP 200 и текущее состояние типа, ничего не меняя. **Изменение `entityTypeId` невозможно** — он задаётся при создании и служит стабильным идентификатором типа. ## Смотрите также - [Получить тип](/docs/entities/smart-processes/get) — `GET /v1/smart-processes/:entityTypeId` - [Список типов](/docs/entities/smart-processes/list) - [Создать тип](/docs/entities/smart-processes/create) - [Удалить тип](/docs/entities/smart-processes/delete) - [Поля типа](/docs/entities/smart-processes/fields) — полный список полей - [Элементы смарт-процессов](/docs/entities/items) — CRUD по элементам - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Statuses: Create ## Создать запись справочника `POST /v1/statuses` Создаёт новую запись в справочнике CRM. Обязательные поля: `entityId`, `statusId`, `name`. ## Параметры тела запроса | Параметр | Тип | Обязат. | Описание | |----------|-----|:-------:|---------| | `entityId` | string | да | Тип справочника (DEAL_STAGE, SOURCE и др.) | | `statusId` | string | да | Символьный код значения | | `name` | string | да | Название | | `sort` | number | | Порядок сортировки | | `color` | string | | Цвет (HEX без #, напр. `22B9FF`) | | `semantics` | string | | Семантика: S (успех), F (провал), P (в работе) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/statuses" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"entityId": "SOURCE", "statusId": "PARTNER", "name": "Партнёр", "sort": 50}' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/statuses" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"entityId": "SOURCE", "statusId": "PARTNER", "name": "Партнёр", "sort": 50}' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ entityId: 'SOURCE', statusId: 'PARTNER', name: 'Партнёр', sort: 50 }), }) const { success, data } = await res.json() console.log('ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ entityId: 'SOURCE', statusId: 'PARTNER', name: 'Партнёр', sort: 50 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID записи | | `entityId` | string | Тип справочника | | `statusId` | string | Символьный код | | `name` | string | Название | | `nameInit` | string | Исходное название | | `sort` | number | Сортировка | | `SYSTEM` | string | Системная запись (Y/N) | | `CATEGORY_ID` | string/null | ID категории | | `color` | string | Цвет (HEX) | | `semantics` | string/null | Семантика | ## Пример ответа ```json { "success": true, "data": { "id": 801, "entityId": "SOURCE", "statusId": "PARTNER", "name": "Партнёр", "nameInit": "", "sort": 50, "SYSTEM": "N", "CATEGORY_ID": "0", "color": "", "semantics": null } } ``` ## Пример ответа при ошибке 502 — дублирование кода: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Duplicate STATUS_ID for this ENTITY_ID" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 502 | `BITRIX_ERROR` | Ошибка Bitrix24 (дублирование statusId и др.) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список справочников](/docs/entities/statuses/list) — проверить существующие записи - [Поля справочника](/docs/entities/statuses/fields) — все доступные поля - [Справочники CRM](/docs/entities/statuses) — обзор сущности --- # Statuses: Delete ## Удалить запись справочника `DELETE /v1/statuses/:id` Удаляет запись справочника CRM по ID. Системные записи (`SYSTEM = Y`) удалить нельзя. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID записи справочника | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/statuses/42" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/statuses/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) if (res.status === 204) { console.log('Запись удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/42', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — запись не найдена или системная: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Status is not found." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Запись не найдена, является системной (`SYSTEM = Y`) или ID невалиден | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список справочников](/docs/entities/statuses/list) — найти записи перед удалением - [Справочники CRM](/docs/entities/statuses) — обзор сущности --- # Statuses: Fields ## Поля справочника `GET /v1/statuses/fields` Возвращает описание всех полей сущности с типами и атрибутами. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/statuses/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/statuses/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | RO | Описание | |------|-----|:--:|---------| | `id` | number | да | ID записи | | `entityId` | string | | Тип справочника (DEAL_STAGE, SOURCE и др.) | | `statusId` | string | | Символьный код значения | | `name` | string | | Название | | `nameInit` | string | | Исходное название | | `sort` | number | | Сортировка | | `color` | string | | Цвет (HEX) | | `semantics` | string | | Семантика: S (успех), F (провал), P (в работе) | ## Пример ответа ```json { "success": true, "data": { "ID": { "type": "integer", "isRequired": false, "isReadOnly": true }, "ENTITY_ID": { "type": "string", "isRequired": true, "isReadOnly": false }, "STATUS_ID": { "type": "string", "isRequired": true, "isReadOnly": false }, "NAME": { "type": "string", "isRequired": true, "isReadOnly": false }, "NAME_INIT": { "type": "string", "isRequired": false, "isReadOnly": true }, "SORT": { "type": "integer", "isRequired": false, "isReadOnly": false }, "COLOR": { "type": "string", "isRequired": false, "isReadOnly": false }, "SEMANTICS": { "type": "string", "isRequired": false, "isReadOnly": false } } } ``` ## Пример ответа при ошибке 404 — не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Справочники CRM](/docs/entities/statuses) — обзор сущности - [Список справочников](/docs/entities/statuses/list) — получить записи --- # Statuses: Get ## Получить запись справочника `GET /v1/statuses/:id` Возвращает одну запись справочника CRM по ID. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | ID записи справочника | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/statuses/1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/statuses/1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/1', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/1', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID записи | | `entityId` | string | Тип справочника (DEAL_STAGE, SOURCE, CONTACT_TYPE и др.) | | `statusId` | string | Символьный код значения | | `name` | string | Название | | `nameInit` | string | Исходное название | | `sort` | number | Сортировка | | `SYSTEM` | string | Системная запись (Y/N) | | `CATEGORY_ID` | number/null | ID категории | | `color` | string | Цвет (HEX) | | `semantics` | string/null | Семантика: S (успех), F (провал), P (в работе) | ## Пример ответа ```json { "success": true, "data": { "id": 1, "entityId": "DEAL_STAGE", "statusId": "NEW", "name": "Новая", "nameInit": "Новая", "sort": 10, "color": "22B9FF", "semantics": "P" } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Status not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Запись не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Список справочников](/docs/entities/statuses/list) — все записи с фильтрами - [Обновить запись](/docs/entities/statuses/update) — изменение значения - [Справочники CRM](/docs/entities/statuses) — обзор сущности --- # Statuses: List ## Список справочников `GET /v1/statuses` Возвращает записи справочников CRM. Используйте `filter[entityId]` для выбора конкретного типа. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` авто-пагинация | | `offset` | number | `0` | Пропустить N записей | | `select` | string | — | Выборка полей: `?select=id,name,entityId` | | `order` | object | — | Сортировка: `?order[sort]=asc` | | `filter` | object | — | Фильтрация по полям `GET /v1/statuses/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[entityId]=DEAL_STAGE` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/statuses?filter[entityId]=DEAL_STAGE&order[sort]=asc" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/statuses?filter[entityId]=DEAL_STAGE&order[sort]=asc" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses?filter[entityId]=DEAL_STAGE&order[sort]=asc', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data, meta } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses?filter[entityId]=DEAL_STAGE&order[sort]=asc', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data[].id` | number | ID записи | | `data[].entityId` | string | Тип справочника (DEAL_STAGE, SOURCE, CONTACT_TYPE и др.) | | `data[].statusId` | string | Символьный код значения | | `data[].name` | string | Название | | `data[].nameInit` | string | Исходное название | | `data[].sort` | number | Сортировка | | `data[].SYSTEM` | string | Системная запись (Y/N) | | `data[].CATEGORY_ID` | number/null | ID категории | | `data[].color` | string | Цвет (HEX) | | `data[].semantics` | string/null | Семантика: S (успех), F (провал), P (в работе) | ## Пример ответа ```json { "success": true, "data": [ { "id": 1, "entityId": "DEAL_STAGE", "statusId": "NEW", "name": "Новая", "sort": 10, "color": "22B9FF", "semantics": "P" }, { "id": 2, "entityId": "DEAL_STAGE", "statusId": "WON", "name": "Сделка успешна", "sort": 50, "color": "7BD500", "semantics": "S" } ], "meta": { "total": 12, "hasMore": false } } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Справочники CRM](/docs/entities/statuses) — обзор сущности - [Создать запись](/docs/entities/statuses/create) — добавление нового значения - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — объединение запросов --- # Statuses: Update ## Обновить запись справочника `PATCH /v1/statuses/:id` Обновляет поля записи справочника CRM по ID. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | ID записи справочника | ## Параметры тела запроса | Параметр | Тип | Описание | |----------|-----|---------| | `name` | string | Название | | `sort` | number | Порядок сортировки | | `color` | string | Цвет (HEX без #) | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/statuses/42" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Предоплата получена", "sort": 35}' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/statuses/42" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Предоплата получена", "sort": 35}' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Предоплата получена', sort: 35 }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/statuses/42', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Предоплата получена', sort: 35 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | boolean | `true` при успешном выполнении | ## Пример ответа ```json { "success": true, "data": true } ``` ## Пример ответа при ошибке ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Status not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `NOT_FOUND` | Запись не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | Не передан API-ключ | Полный список ошибок — [Ошибки](/docs/errors). ## Смотрите также - [Получить запись](/docs/entities/statuses/get) — проверить текущие значения - [Описание полей](/docs/entities/statuses/fields) — все доступные поля - [Справочники CRM](/docs/entities/statuses) — обзор сущности --- # Task Comments: Comments Batch ## Пакет операций над комментариями `POST /v1/tasks/:taskId/comments/batch` Массовое создание, обновление или удаление комментариев одной задачи. До 50 элементов за вызов. Каждый элемент обрабатывается независимо — ошибка одного не отменяет остальные. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `action` | string | ★ | Тип операции: `create`, `update` или `delete` | | `items` | array | при `create` / `update` | Список элементов (до 50). Для `create`: `[{ message: string }]`. Для `update`: `[{ id: number, message: string }]` | | `ids` | number[] | при `delete` | Идентификаторы комментариев для удаления (до 50) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/289/comments/batch" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "action": "create", "items": [ { "message": "Шаг 1: подготовил черновик." }, { "message": "Шаг 2: отправил на ревью." } ] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/289/comments/batch" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "create", "items": [ { "message": "Шаг 1: подготовил черновик." }, { "message": "Шаг 2: отправил на ревью." } ] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/batch', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'create', items: [ { message: 'Шаг 1: подготовил черновик.' }, { message: 'Шаг 2: отправил на ревью.' }, ], }), }) const { success, data } = await res.json() data.forEach((item) => { if (item.success) console.log(`#${item.index} → id=${item.id}`) else console.log(`#${item.index} → ошибка: ${item.error}`) }) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/batch', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'create', items: [ { message: 'Шаг 1: подготовил черновик.' }, { message: 'Шаг 2: отправил на ревью.' }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` — даже если все элементы упали, верхний уровень success. Смотрите статус каждого в `data[i]` | | `data` | array | Массив результатов в том же порядке, что и `items` / `ids` запроса | | `data[].index` | number | Индекс элемента (0-based) | | `data[].success` | boolean | Результат конкретной операции | | `data[].id` | number \| null | ID комментария при `create` / `update` (для `create` на новой карточке может быть `null` — см. [`POST /v1/tasks/:taskId/comments`](./create.md)) | | `data[].error` | string | Код ошибки для упавшего элемента (`GONE`, `BATCH_ITEM_VALIDATION`, `BITRIX_ERROR`, `INVALID_PARAMS`) | | `data[].message` | string | Текст ошибки для упавшего элемента | ## Пример ответа `action: create` на новой карточке — обе записи попали в чат задачи: ```json { "success": true, "data": [ { "index": 0, "success": true, "id": 36571 }, { "index": 1, "success": true, "id": 36573 } ] } ``` `action: update` на новой карточке — каждая попытка обновления превращается в `GONE` (метод недоступен): ```json { "success": true, "data": [ { "index": 0, "success": false, "error": "GONE", "message": "Bitrix24 disabled update/delete for task comments in the new task card. To remove a comment, delete the source task or ask a portal admin to remove the message via the chat UI." } ] } ``` ## Пример ответа при ошибке 400 — некорректное значение `action`: ```json { "success": false, "error": { "code": "INVALID_BATCH_ACTION", "message": "Action must be one of: create, update, delete" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `taskId` не положительное целое | | 400 | `INVALID_BATCH_ACTION` | `action` не равен `create`, `update` или `delete` | | 400 | `BATCH_ITEM_VALIDATION` | `items` (или `ids` при `delete`) пустой или не массив | | 400 | `BATCH_LIMIT_EXCEEDED` | В одном запросе передано более 50 элементов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Ошибки отдельных элементов приходят внутри `data[i].error`: | Код | Описание | |-----|----------| | `GONE` | Только для `update` / `delete` на новой карточке — операция недоступна на стороне Битрикс24 | | `BATCH_ITEM_VALIDATION` | Элемент не прошёл валидацию (например, нет `id` или `message`, неверный тип) | | `INVALID_PARAMS` | `message` отсутствует или превышает лимит длины | | `BITRIX_ERROR` | Битрикс24 вернул ошибку для конкретного элемента (текст в `message`) | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Верхний `success` всегда `true`, если запрос прошёл валидацию.** Несколько упавших элементов внутри не превращают весь ответ в ошибку — это сделано специально, чтобы клиент мог обработать частичный результат. Перед использованием результата всегда проверяйте `data[i].success` для каждого элемента. **`GONE` приходит для каждого элемента отдельно.** На новой карточке `update` / `delete` каждого элемента возвращает `GONE`, но общий ответ остаётся `200 success` — весь пакет не отклоняется. В смешанных сценариях часть элементов на старой карточке проходит, часть на новой возвращает `GONE`. ## Смотрите также - [Создать комментарий](./create.md) — одиночный POST - [Обновить комментарий](./update.md) — одиночный PATCH (тот же контракт по карточкам) - [Удалить комментарий](./delete.md) — одиночный DELETE - [Универсальный batch](/docs/batch) — объединение разных entity-операций в один HTTP-вызов - [Задачи](/docs/entities/tasks) — родительская сущность --- # Task Comments: Create ## Создать комментарий `POST /v1/tasks/:taskId/comments` Добавляет комментарий к задаче. На новой карточке задачи сообщение отправляется в чат, на старой — попадает в блок комментариев в самой карточке. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `message` | string | ★ | Текст комментария, до 20 000 символов. Поддерживает BB-код (`[USER=ID]Имя[/USER]`, `[B]...[/B]`, `[QUOTE]...[/QUOTE]`) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/289/comments" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": "Добавил черновик отчёта — посмотри, пожалуйста." }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/289/comments" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "message": "Добавил черновик отчёта — посмотри, пожалуйста." }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ message: 'Добавил черновик отчёта — посмотри, пожалуйста.', }), }) const { success, data } = await res.json() console.log('ID нового комментария:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ message: 'Добавил черновик отчёта — посмотри, пожалуйста.', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number \| null | Идентификатор нового комментария. На новой карточке возвращается id чат-сообщения, в редком случае может быть `null` — см. «Известные особенности» | ## Пример ответа HTTP 201 Created: ```json { "success": true, "data": { "id": 36559 } } ``` ## Пример ответа при ошибке 400 — пустой или отсутствующий `message`: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "`message` is required and must be a string" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `taskId` не положительное целое | | 400 | `INVALID_PARAMS` | Поле `message` отсутствует или не является строкой | | 400 | `INVALID_PARAMS` | `message` превышает лимит длины | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список комментариев](./list.md) — найти добавленный комментарий - [Получить комментарий](./get.md) — прочитать по `id` - [Пакет операций](./comments-batch.md) — добавить несколько комментариев одним запросом - [Задачи](/docs/entities/tasks) — родительская сущность - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Task Comments: Delete ## Удалить комментарий `DELETE /v1/tasks/:taskId/comments/:id` Удаляет комментарий задачи. Доступно только на порталах со старой карточкой задачи: на новой карточке метод возвращает `410 GONE`. Восстановить удалённый комментарий через API нельзя. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | | `id` (path) | number | да | ID комментария | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Комментарий удалён') } else if (res.status === 410) { const { error } = await res.json() console.log('Новая карточка — удаление недоступно:', error.message) } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) ``` ## Ответ При успешном удалении на старой карточке возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. На новой карточке вместо `204` приходит `410 GONE` с JSON-телом (см. ниже). ## Пример ответа Старая карточка: ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 410 — новая карточка задачи (метод недоступен): ```json { "success": false, "error": { "code": "GONE", "message": "Bitrix24 disabled update/delete for task comments in the new task card. To remove a comment, delete the source task or ask a portal admin to remove the message via the chat UI.", "hint": "Verified against apidocs.bitrix24.ru on 2026-05-09 — the modern task-chat API accepts only new messages, no edit or delete." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `taskId` или `id` не являются положительными целыми | | 410 | `GONE` | Задача создана на новой карточке — удаление комментария на стороне Битрикс24 недоступно | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Альтернатива для новой карточки.** Способов программно удалить отправленный комментарий нет. Если содержимое нужно скрыть — удалите задачу целиком ([`DELETE /v1/tasks/:id`](/docs/entities/tasks/delete)), либо попросите администратора портала удалить сообщение через интерфейс чата. ## Смотрите также - [Список комментариев](./list.md) — найти комментарий перед удалением - [Получить комментарий](./get.md) — проверить текст перед удалением - [Обновить комментарий](./update.md) — изменение (тот же контракт по карточкам) - [Задачи](/docs/entities/tasks) — родительская сущность --- # Task Comments: Get ## Получить комментарий `GET /v1/tasks/:taskId/comments/:id` Возвращает один комментарий задачи по его идентификатору. Работает и для комментариев из чата новой карточки, и для записей в блоке комментариев старой карточки. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | | `id` (path) | number | да | ID комментария (из `GET /v1/tasks/:taskId/comments` или ответа `POST /v1/tasks/:taskId/comments`) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log(data.message) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор комментария | | `data.taskId` | number | ID родительской задачи | | `data.authorId` | number | Автор. Профиль: `GET /v1/users/:authorId` | | `data.message` | string | Текст комментария (поддерживает BB-код) | | `data.createdAt` | datetime | Дата создания (UTC ISO 8601) | ## Пример ответа ```json { "success": true, "data": { "id": 36559, "taskId": 289, "authorId": 1, "message": "Добавил черновик отчёта в комментарии — посмотри, пожалуйста.", "createdAt": "2026-05-13T12:30:58.000Z" } } ``` ## Пример ответа при ошибке 404 — комментарий не найден: ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Comment not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `taskId` или `id` не являются положительными целыми числами | | 404 | `NOT_FOUND` | Комментарий с таким `id` не найден ни в чате, ни в блоке комментариев старой карточки | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Двухступенчатый поиск.** На новой карточке API сначала ищет комментарий среди последних 200 сообщений чата задачи. Если совпадения нет — например, комментарий старше 200 последних или относится к старой карточке — запрос автоматически идёт по старому пути чтения. Это прозрачно для клиента: формат ответа одинаковый. ## Смотрите также - [Список комментариев](./list.md) — получить ID нужного комментария - [Создать комментарий](./create.md) — добавить новый - [Обновить комментарий](./update.md) — изменить текст - [Удалить комментарий](./delete.md) — снять комментарий - [Задачи](/docs/entities/tasks) — родительская сущность --- # Task Comments: List ## Список комментариев `GET /v1/tasks/:taskId/comments` Возвращает комментарии конкретной задачи. На новой карточке задачи список читается из чата (системные сообщения отфильтрованы); на старой — из блока комментариев в самой карточке. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `taskId` (path) | number | да | — | ID родительской задачи | | `limit` (query) | number | | `50` | Размер страницы (до 200) | | `sort` (query) | string | | `id:desc` | Сортировка: `id:asc` или `id:desc` | | `filter` (query) | object | | — | Фильтр для старой карточки. Передаётся как JSON: `?filter={"AUTHOR_ID":1}`. На новой карточке передача параметра переключает чтение в режим старой карточки | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/comments?limit=20&sort=id:desc" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/comments?limit=20&sort=id:desc" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const url = 'https://vibecode.bitrix24.tech/v1/tasks/289/comments?limit=20&sort=id:desc' const res = await fetch(url, { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Получено ${data.length} комментариев`) ``` ### JavaScript — OAuth-приложение ```javascript const url = 'https://vibecode.bitrix24.tech/v1/tasks/289/comments?limit=20&sort=id:desc' const res = await fetch(url, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив комментариев | | `data[].id` | number | Идентификатор комментария | | `data[].taskId` | number | ID родительской задачи | | `data[].authorId` | number | Автор. Профиль: `GET /v1/users/:authorId` | | `data[].message` | string | Текст комментария (поддерживает BB-код) | | `data[].createdAt` | datetime | Дата создания (UTC ISO 8601) | | `meta.total` | number | Оценка количества комментариев | | `meta.hasMore` | boolean | Есть ли ещё комментарии за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 36559, "taskId": 289, "authorId": 1, "message": "Добавил черновик отчёта в комментарии — посмотри, пожалуйста.", "createdAt": "2026-05-13T12:30:58.000Z" }, { "id": 36557, "taskId": 289, "authorId": 79, "message": "[USER=99]Зуля[/USER], готово, спасибо.", "createdAt": "2026-05-12T15:11:04.000Z" } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — `taskId` не положительное целое: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "taskId must be a positive integer" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `taskId` некорректен (не целое положительное число) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Пустая страница при `meta.hasMore: true`.** Системные уведомления (постановка задачи, смена срока, назначение исполнителя) отфильтровываются на стороне API. Если их много в текущем срезе, `data` может прийти пустым при `meta.hasMore: true` — запросите следующую страницу или увеличьте `limit`. ## Смотрите также - [Получить комментарий](./get.md) — одна запись по `id` - [Создать комментарий](./create.md) — добавить новый - [Пакет операций](./comments-batch.md) — добавить несколько за один вызов - [Задачи](/docs/entities/tasks) — родительская сущность - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Task Comments: Update ## Обновить комментарий `PATCH /v1/tasks/:taskId/comments/:id` Изменяет текст существующего комментария задачи. Доступно только на порталах со старой карточкой задачи: на новой карточке метод возвращает `410 GONE` с пояснением. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | | `id` (path) | number | да | ID комментария | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `message` | string | ★ | Новый текст комментария, до 20 000 символов | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": "Уточнил формулировку в комментарии." }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "message": "Уточнил формулировку в комментарии." }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ message: 'Уточнил формулировку в комментарии.', }), }) const { success, data, error } = await res.json() if (res.status === 410) console.log('Новая карточка — обновление недоступно:', error.message) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/comments/36559', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ message: 'Уточнил формулировку в комментарии.', }), }) const { success, data, error } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | `true` при успешном обновлении на старой карточке | | `data.id` | number | Идентификатор обновлённого комментария | ## Пример ответа Старая карточка — обновление применилось: ```json { "success": true, "data": { "id": 36559 } } ``` ## Пример ответа при ошибке 410 — новая карточка задачи (метод недоступен): ```json { "success": false, "error": { "code": "GONE", "message": "Bitrix24 disabled update/delete for task comments in the new task card. To remove a comment, delete the source task or ask a portal admin to remove the message via the chat UI.", "hint": "Verified against apidocs.bitrix24.ru on 2026-05-09 — the modern task-chat API accepts only new messages, no edit or delete." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `taskId` или `id` не являются положительными целыми | | 410 | `GONE` | Задача создана на новой карточке — обновление комментария на стороне Битрикс24 недоступно | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Альтернатива для новой карточки.** Способов программно изменить отправленный комментарий нет. Если содержимое критично — удалите задачу целиком ([`DELETE /v1/tasks/:id`](/docs/entities/tasks/delete)) и создайте новую, либо попросите администратора портала удалить сообщение через интерфейс чата. ## Смотрите также - [Получить комментарий](./get.md) — прочитать текущий текст - [Создать комментарий](./create.md) — добавить новый - [Удалить комментарий](./delete.md) — снять комментарий (тот же контракт по карточкам) - [Задачи](/docs/entities/tasks) — родительская сущность --- # Tasks: Aggregate ## Агрегация задач `POST /v1/tasks/aggregate` Подсчёт количества задач с фильтрацией и группировкой. Числовые функции работают по числовым полям задачи и пользовательским полям подходящих типов. **Стандартные поля:** - `status` — статус задачи (для `groupBy`; для числовых функций смысла нет — это категориальный код) - `priority` — приоритет (для `groupBy`) - `responsibleId` — ответственный (для `groupBy`; идентификатор) - `groupId` — рабочая группа (для `groupBy`; идентификатор) Все стандартные `aggregatable` поля — идентификаторы или категориальные коды, поэтому по ним работают `count` и `groupBy`. Для числовых функций (`sum`/`avg`/`min`/`max`) подходящий встроенный кандидат — `timeEstimate` (оценка трудозатрат в секундах); либо пользовательские поля. **Пользовательские поля (UF):** UF-поля типов `integer`, `double`, `money` принимаются в числовых функциях; UF любого типа — в `groupBy`. Полный список UF-полей конкретного портала приходит в тексте ошибки `INVALID_PARAMS`, если передать несуществующее имя. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "timeEstimate", "function": "sum" }`. Функции: `count`, `sum`, `avg`, `min`, `max`. Без параметра — только count | | `filter` | object | нет | Фильтрация по полям `GET /v1/tasks/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `{"responsibleId": 1}` | | `groupBy` | string \| string[] | нет | Поле или массив полей для группировки (максимум 5). Принимает UF-поля любого типа | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "timeEstimate", "function": "sum" } ], "groupBy": "status" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "aggregate": [ { "field": "timeEstimate", "function": "sum" } ], "groupBy": "status" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'timeEstimate', function: 'sum' }], groupBy: 'status', }), }) const { success, data } = await res.json() console.log('Всего задач:', data.count) console.log('По статусам:', data.groups) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ aggregate: [{ field: 'timeEstimate', function: 'sum' }], groupBy: 'status', }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["status", "responsibleId"]` (максимум 5). ## Другие сценарии Общее количество задач на портале — самый быстрый запрос, без выгрузки записей: ```json {} ``` Сколько задач у каждого ответственного: ```json { "groupBy": "responsibleId" } ``` Сумма по UF-полю числового типа в разрезе приоритета: ```json { "aggregate": [{ "field": "UF_CRM_TASK_BUDGET", "function": "sum" }], "groupBy": "priority" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Количество записей, соответствующих фильтру | | `data.aggregates` | object | Результаты агрегаций. Без `aggregate` — пустой объект | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: поля группировки + `count` + `aggregates` | | `data.meta.totalRecords` | number | Общее количество записей | | `data.meta.recordsProcessed` | number | Сколько записей реально обработано | | `data.meta.truncated` | boolean | `true`, если попали в ограничение 5000 — агрегация и группы построены по первым 5000 записям | | `data.meta.groupTotal` | number | Общее количество групп (только при `groupBy`) | | `data.meta.groupsTruncated` | boolean | Был ли список групп ограничен `groupLimit` | ## Пример ответа Ответ на основной запрос (`aggregate: [{field: "timeEstimate", function: "sum"}]` + `groupBy: "status"`): ```json { "success": true, "data": { "count": 599, "aggregates": { "timeEstimate": { "sum": 54000 } }, "groups": [ { "status": "2", "count": 247, "aggregates": { "timeEstimate": { "sum": 18000 } } }, { "status": "5", "count": 341, "aggregates": { "timeEstimate": { "sum": 32400 } } }, { "status": "3", "count": 7, "aggregates": { "timeEstimate": { "sum": 2400 } } }, { "status": "4", "count": 4, "aggregates": { "timeEstimate": { "sum": 1200 } } } ], "meta": { "totalRecords": 599, "recordsProcessed": 599, "truncated": false, "groupTotal": 4, "groupsTruncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — несуществующее поле: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Unknown field 'noSuchField'. Available: status, priority, responsibleId, groupId, UF_CRM_TASK_BUDGET, …" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Неизвестная функция или несуществующее поле — сообщение содержит список допустимых (стандартных + UF) | | 400 | `INVALID_PARAMS` | UF-поле нечислового типа (`string`, `enumeration`, `date`) в `sum`/`avg`/`min`/`max` — сообщение называет тип | | 400 | `INVALID_PARAMS` | `groupBy` по стандартному полю вне списка `aggregatable` | | 400 | `INVALID_PARAMS` | Больше 5 полей в `groupBy` | | 400 | `INVALID_PARAMS` | Зарезервированные ключевые слова в `groupBy`: `count`, `aggregates`, `meta`, `groups` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` против числовых функций.** `count` считается одним вызовом и работает на любом объёме. `sum`/`avg`/`min`/`max` подгружают записи постранично (максимум 5000) и считают на стороне API. При выборках свыше 5000 — `meta.truncated: true`, агрегация по первым 5000. Для точных счётчиков на больших выборках используйте `count` или сужайте фильтр. ## Смотрите также - [Список задач](./list.md) — `meta.total` показывает точное число записей под фильтр - [Поиск задач](./search.md) — POST-запрос с фильтрами в body - [Поля задачи](./fields.md) — список стандартных полей и расшифровка `status`/`priority` - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Tasks: Checklist # Чек-лист задачи Пункты чек-листа задачи — вложенный ресурс задачи. У каждого пункта есть название, статус выполнения, признак важности, порядок сортировки, участники и (опционально) родительский пункт для вложенных чек-листов. Базовый путь — `/v1/tasks/:taskId/checklist`. Все операции требуют существующей задачи (`:taskId`) на портале. Битрикс24 API: `task.checklistitem.*` Скоуп: `task` > **Почему отдельный ресурс.** Битрикс24 **не принимает** поле `CHECKLIST` внутри `POST /v1/tasks` (`tasks.task.add`) — чек-лист нельзя создать вместе с задачей. Единственный поддерживаемый способ управлять пунктами — это методы семейства `task.checklistitem.*`, которые и оборачивает данный ресурс. Сначала создайте задачу, затем добавляйте пункты по одному. ## Операции - [Список пунктов](#список--get-v1taskstaskidchecklist) — `GET /v1/tasks/:taskId/checklist` - [Получить пункт](#получить--get-v1taskstaskidchecklistitemid) — `GET /v1/tasks/:taskId/checklist/:itemId` - [Добавить пункт](#добавить--post-v1taskstaskidchecklist) — `POST /v1/tasks/:taskId/checklist` - [Обновить пункт](#обновить--patch-v1taskstaskidchecklistitemid) — `PATCH /v1/tasks/:taskId/checklist/:itemId` - [Удалить пункт](#удалить--delete-v1taskstaskidchecklistitemid) — `DELETE /v1/tasks/:taskId/checklist/:itemId` - [Отметить выполненным](#отметить-выполненным--post-completerenew) — `POST /v1/tasks/:taskId/checklist/:itemId/complete` - [Вернуть в работу](#отметить-выполненным--post-completerenew) — `POST /v1/tasks/:taskId/checklist/:itemId/renew` ## Поля пункта | Поле | Тип | Только чтение | Описание | |------|-----|:---:|---------| | `title` | string | | Текст пункта. **Обязателен при создании.** Если `parentId = 0`, то `title` — название нового чек-листа | | `sortIndex` | integer | | Индекс сортировки. Чем меньше значение, тем выше пункт в списке | | `isComplete` | boolean / `Y`,`N` | | Статус выполнения. При записи принимает `true`/`false` или `"Y"`/`"N"`. В ответе — `"Y"`/`"N"` | | `isImportant` | boolean / `Y`,`N` | | Признак важности. Формат — как у `isComplete` | | `parentId` | integer | | ID родительского пункта для вложенных чек-листов. **`0` создаёт новый чек-лист** в задаче | | `members` | object | | Участники пункта. Объект вида `{ "": { "type": "A" \| "U" } }`. `A` — соисполнитель, `U` — наблюдатель. Список сотрудников: `GET /v1/users` | | `id` | string | да | ID пункта | | `taskId` | string | да | ID родительской задачи | | `createdBy` | string | да | Автор пункта | | `toggledBy` | string | да | Кто последним менял статус выполнения | | `toggledDate` | string | да | Когда статус менялся последний раз | | `attachments` | object | да | Прикреплённые файлы (заполняются в UI Битрикс24) | > **Регистр и типы в ответе.** Ответы приходят в camelCase (`id`, `taskId`, `sortIndex`, `isComplete`). Числовые значения Битрикс24 сериализует **строками** (`"id": "477"`, `"sortIndex": "2"`) — для арифметики приводите через `Number(value)`. Флаги `isComplete` / `isImportant` — это строки `"Y"` / `"N"`, а не булевы значения. ## Список — `GET /v1/tasks/:taskId/checklist` Возвращает все пункты чек-листа задачи. ### Параметры запроса | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `sort` | string | нет | Сортировка в формате `поле:направление`, например `sortIndex:asc`. Поля: `id`, `parentId`, `createdBy`, `title`, `sortIndex`, `isComplete`, `isImportant`, `toggledBy`, `toggledDate`. Направление: `asc` / `desc` (по умолчанию `asc`). Без параметра Битрикс24 сортирует по `id` убыванию | | `start` | integer | нет | Смещение в выборке. Битрикс24 отдаёт страницами по 50 пунктов; для следующей страницы передайте `start=50`, затем `100` и т.д. | ### Пример ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/8017/checklist?sort=sortIndex:asc" \ -H "X-Api-Key: $VIBE_KEY" ``` ### Пример ответа ```json { "success": true, "data": [ { "id": "431", "taskId": "8017", "parentId": 0, "createdBy": "503", "title": "Чек-лист 1", "sortIndex": "0", "isComplete": "N", "isImportant": "N", "toggledBy": null, "toggledDate": "", "members": [], "attachments": [] }, { "id": "433", "taskId": "8017", "parentId": "431", "createdBy": "503", "title": "Найти все документы по клиенту", "sortIndex": "0", "isComplete": "Y", "isImportant": "N", "members": [], "attachments": [] } ], "meta": { "total": 2 } } ``` ## Получить — `GET /v1/tasks/:taskId/checklist/:itemId` ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/8017/checklist/433" \ -H "X-Api-Key: $VIBE_KEY" ``` Возвращает один пункт (`{ "success": true, "data": { ... } }`) или `404 NOT_FOUND`, если пункта нет. ## Добавить — `POST /v1/tasks/:taskId/checklist` `title` обязателен. Возвращает `id` нового пункта. ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/13/checklist" \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Подготовить отчёт", "sortIndex": 200, "isImportant": true, "parentId": 457, "members": { "547": { "type": "A" } } }' ``` ```json { "success": true, "data": { "id": 475 } } ``` Чтобы создать **новый чек-лист** (контейнер верхнего уровня), передайте `parentId: 0` — в этом случае `title` становится названием чек-листа: ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/13/checklist" \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Документы", "parentId": 0 }' ``` ## Обновить — `PATCH /v1/tasks/:taskId/checklist/:itemId` Частичное обновление — передавайте только изменяемые поля. Хотя бы одно поле обязательно. ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/tasks/13/checklist/475" \ -H "X-Api-Key: $VIBE_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Подготовить итоговый отчёт", "isImportant": false }' ``` ```json { "success": true, "data": { "id": 475 } } ``` > **`members` заменяется целиком.** При обновлении поля `members` Битрикс24 **полностью** перезаписывает список участников пункта. Чтобы сохранить текущих участников, передайте их вместе с новыми. ## Удалить — `DELETE /v1/tasks/:taskId/checklist/:itemId` ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/tasks/13/checklist/475" \ -H "X-Api-Key: $VIBE_KEY" ``` Успех — `204 No Content` без тела. ## Отметить выполненным — `POST .../complete` / вернуть в работу — `POST .../renew` Удобные операции для переключения статуса пункта без полного `PATCH`: ```bash # Отметить выполненным curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/13/checklist/475/complete" \ -H "X-Api-Key: $VIBE_KEY" # Вернуть в работу curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/13/checklist/475/renew" \ -H "X-Api-Key: $VIBE_KEY" ``` ```json { "success": true, "data": { "id": 475, "isComplete": "Y" } } ``` `complete` эквивалентен `PATCH { "isComplete": true }`, `renew` — `PATCH { "isComplete": false }`. ## Типичный сценарий 1. Создать задачу: [`POST /v1/tasks`](./create.md). 2. (Опционально) создать чек-лист-контейнер: `POST /v1/tasks/:taskId/checklist` с `parentId: 0`. 3. Добавить пункты: `POST /v1/tasks/:taskId/checklist` (по одному; при необходимости укажите `parentId` контейнера). 4. Отметить пункт выполненным: `POST /v1/tasks/:taskId/checklist/:itemId/complete`. 5. Посмотреть прогресс: `GET /v1/tasks/:taskId/checklist`. ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `taskId`/`itemId` не положительное целое, отсутствует `title` при создании, пустое тело `PATCH`, неизвестное поле сортировки или некорректный `members` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ в режиме «только чтение» — переключите на чтение+запись в [/keys](/keys) | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 404 | `NOT_FOUND` | Пункт чек-листа не найден | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Задачи](../tasks.md) — родительская сущность - [Учёт времени](./time.md) — другой вложенный ресурс задачи - [Комментарии задач](/docs/entities/task-comments) — обсуждение задачи - [Сотрудники](/docs/entities/users) — источник `members` и `createdBy` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Tasks: Create ## Создать задачу `POST /v1/tasks` Создаёт новую задачу. Минимум — название и ответственный. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `title` | string | ★ | Название задачи | | `responsibleId` | number | ★ | Ответственный. Список сотрудников: `GET /v1/users` | | `description` | string | | Описание задачи. Поддерживает BB-код (`[USER=ID]Имя[/USER]`, `[B]...[/B]`, `[QUOTE]...[/QUOTE]`) | | `priority` | number | | Приоритет: `0` — низкий, `1` — обычный (по умолчанию), `2` — высокий | | `status` | number | | Статус. По умолчанию `2` (ждёт выполнения). Полный список значений: `GET /v1/tasks/fields` → `fields.status.enum` | | `deadline` | datetime | | Крайний срок (ISO 8601) | | `startDatePlan` | datetime | | Плановая дата начала | | `endDatePlan` | datetime | | Плановая дата окончания | | `timeEstimate` | number | | Оценка трудозатрат в секундах | | `groupId` | number | | Рабочая группа. Список: `GET /v1/workgroups` | | `parentId` | number | | Родительская задача. Список: `GET /v1/tasks` | | `accomplices` | number[] | | Соисполнители. Список сотрудников: `GET /v1/users` | | `auditors` | number[] | | Наблюдатели. Список сотрудников: `GET /v1/users` | | `tags` | string[] | | Метки задачи | Полный список полей — [`GET /v1/tasks/fields`](./fields.md). Поля `id`, `createdBy`, `createdDate`, `changedDate`, `closedDate` заполняются системой и в body не передаются. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Подготовить отчёт за квартал", "responsibleId": 1, "priority": 2, "deadline": "2026-05-19T18:00:00+03:00" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Подготовить отчёт за квартал", "responsibleId": 1, "priority": 2, "deadline": "2026-05-19T18:00:00+03:00" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Подготовить отчёт за квартал', responsibleId: 1, priority: 2, deadline: '2026-05-19T18:00:00+03:00', }), }) const { success, data } = await res.json() console.log('ID новой задачи:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Подготовить отчёт за квартал', responsibleId: 1, priority: 2, deadline: '2026-05-19T18:00:00+03:00', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Полный объект созданной задачи (как у `GET /v1/tasks/:id`) — см. [Поля задачи](./fields.md) | URL карточки задачи в Битрикс24 строится из `id` и ID сотрудника: ``` https://.bitrix24.ru/company/personal/user//tasks/task/view// ``` `` — ID ответственного (поле `responsibleId` в ответе): задача откроется в его личном кабинете. Сегмент `user/<...>` задаёт, в чьём кабинете отображается страница задач — подставьте ID нужного сотрудника, например текущего. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": "3871", "title": "Подготовить отчёт за квартал", "description": "", "status": "2", "priority": "2", "responsibleId": "1", "createdBy": "1", "createdDate": "2026-05-12T11:46:12+03:00", "deadline": "2026-05-19T18:00:00+03:00", "groupId": "0", "accomplices": [], "auditors": [], "creator": { "id": "1", "name": "Текущий пользователь", "link": "/company/personal/user/1/" }, "responsible": { "id": "1", "name": "Текущий пользователь", "link": "/company/personal/user/1/" } } } ``` ## Пример ответа при ошибке 400 — не указан ответственный: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Не указан исполнитель" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `BITRIX_ERROR` | Не передано обязательное поле (`title`, `responsibleId`) или поле содержит недопустимое значение | | 400 | `READONLY_FIELD` | В теле запроса передано поле, доступное только на чтение (`id`, `createdBy`, `createdDate`, `changedDate`, `closedDate`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Поля задачи](./fields.md) — что можно передавать - [Получить задачу](./get.md) — чтение деталей - [Обновить задачу](./update.md) — изменить состояние или сроки - [Список задач](./list.md) — поиск задач после создания - [Batch-запросы](/docs/batch) — массовое создание - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Tasks: Delete ## Удалить задачу `DELETE /v1/tasks/:id` Удаляет задачу. Восстановить удалённую задачу через API нельзя — создавайте новую при необходимости. Вместе с задачей становятся недоступными её комментарии и записи учёта времени. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID задачи | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/tasks/3871" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/tasks/3871" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/3871', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Задача удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/3871', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — задача не найдена (или уже удалена): ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "task 999999999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Задача с таким ID не найдена (в том числе если она уже была удалена) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Каскадное удаление вложенных ресурсов.** После удаления задачи становятся недоступными её комментарии и записи учёта времени — отдельный `DELETE` для каждого из них не нужен. Попытка обратиться к ним по прежнему ID вернёт `422 BITRIX_ERROR` с сообщением `ITEM_NOT_FOUND_OR_NOT_ACCESSIBLE`. ## Смотрите также - [Список задач](./list.md) — найти задачу перед удалением - [Получить задачу](./get.md) — проверить состояние перед удалением - [Обновить задачу](./update.md) — альтернатива: перевести в статус `6` (отложена), если задача может понадобиться позже - [Batch-запросы](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Tasks: Fields ## Поля задачи `GET /v1/tasks/fields` Возвращает схему полей задачи: типы, флаги «только чтение», статические перечисления значений для `status` и `priority`. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) console.log('Значения status:', data.fields.status.enum) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Ниже — основные поля, описанные в API. В ответе также возвращаются их UPPER_SNAKE_CASE-эквиваленты Битрикс24 (`TITLE`, `RESPONSIBLE_ID`, `CREATED_DATE` и др.) — оставлены ради обратной совместимости. | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `ID` | number | да | Идентификатор задачи | | `title` | `TITLE` | string | | Название задачи | | `description` | `DESCRIPTION` | string | | Описание (поддерживает BB-код) | | `responsibleId` | `RESPONSIBLE_ID` | number | | Ответственный. Список: `GET /v1/users` | | `createdBy` | `CREATED_BY` | number | да | Постановщик. Список: `GET /v1/users` | | `status` | `STATUS` | number | | Статус задачи. Допустимые значения в `fields.status.enum` | | `priority` | `PRIORITY` | number | | Приоритет задачи. Допустимые значения в `fields.priority.enum` | | `groupId` | `GROUP_ID` | number | | Рабочая группа. Список: `GET /v1/workgroups` | | `parentId` | `PARENT_ID` | number | | Родительская задача. Список: `GET /v1/tasks` | | `deadline` | `DEADLINE` | datetime | | Крайний срок (ISO 8601) | | `dateStart` | `DATE_START` | datetime | да | Фактическая дата начала работы над задачей. Фильтруется: `?filter[>=dateStart]=2026-05-01T00:00:00` | | `startDatePlan` | `START_DATE_PLAN` | datetime | | Плановая дата начала | | `endDatePlan` | `END_DATE_PLAN` | datetime | | Плановая дата окончания | | `timeEstimate` | `TIME_ESTIMATE` | number | | Оценка трудозатрат в секундах | | `tags` | `TAGS` | object \| array | | Метки задачи. У задачи С метками — объект-словарь `{ "": { "id": , "title": "<метка>" } }`; у задачи БЕЗ меток приходит пустой массив `[]` (а не пустой объект) — тип зависит от данных, проверяйте `Array.isArray()` перед обращением по ключу. Фильтр по одной метке: `?filter[tags]=метка` (транслируется в B24 `TAG`) | | `accomplices` | `ACCOMPLICES` | array | | Соисполнители. Список: `GET /v1/users`. Фильтр по одному пользователю: `?filter[accomplices]=25` (транслируется в B24 `ACCOMPLICE`) | | `auditors` | `AUDITORS` | array | | Наблюдатели. Список: `GET /v1/users`. Фильтр по одному пользователю: `?filter[auditors]=25` (транслируется в B24 `AUDITOR`) | | `closedDate` | `CLOSED_DATE` | datetime | да | Дата закрытия (заполняется при переводе в статус `5` или `6`) | | `createdDate` | `CREATED_DATE` | datetime | да | Дата создания | | `changedDate` | `CHANGED_DATE` | datetime | да | Дата последнего изменения | **Расшифровка `status`** — поле `fields.status.enum`: | Значение | Метка | Описание | |----------|-------|----------| | `1` | New | Начальное состояние. Новые задачи создаются со статусом `2`; `1` встречается у задач, импортированных из внешних систем или мигрированных со старых версий портала | | `2` | Pending | Ждёт выполнения. Статус по умолчанию для новых задач | | `3` | In Progress | Выполняется | | `4` | Awaiting Control | Ожидает контроля. Исполнитель пометил задачу как сделанную, постановщик должен подтвердить | | `5` | Completed | Завершена | | `6` | Deferred | Отложена | | `7` | Declined | Отклонена | **Расшифровка `priority`** — поле `fields.priority.enum`: | Значение | Метка | |----------|-------| | `0` | Низкий | | `1` | Обычный | | `2` | Высокий | **Пользовательские поля (`UF_*`)** принимаются при создании/обновлении и в фильтрах в обоих написаниях — `ufCrmTask` и `UF_CRM_TASK` (camelCase конвертируется автоматически). ⚠ `UF_CRM_TASK` (привязка к CRM) принимает **массив** идентификаторов привязок — `["D_123"]` (сделка), `["C_45"]` (контакт), `["CO_7"]` (компания), `["L_9"]` (лид). Строка вместо массива (`"D_123"`) молча игнорируется Bitrix24 — значение не сохранится (проверено на живом портале). **Нульность.** Многие необязательные поля приходят `null`, когда не заполнены: `parentId`, `dateStart`, `startDatePlan`, `endDatePlan`, `deadline`, `closedBy`, `closedDate`, `mark`, `sprintId`, `backlogId`, `durationFact`, `durationPlan`, `timeSpentInLogs`, `sorting`, `flowId`, `xmlId`, `ufCrmTask`, `ufMailMessage` и др. Типобезопасным клиентам (TS) объявляйте такие поля как `T | null`. Документированные пустые случаи `accomplices`/`auditors`/`checklist` приходят как `[]`; **`tags` — исключение**: без меток приходит `[]`, с метками — объект (см. выше). ## Пример ответа Показаны основные поля. Полный ответ дополнительно содержит UPPER_SNAKE-эквиваленты и системные служебные поля. ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "title": { "type": "string", "readonly": false }, "description": { "type": "string", "readonly": false }, "responsibleId": { "type": "number", "readonly": false }, "createdBy": { "type": "number", "readonly": true }, "status": { "type": "number", "readonly": false, "enum": [ { "value": 1, "label": "New", "labelRu": "Новая" }, { "value": 2, "label": "Pending", "labelRu": "Ждёт выполнения" }, { "value": 3, "label": "In Progress", "labelRu": "Выполняется" }, { "value": 4, "label": "Awaiting Control", "labelRu": "Ожидает контроля" }, { "value": 5, "label": "Completed", "labelRu": "Завершена" }, { "value": 6, "label": "Deferred", "labelRu": "Отложена" }, { "value": 7, "label": "Declined", "labelRu": "Отклонена" } ] }, "priority": { "type": "number", "readonly": false, "enum": [ { "value": 0, "label": "Low", "labelRu": "Низкий" }, { "value": 1, "label": "Normal", "labelRu": "Обычный" }, { "value": 2, "label": "High", "labelRu": "Высокий" } ] }, "deadline": { "type": "datetime", "readonly": false }, "createdDate": { "type": "datetime", "readonly": true }, "changedDate": { "type": "datetime", "readonly": true } } } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'tasks' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать задачу](./create.md) — какие поля передавать - [Обновить задачу](./update.md) — какие поля можно изменять - [Список задач](./list.md) — фильтрация и сортировка по полям - [Поиск задач](./search.md) — те же поля в POST-варианте - [Агрегация задач](./aggregate.md) — группировка по полям - [Entity API](/docs/entity-api) — `select` для выборки нужных полей --- # Tasks: Get ## Получить задачу `GET /v1/tasks/:id` Возвращает одну задачу со всеми полями. Дополнительно к полям списка приходят встроенные объекты постановщика и ответственного, чек-лист, разрешённые действия и расширенная информация о соисполнителях и наблюдателях. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID задачи | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log(data.title, '— статус:', data.status) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект задачи. Базовые поля — см. [Поля задачи](./fields.md). Дополнительные блоки описаны ниже | **Дополнительные блоки одиночного ответа:** | Поле | Тип | Описание | |------|-----|---------| | `data.creator` | object | Постановщик: `{ id, name, link, icon, workPosition }` | | `data.responsible` | object | Ответственный: тот же формат, что и `creator` | | `data.accomplicesData` | object[] | Подробности по соисполнителям (тот же формат, что и `creator`) | | `data.auditorsData` | object[] | Подробности по наблюдателям (тот же формат, что и `creator`) | | `data.action` | object | Карта разрешённых действий (boolean): `complete`, `start`, `pause`, `delegate`, `remove`, `edit`, `defer`, `changeDeadline`, `checklistAddItems` и другие | | `data.checklist` | array | Пункты чек-листа (пустой массив, если чек-лист не заполнен) | | `data.checkListTree` | object | Дерево чек-листа с метаданными | | `data.newCommentsCount` | number | Количество непрочитанных комментариев | ## Пример ответа ```json { "success": true, "data": { "id": "289", "title": "Подготовить отчёт за квартал", "description": "", "status": "2", "priority": "1", "groupId": "0", "responsibleId": "79", "createdBy": "99", "createdDate": "2026-05-12T09:11:18+03:00", "changedDate": "2026-05-12T09:11:18+03:00", "deadline": "2026-05-19T18:00:00+03:00", "accomplices": [], "auditors": [], "checklist": [], "creator": { "id": "99", "name": "Анна Соколова", "link": "/company/personal/user/99/", "icon": "https://example.bitrix24.ru/.../avatar.png", "workPosition": null }, "responsible": { "id": "79", "name": "Дмитрий Орлов", "link": "/company/personal/user/79/", "icon": "/bitrix/images/tasks/default_avatar.png", "workPosition": null }, "newCommentsCount": 0, "action": { "complete": true, "start": true, "delegate": true, "edit": true, "remove": true, "defer": true, "changeDeadline": true } } } ``` ## Пример ответа при ошибке 404 — задача не найдена: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "task 999999999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Задача с таким ID не найдена | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Встроенные данные пользователей.** Поля `creator` и `responsible` приходят вложенным объектом с именем, ссылкой на профиль и аватаркой. Отдельный `GET /v1/users/:id` для отображения автора задачи не требуется. **Числовые значения как строки.** Большинство числовых полей (`id`, `status`, `priority`, `responsibleId`, `createdBy`, `groupId` и подобные) приходят строками. Для арифметики и сравнений приводите через `Number(value)`. Исключения: `newCommentsCount` приходит **числом** (и в списке, и в карточке); `commentsCount`/`serviceCommentsCount` приходят либо `null`, либо строкой (`"0"`/`"N"`) — числом не бывают. `chatId` непоследователен: в списке строка (`"255"`), в карточке число (`255`) — приводите через `Number()`. ## Смотрите также - [Список задач](./list.md) — поиск задачи перед чтением - [Поля задачи](./fields.md) — полный список полей и расшифровка значений `status`/`priority` - [Обновить задачу](./update.md) — изменить состояние или сроки - [Удалить задачу](./delete.md) — снять задачу - [Комментарии задачи](/docs/entities/task-comments) — обсуждение - [Учёт времени](./time.md) — записи о трудозатратах - [Чек-лист задачи](./checklist.md) — пункты чек-листа (add/update/complete) - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Tasks: List ## Список задач `GET /v1/tasks` Возвращает список задач портала с поддержкой фильтрации, сортировки и авто-пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` API автоматически запрашивает несколько страниц | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `select` | string | — | Выборка полей: `?select=id,title,status,responsibleId` | | `order` | object | `id desc` | Сортировка: `?order[id]=desc`, `?order[createdDate]=desc` | | `filter` | object | — | Фильтрация по полям `GET /v1/tasks/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[status]=2&filter[responsibleId]=1` | > ⚠ **Какие даты фильтруются.** B24 `tasks.task.list` поддерживает фильтры по `createdDate`, `changedDate`, `closedDate`, `deadline`, `dateStart`. Поля `statusChangedDate` и `activityDate` **не фильтруются** на стороне Bitrix24 (их нет в списке фильтруемых полей метода) — такой фильтр будет молча проигнорирован; используйте `changedDate` как ближайшую замену. Соисполнители/наблюдатели фильтруются по одному пользователю: `?filter[accomplices]=25`, `?filter[auditors]=25`; метки — `?filter[tags]=метка`. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/tasks?limit=10&filter[status]=2&order[id]=desc" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/tasks?limit=10&filter[status]=2&order[id]=desc" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const url = 'https://vibecode.bitrix24.tech/v1/tasks?limit=10&filter[status]=2&order[id]=desc' const res = await fetch(url, { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Получено ${data.length} из ${meta.total} задач`) ``` ### JavaScript — OAuth-приложение ```javascript const url = 'https://vibecode.bitrix24.tech/v1/tasks?limit=10&filter[status]=2&order[id]=desc' const res = await fetch(url, { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив задач (все поля — см. [Поля задачи](./fields.md)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | URL карточки любой задачи из массива `data` строится из её `id` и ID сотрудника: ``` https://.bitrix24.ru/company/personal/user//tasks/task/view// ``` `` — ID ответственного (поле `responsibleId` каждого элемента): задача откроется в его личном кабинете. Сегмент `user/<...>` задаёт, в чьём кабинете отображается страница задач — подставьте ID нужного сотрудника, например текущего. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": "289", "title": "Подготовить отчёт за квартал", "status": "2", "priority": "1", "responsibleId": "79", "createdBy": "99", "createdDate": "2026-05-12T09:11:18+03:00", "deadline": "2026-05-19T18:00:00+03:00", "groupId": "0", "accomplices": [], "auditors": [], "creator": { "id": "99", "name": "Анна Соколова", "link": "/company/personal/user/99/" }, "responsible": { "id": "79", "name": "Дмитрий Орлов", "link": "/company/personal/user/79/" } } ], "meta": { "total": 184, "hasMore": true } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'tasks' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Передан некорректный или несуществующий ключ | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Когда переходить на `POST /v1/tasks/search`.** Если у запроса много условий фильтра или нужна выгрузка по большому диапазону дат, выбирайте `POST /v1/tasks/search` — параметры передаются в body, плюс доступно автоматическое разбиение запроса по временны́м окнам для выборок свыше 5000 записей. См. [Поиск задач](./search.md). **Числовые значения как строки.** Поля-идентификаторы и числовые перечисления (`id`, `status`, `priority`, `responsibleId`, `createdBy`, `groupId`) приходят в виде строк. Для арифметики и сравнений приводите через `Number(value)`. ## Смотрите также - [Получить задачу](./get.md) — одна задача по ID - [Поиск задач](./search.md) — POST с фильтрами в body и разбиением выборки по временны́м окнам - [Поля задачи](./fields.md) — полный список полей и расшифровка `status`/`priority` - [Агрегация задач](./aggregate.md) — подсчёт и группировка - [Синтаксис фильтрации](/docs/filtering) - [Batch-запросы](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Tasks: Search ## Поиск задач `POST /v1/tasks/search` Поиск задач с фильтрами и сортировкой. Аналог `GET /v1/tasks`, но параметры передаются в теле запроса — подходит для длинных и сложных фильтров. Дополнительно поддерживает автоматическое разбиение запроса по временны́м окнам для выборок свыше 5000 записей. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/tasks/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `{"status": 2, "responsibleId": 1}` | | `select` | string[] | — | Выборка полей: `["id", "title", "status", "responsibleId"]` | | `order` | object | `id desc` | Сортировка: `{ "createdDate": "desc" }` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `autoWindow` | boolean | `false` | Разбить запрос по временны́м окнам — обход лимита Битрикс24 в 5000 записей на один вызов | | `windowFrom` | datetime | — | Начало диапазона для разбиения по временны́м окнам (ISO 8601) | | `windowTo` | datetime | — | Конец диапазона для разбиения по временны́м окнам (ISO 8601) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "status": 2, "responsibleId": 1 }, "select": ["id", "title", "status", "deadline"], "order": { "id": "desc" }, "limit": 50 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "status": 2, "responsibleId": 1 }, "select": ["id", "title", "status", "deadline"], "order": { "id": "desc" }, "limit": 50 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { status: 2, responsibleId: 1 }, select: ['id', 'title', 'status', 'deadline'], order: { id: 'desc' }, limit: 50, }), }) const { success, data, meta } = await res.json() console.log(`Найдено ${data.length} из ${meta.total} задач`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { status: 2, responsibleId: 1 }, select: ['id', 'title', 'status', 'deadline'], order: { id: 'desc' }, limit: 50, }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив задач (все поля — см. [Поля задачи](./fields.md)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | | `meta.durationMs` | number | Длительность выполнения запроса в миллисекундах | | `meta.autoWindowed` | boolean | `true`, если запрос был разбит по временны́м окнам | | `meta.windowCount` | number | Количество окон (только при `autoWindowed: true`) | | `meta.batchWaves` | number | Сколько волн параллельных запросов потребовалось (только при `autoWindowed: true`) | URL карточки любой задачи из массива `data` строится из её `id` и ID сотрудника: ``` https://.bitrix24.ru/company/personal/user//tasks/task/view// ``` `` — ID ответственного (поле `responsibleId` каждого элемента): задача откроется в его личном кабинете. Сегмент `user/<...>` задаёт, в чьём кабинете отображается страница задач — подставьте ID нужного сотрудника, например текущего. `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": "289", "title": "Подготовить отчёт за квартал", "status": "2", "deadline": "2026-05-19T18:00:00+03:00" }, { "id": "311", "title": "Свериться с бухгалтерией", "status": "2", "deadline": "2026-05-15T17:00:00+03:00" } ], "meta": { "total": 182, "hasMore": true, "durationMs": 1226 } } ``` С `autoWindow: true` дополнительно появятся `autoWindowed`, `windowCount`, `batchWaves`: ```json { "success": true, "data": [ /* ... */ ], "meta": { "total": 50, "hasMore": false, "autoWindowed": true, "windowCount": 157, "batchWaves": 4, "durationMs": 4357 } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'tasks' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 502 | `WINDOWED_SEARCH_FAILED` | При `autoWindow: true` все под-окна вернули ошибку — повторите запрос с более узким диапазоном дат | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Когда выбирать search вместо list.** `GET /v1/tasks` подходит для коротких фильтров в URL. `POST /v1/tasks/search` применяется, когда условий много — вложенные объекты, массивы, диапазоны дат: параметры в теле читаются и собираются проще, чем длинная query-строка. **Разбиение по временны́м окнам.** Если задач больше 5000, передайте `autoWindow: true` вместе с диапазоном `windowFrom`/`windowTo`. Запрос автоматически разбивается на окна, выполняется параллельными волнами, и в `meta` приходит число окон (`windowCount`) и волн (`batchWaves`). Этим обходится лимит Битрикс24 в 5000 записей на один вызов. **Числовые значения как строки.** Поля-идентификаторы и числовые перечисления (`id`, `status`, `priority`, `responsibleId`, `createdBy`, `groupId`) приходят строками. Для арифметики и сравнений приводите через `Number(value)`. ## Смотрите также - [Список задач](./list.md) — GET-вариант с query-параметрами - [Поля задачи](./fields.md) — какие поля принимает `filter` и `select` - [Агрегация задач](./aggregate.md) — подсчёт и группировка - [Синтаксис фильтрации](/docs/filtering) - [Batch-запросы](/docs/batch) — объединение нескольких запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Tasks: Time # Учёт времени задач Записи о потраченном на задачу времени — вложенный ресурс задачи. У каждой записи есть длительность, автор, комментарий и время создания. Базовый путь — `/v1/tasks/:taskId/time`. Все операции требуют существующей задачи (`:taskId`) на портале. Битрикс24 API: `task.elapseditem.*` Скоуп: `task` ## Операции - [Добавить запись](./time/create.md) — `POST /v1/tasks/:taskId/time` - [Список записей](./time/list.md) — `GET /v1/tasks/:taskId/time` - [Получить запись](./time/get.md) — `GET /v1/tasks/:taskId/time/:itemId` - [Обновить запись](./time/update.md) — `PATCH /v1/tasks/:taskId/time/:itemId` - [Удалить запись](./time/delete.md) — `DELETE /v1/tasks/:taskId/time/:itemId` - **Глобальный список (по сотруднику и периоду)** — `GET /v1/task-time?userId=&from=&to=` (см. ниже) ## Глобальный список — `GET /v1/task-time` Возвращает записи учёта времени **по всему порталу** одним запросом — без необходимости перебирать задачи по очереди. Удобно для сценариев «сколько времени сотрудник X потратил за месяц», когда заранее неизвестен список задач. ### Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `userId` | number | нет | Идентификатор сотрудника. Без параметра — записи всех сотрудников, к которым у владельца ключа есть доступ | | `from` | string | нет | Нижняя граница периода (включительно) — по полю `CREATED_DATE`. Принимает ISO 8601 (`2026-05-01T00:00:00+03:00`) и сокращённую дату (`2026-05-01`) | | `to` | string | нет | Верхняя граница периода (включительно) — по полю `CREATED_DATE`. Формат — как у `from` | | `taskId` | number | нет | Сузить выборку до одной задачи (опциональный фильтр поверх `userId` / `from` / `to`) | | `limit` | number | нет | Количество записей на странице (1..500, по умолчанию 50) | | `offset` | number | нет | Смещение в выборке (по умолчанию 0). Конвертируется в номер страницы для Битрикс24 | ### Пример ```bash curl "https://vibecode.bitrix24.tech/v1/task-time?userId=5&from=2026-05-01&to=2026-05-31&limit=200" \ -H "X-Api-Key: $VIBE_KEY" ``` ### Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив записей учёта времени. Ключи в camelCase (`id`, `userId`, `taskId`, `seconds`, `minutes`, `commentText`, `source`, `createdDate`, `dateStart`, `dateStop`) | | `meta.total` | number | Общее число записей в выборке (соответствует фильтру) | | `meta.limit` | number | Применённый лимит на странице | | `meta.offset` | number | Применённое смещение | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами текущей страницы | ### Пример ответа ```json { "success": true, "data": [ { "id": "13", "userId": "5", "taskId": "100", "seconds": "1800", "minutes": "30", "commentText": "Code review", "createdDate": "2026-05-20T10:00:00+03:00", "dateStart": "2026-05-20T11:00:00+03:00", "dateStop": "2026-05-20T11:30:00+03:00", "source": "2" } ], "meta": { "total": 247, "limit": 50, "offset": 0, "hasMore": true } } ``` ### Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_USER_ID` | `userId` не положительное целое число | | 400 | `INVALID_TASK_ID` | `taskId` не положительное целое число | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | ## Ключевые поля | Поле | Описание | |------|---------| | `id` | Идентификатор записи | | `taskId` | ID родительской задачи | | `userId` | Автор. Список сотрудников: `GET /v1/users` | | `seconds` | Длительность в секундах (основное поле — задаётся при создании) | | `minutes` | Длительность в минутах (производное от `seconds`, заполняется системой) | | `commentText` | Комментарий к записи (`""`, если комментарий пуст — не `null`) | | `source` | Источник: `2` — REST API (записи, созданные через этот эндпоинт) | | `createdDate` | Дата создания записи | | `dateStart`, `dateStop` | Начало и окончание учтённого интервала. Заполняются автоматически и через текущий API не редактируются | ## Что нужно знать перед работой 1. **Поля ответа — в camelCase.** Записи учёта времени возвращаются в camelCase (`id`, `taskId`, `userId`, `seconds`, `minutes`, `commentText`, `source`, `createdDate`, `dateStart`, `dateStop`) — как и комментарии задач, и остальная часть API. (Ранее документация ошибочно обещала UPPER_SNAKE_CASE.) 2. **Числовые значения сериализуются строками.** `id`, `taskId`, `userId`, `seconds`, `minutes`, `source` приходят в виде строк (`"seconds": "900"`) — и в per-task списке/карточке, и в глобальном `/v1/task-time`. Для арифметики приводите через `Number(value)`. 3. **`seconds` — единственная единица измерения при записи.** Параметр `seconds` обязателен; `minutes` система пересчитывает сама. 4. **Записи удаляются вместе с задачей.** Если родительская задача удалена ([`DELETE /v1/tasks/:id`](./delete.md)), её записи учёта времени становятся недоступны — отдельный `DELETE` для каждой не требуется. Попытка обратиться к ним по прежнему ID вернёт `422`. 5. **`dateStart` и `dateStop` через API не редактируются.** Их значения заполняются Битрикс24 автоматически в момент создания записи. Чтобы зафиксировать конкретный интервал, передавайте суммарное время через `seconds` в `POST` или `PATCH`. NB: Битрикс24 систематически проставляет интервал на ~1 час впереди `createdDate` (автозаполнение на своей стороне) — это поведение B24, обёртка даты не трогает. 6. **Список может показывать записи, недоступные карточке.** Глобальный/per-task список (`task.elapseditem.getlist`) и карточка (`task.elapseditem.get`) — разные методы B24 с разными проверками доступа: список иногда возвращает чужие записи, по которым карточка отдаёт `422 ITEM_NOT_FOUND_OR_NOT_ACCESSIBLE`. Это рассогласование доступа на стороне Битрикс24. ## Типичный сценарий 1. Найти или создать задачу: [`GET /v1/tasks`](./list.md) / [`POST /v1/tasks`](./create.md). 2. Добавить запись: [`POST /v1/tasks/:taskId/time`](./time/create.md) с `seconds` и при необходимости `comment` и `userId`. 3. Посмотреть историю учёта: [`GET /v1/tasks/:taskId/time`](./time/list.md). 4. Скорректировать длительность или комментарий: [`PATCH /v1/tasks/:taskId/time/:itemId`](./time/update.md). 5. Удалить ошибочную запись: [`DELETE /v1/tasks/:taskId/time/:itemId`](./time/delete.md). ## Лимиты | Лимит | Значение | |-------|----------| | Rate limit | общий для API — см. [Лимиты и оптимизация](/docs/optimization) | ## Смотрите также - [Задачи](../tasks.md) — родительская сущность - [Комментарии задач](../task-comments.md) — другой вложенный ресурс задачи - [Сотрудники](/docs/entities/users) — источник `USER_ID` - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Tasks: Create ## Добавить запись учёта времени `POST /v1/tasks/:taskId/time` Создаёт новую запись учёта времени для задачи. Обязательное поле — `seconds`; комментарий и автор передаются опционально. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `seconds` | number | ★ | Длительность в секундах | | `comment` | string | | Комментарий к записи. Записывается в `COMMENT_TEXT` | | `userId` | number | | ID автора. По умолчанию — пользователь API-ключа. Список сотрудников: `GET /v1/users` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/289/time" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "seconds": 1800, "comment": "Подготовка черновика" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/tasks/289/time" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "seconds": 1800, "comment": "Подготовка черновика" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ seconds: 1800, comment: 'Подготовка черновика', }), }) const { success, data } = await res.json() console.log('ID новой записи:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ seconds: 1800, comment: 'Подготовка черновика', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор созданной записи. Используйте его для `GET` / `PATCH` / `DELETE` | ## Пример ответа HTTP 201 Created: ```json { "success": true, "data": { "id": 161 } } ``` ## Пример ответа при ошибке 400 — не передан обязательный `seconds`: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: seconds (number)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передано поле `seconds` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (например, родительская задача недоступна или `userId` не существует) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Ответ — только `id`, без остальных полей.** В отличие от создания задачи или комментария, метод возвращает только идентификатор. Чтобы получить полную запись с автогенерированными `MINUTES`, `SOURCE`, `CREATED_DATE`, `DATE_START`, `DATE_STOP` — сделайте [`GET /v1/tasks/:taskId/time/:itemId`](./get.md). ## Смотрите также - [Получить запись](./get.md) — прочитать только что созданную запись со всеми полями - [Список записей](./list.md) — все записи задачи - [Обновить запись](./update.md) — изменить длительность или комментарий - [Удалить запись](./delete.md) — снять запись - [Задачи](/docs/entities/tasks) — родительская сущность --- # Tasks: Delete ## Удалить запись учёта времени `DELETE /v1/tasks/:taskId/time/:itemId` Удаляет запись учёта времени. Восстановить её через API нельзя — создавайте новую при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | | `itemId` (path) | number | да | ID записи учёта времени | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/tasks/289/time/161" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/tasks/289/time/161" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time/161', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Запись удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time/161', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — запись не найдена или недоступна: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "TASKS_ERROR_EXCEPTION_#512; Check listitem not found or not accessible; 512/TE/ITEM_NOT_FOUND_OR_NOT_ACCESSIBLE" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Запись с таким `itemId` не найдена (в том числе если она или родительская задача уже удалены) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список записей](./list.md) — найти запись перед удалением - [Получить запись](./get.md) — проверить состояние перед удалением - [Обновить запись](./update.md) — альтернатива удалению: исправить ошибочное значение - [Задачи](/docs/entities/tasks) — родительская сущность --- # Tasks: Get ## Получить запись учёта времени `GET /v1/tasks/:taskId/time/:itemId` Возвращает одну запись учёта времени по её идентификатору. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | | `itemId` (path) | number | да | ID записи учёта времени (из [`GET /v1/tasks/:taskId/time`](./list.md) или ответа [`POST /v1/tasks/:taskId/time`](./create.md)) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/time/161" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/time/161" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time/161', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log(`Минут потрачено: ${data.minutes}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time/161', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | string | Идентификатор записи | | `data.taskId` | string | ID родительской задачи | | `data.userId` | string | Автор. Профиль: `GET /v1/users/:userId` | | `data.seconds` | string | Длительность в секундах | | `data.minutes` | string | Длительность в минутах (производное от `seconds`) | | `data.commentText` | string | Комментарий к записи | | `data.source` | string | Источник: `2` — REST API | | `data.createdDate` | datetime | Когда запись была создана | | `data.dateStart` | datetime | Начало учтённого интервала | | `data.dateStop` | datetime | Окончание учтённого интервала | ## Пример ответа ```json { "success": true, "data": { "id": "161", "taskId": "289", "userId": "1", "commentText": "Подготовка черновика", "seconds": "900", "minutes": "15", "source": "2", "createdDate": "2026-05-13T16:15:41+03:00", "dateStart": "2026-05-13T17:15:41+03:00", "dateStop": "2026-05-13T17:15:41+03:00" } } ``` ## Пример ответа при ошибке 422 — запись не найдена или недоступна: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "TASKS_ERROR_EXCEPTION_#512; Check listitem not found or not accessible; 512/TE/ITEM_NOT_FOUND_OR_NOT_ACCESSIBLE" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Запись с таким `itemId` не найдена или родительская задача недоступна | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список записей](./list.md) — найти `itemId` нужной записи - [Обновить запись](./update.md) — изменить длительность или комментарий - [Удалить запись](./delete.md) — снять запись - [Задачи](/docs/entities/tasks) — родительская сущность --- # Tasks: List ## Список записей учёта времени `GET /v1/tasks/:taskId/time` Возвращает все записи учёта времени конкретной задачи, отсортированные по `id` (сначала новые). ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `taskId` (path) | number | да | — | ID задачи | | `limit` (query) | number | | `50` | Размер страницы | | `offset` (query) | number | | `0` | Пропустить N записей | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/time" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/tasks/289/time" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() const totalSeconds = data.reduce((sum, r) => sum + Number(r.seconds), 0) console.log(`Всего по задаче: ${totalSeconds / 60} мин`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив записей учёта времени | | `data[].id` | string | Идентификатор записи | | `data[].taskId` | string | ID родительской задачи | | `data[].userId` | string | Автор. Профиль: `GET /v1/users/:userId` | | `data[].seconds` | string | Длительность в секундах | | `data[].minutes` | string | Длительность в минутах (производное от `seconds`) | | `data[].commentText` | string | Комментарий к записи | | `data[].source` | string | Источник: `2` — REST API | | `data[].createdDate` | datetime | Когда запись была создана | | `data[].dateStart` | datetime | Начало учтённого интервала (заполняется автоматически) | | `data[].dateStop` | datetime | Окончание учтённого интервала (заполняется автоматически) | | `meta.total` | number | Количество записей в текущем ответе | ## Пример ответа ```json { "success": true, "data": [ { "id": "163", "taskId": "289", "userId": "1", "commentText": "Подготовка черновика", "seconds": "1800", "minutes": "30", "source": "2", "createdDate": "2026-05-13T16:15:43+03:00", "dateStart": "2026-05-13T17:15:43+03:00", "dateStop": "2026-05-13T17:15:43+03:00" }, { "id": "161", "taskId": "289", "userId": "1", "commentText": "", "seconds": "600", "minutes": "10", "source": "2", "createdDate": "2026-05-13T16:15:41+03:00", "dateStart": "2026-05-13T17:15:41+03:00", "dateStop": "2026-05-13T17:15:41+03:00" } ], "meta": { "total": 2 } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'task' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку при чтении — например, родительская задача отсутствует или удалена | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Сортировка по убыванию `id`.** Сначала возвращаются последние добавленные записи; `limit` + `offset` работают поверх этой сортировки. **`meta.total` равен длине текущей страницы.** Эндпоинт не возвращает общее число записей по фильтру — `meta.total` фиксирует лишь длину `data` в этом ответе. Для полного обхода используйте `offset`-пагинацию и проверяйте пустой ответ как признак конца выборки. ## Смотрите также - [Получить запись](./get.md) — одна запись по `id` - [Добавить запись](./create.md) — создание новой записи - [Обновить запись](./update.md) — изменить длительность или комментарий - [Удалить запись](./delete.md) — снять запись - [Задачи](/docs/entities/tasks) — родительская сущность --- # Tasks: Update ## Обновить запись учёта времени `PATCH /v1/tasks/:taskId/time/:itemId` Изменяет существующую запись учёта времени. Передавайте только изменяемые поля. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `taskId` (path) | number | да | ID задачи | | `itemId` (path) | number | да | ID записи учёта времени | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `seconds` | number | | Новая длительность в секундах. После обновления `MINUTES` пересчитывается автоматически | | `comment` | string | | Новый комментарий к записи | | `userId` | number | | Новый автор. Список сотрудников: `GET /v1/users` | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/tasks/289/time/161" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "seconds": 900, "comment": "Уточнённая оценка" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/tasks/289/time/161" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "seconds": 900, "comment": "Уточнённая оценка" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time/161', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ seconds: 900, comment: 'Уточнённая оценка', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/289/time/161', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ seconds: 900, comment: 'Уточнённая оценка', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успешном обновлении | | `data.id` | number | Идентификатор обновлённой записи | ## Пример ответа ```json { "success": true, "data": { "id": 161 } } ``` ## Пример ответа при ошибке 422 — запись не найдена или недоступна: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "TASKS_ERROR_EXCEPTION_#512; Check listitem not found or not accessible; 512/TE/ITEM_NOT_FOUND_OR_NOT_ACCESSIBLE" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Запись с таким `itemId` не найдена или родительская задача недоступна | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `task` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Ответ — только `id`, без остальных полей.** Чтобы прочитать обновлённую запись со всеми полями, сделайте [`GET /v1/tasks/:taskId/time/:itemId`](./get.md). ## Смотрите также - [Получить запись](./get.md) — прочитать запись после обновления - [Список записей](./list.md) — все записи задачи - [Добавить запись](./create.md) — создать новую - [Удалить запись](./delete.md) — снять запись - [Задачи](/docs/entities/tasks) — родительская сущность --- # Tasks: Update ## Обновить задачу `PATCH /v1/tasks/:id` Обновляет поля существующей задачи. Передавайте только изменяемые поля. Полный список — [Поля задачи](./fields.md). ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID задачи | ## Поля запроса (body) Передавайте только изменяемые поля — поведение PATCH, остальные значения не затрагиваются. | Поле | Тип | Описание | |------|-----|---------| | `title` | string | Название | | `description` | string | Описание задачи (поддерживает BB-код) | | `responsibleId` | number | Новый ответственный. Список сотрудников: `GET /v1/users` | | `status` | number | Статус задачи. Полный список значений: `GET /v1/tasks/fields` → `fields.status.enum` | | `priority` | number | Приоритет: `0` — низкий, `1` — обычный, `2` — высокий | | `deadline` | datetime | Крайний срок (ISO 8601) | | `startDatePlan` | datetime | Плановая дата начала | | `endDatePlan` | datetime | Плановая дата окончания | | `timeEstimate` | number | Оценка трудозатрат в секундах | | `groupId` | number | Рабочая группа. Список: `GET /v1/workgroups` | | `parentId` | number | Родительская задача. Список: `GET /v1/tasks` | | `accomplices` | number[] | Соисполнители. Список сотрудников: `GET /v1/users` | | `auditors` | number[] | Наблюдатели. Список сотрудников: `GET /v1/users` | | `tags` | string[] | Метки задачи | Поля `id`, `createdBy`, `createdDate`, `changedDate`, `closedDate` — read-only, в body не передаются. Попытка → `400 READONLY_FIELD`. ## Часто обновляемые поля | Поле | Когда используется | |------|-------------------| | `status` | Закрытие (`5`), возврат в работу (`3`), отказ (`7`). Расшифровка: `GET /v1/tasks/fields` → `fields.status.enum` | | `responsibleId` | Передача задачи другому сотруднику. Источник: `GET /v1/users` | | `deadline` | Перенос срока (ISO 8601 со смещением часового пояса портала) | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/tasks/3871" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "status": 5, "priority": 2 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/tasks/3871" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "status": 5, "priority": 2 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/3871', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ status: 5, priority: 2, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/tasks/3871', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ status: 5, priority: 2, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Обновлённый объект задачи со всеми полями — см. [Поля задачи](./fields.md) | ## Пример ответа ```json { "success": true, "data": { "id": "3871", "title": "Подготовить отчёт за квартал", "status": "5", "priority": "2", "responsibleId": "1", "createdBy": "1", "createdDate": "2026-05-12T11:46:12+03:00", "changedDate": "2026-05-12T13:02:48+03:00", "closedDate": "2026-05-12T13:02:48+03:00", "deadline": "2026-05-19T18:00:00+03:00", "accomplices": [], "auditors": [] } } ``` ## Пример ответа при ошибке 400 — попытка изменить read-only поле: ```json { "success": false, "error": { "code": "READONLY_FIELD", "message": "Field 'createdBy' is read-only and cannot be set" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Задача с таким ID не найдена | | 400 | `READONLY_FIELD` | Попытка обновить поле, доступное только на чтение (`id`, `createdBy`, `createdDate`, `changedDate`, `closedDate`) | | 400 | `BITRIX_ERROR` | Некорректное значение поля (например, `status` вне диапазона `1..7`) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `tasks` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Закрытие задачи.** Чтобы пометить задачу выполненной, отправьте `status: 5`. После этого автоматически заполняется `closedDate` — это поле read-only и обновляется только при переводе в статус `5` (завершена) или `6` (отложена). ## Смотрите также - [Получить задачу](./get.md) — текущее состояние перед изменением - [Поля задачи](./fields.md) — какие поля можно изменять, какие — read-only - [Удалить задачу](./delete.md) — полное удаление - [Список задач](./list.md) — найти задачу перед изменением - [Batch-запросы](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Timelines: Create ## Добавить комментарий `POST /v1/timelines` Создаёт новый комментарий таймлайна, привязанный к записи CRM. Используется для фиксации заметок по сделкам, лидам, контактам и компаниям. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | **`entityType`** | string | да | Тип родительской записи CRM: `deal`, `lead`, `contact`, `company` или `DYNAMIC_` для смарт-процессов (например, `DYNAMIC_174` для смарт-процесса с `entityTypeId: 174` из [`GET /v1/smart-processes`](/docs/entities/smart-processes/list)) | | **`entityId`** | number | да | ID родительской записи. Источник зависит от типа: `GET /v1/deals`, `GET /v1/leads`, `GET /v1/contacts`, `GET /v1/companies`, `GET /v1/items/:entityTypeId` (элементы смарт-процессов) | | **`comment`** | string | да | Текст комментария. Пустая строка отклоняется ошибкой `BITRIX_ERROR Empty comment message` | При создании через API автор (`authorId`) проставляется по владельцу API-ключа, дата создания (`createdAt`) — сервером. ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/timelines \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityType": "deal", "entityId": 741, "comment": "Первый контакт: клиент заинтересовался предложением" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/timelines \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "entityType": "deal", "entityId": 741, "comment": "Первый контакт: клиент заинтересовался предложением" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ entityType: 'deal', entityId: 741, comment: 'Первый контакт: клиент заинтересовался предложением', }), }) const { success, data } = await res.json() console.log('Comment ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ entityType: 'deal', entityId: 741, comment: 'Первый контакт: клиент заинтересовался предложением', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `id` | number | ID созданного комментария | | `entityType` | string | Тип родительской записи | | `entityId` | number | ID родительской записи | | `comment` | string | Текст комментария | | `authorId` | number | ID автора — при создании через API соответствует владельцу ключа | | `createdAt` | datetime | Дата создания (ISO 8601, UTC) | ## Пример ответа ```json { "success": true, "data": { "id": 66303, "entityId": 741, "entityType": "deal", "comment": "Первый контакт: клиент заинтересовался предложением", "authorId": 1, "createdAt": "2026-04-24T12:34:05.000Z" } } ``` ## Пример ответа при ошибке 422 — не передан обязательный `comment`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Empty comment message" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Нарушение требований: пустой `comment`, неверный `entityType` | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список комментариев](/docs/entities/timelines/list) — проверка созданных комментариев - [Обновить комментарий](/docs/entities/timelines/update) — изменение текста - [Удалить комментарий](/docs/entities/timelines/delete) - [Поля комментария](/docs/entities/timelines/fields) — полный список полей - [Batch](/docs/batch) — массовое создание комментариев - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Timelines: Delete ## Удалить комментарий `DELETE /v1/timelines/:id` Удаляет комментарий таймлайна по ID. Восстановить удалённый комментарий через API нельзя — при необходимости создавайте новый. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID комментария | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/timelines/66303" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/timelines/66303" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/66303', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Комментарий удалён') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/66303', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Удалено') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — признак успеха проверяется по статусу. ## Пример ответа ``` HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 404 — комментарий не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Комментарий не найден (или уже удалён) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список комментариев](/docs/entities/timelines/list) — найти ID перед удалением - [Batch](/docs/batch) — массовое удаление - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Timelines: Fields ## Поля комментария `GET /v1/timelines/fields` Возвращает схему полей комментария таймлайна. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/timelines/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/timelines/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Поля:', Object.keys(data.fields)) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `ID` | number | да | ID комментария | | `entityType` | `ENTITY_TYPE` | string | | Тип родительской записи CRM: `deal`, `lead`, `contact`, `company` или `DYNAMIC_` для смарт-процессов (например, `DYNAMIC_174`). В ответе приходит в нижнем регистре (`dynamic_174`). Задаётся только при создании | | `entityId` | `ENTITY_ID` | number | | ID родительской записи. Задаётся только при создании. Источник: `GET /v1/deals`, `GET /v1/leads`, `GET /v1/contacts`, `GET /v1/companies`, `GET /v1/items/:entityTypeId` (элементы смарт-процессов) | | `comment` | `COMMENT` | string | | Текст комментария. Обязателен при создании | | `authorId` | `AUTHOR_ID` | number | да | ID автора комментария. Данные пользователя по ID: `GET /v1/users/:id` | | `createdAt` | `CREATED` | datetime | да | Дата создания, ISO 8601 в UTC | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "entityType": { "type": "string", "readonly": false }, "entityId": { "type": "number", "readonly": false }, "comment": { "type": "string", "readonly": false }, "authorId": { "type": "number", "readonly": false }, "createdAt": { "type": "datetime", "readonly": true } } } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "Requires 'crm' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Добавить комментарий](/docs/entities/timelines/create) — какие поля передавать - [Список комментариев](/docs/entities/timelines/list) — фильтрация по полям - [Entity API](/docs/entity-api) — select для выборки нужных полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Timelines: Get ## Получить комментарий `GET /v1/timelines/:id` Возвращает один комментарий таймлайна по его ID. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID комментария. Получить список ID — [`GET /v1/timelines`](/docs/entities/timelines/list) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/timelines/66303" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/timelines/66303" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/66303', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Комментарий:', data.comment) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/66303', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект комментария со всеми полями — см. [Поля комментария](/docs/entities/timelines/fields). ## Пример ответа ```json { "success": true, "data": { "id": 66303, "entityId": 575, "entityType": "deal", "comment": "Первый контакт: клиент заинтересовался предложением", "authorId": 1, "createdAt": "2026-04-24T12:34:05.000Z" } } ``` ## Пример ответа при ошибке 422 — комментарий не найден: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Not found." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Комментарий с указанным ID не существует | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список комментариев](/docs/entities/timelines/list) — поиск с фильтрами - [Обновить комментарий](/docs/entities/timelines/update) — изменение текста - [Удалить комментарий](/docs/entities/timelines/delete) - [Поля комментария](/docs/entities/timelines/fields) — полный список полей - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Timelines: List ## Список комментариев `GET /v1/timelines` Возвращает комментарии таймлайна, привязанные к конкретной записи CRM. Фильтр по `entityType` и `entityId` обязателен — без них запрос возвращает `400 MISSING_REQUIRED_FILTER`. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `filter[entityType]` | string | да | — | Тип родительской записи CRM: `deal`, `lead`, `contact`, `company` или `DYNAMIC_` для смарт-процессов (например, `DYNAMIC_174`) | | `filter[entityId]` | number | да | — | ID родительской записи. Источник зависит от типа: `GET /v1/deals`, `GET /v1/leads`, `GET /v1/contacts`, `GET /v1/companies`, `GET /v1/items/:entityTypeId` (элементы смарт-процессов) | | `limit` | number | нет | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `offset` | number | нет | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `select` | string | нет | — | Выборка полей: `?select=id,comment,authorId` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/timelines?filter[entityType]=deal&filter[entityId]=741" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/timelines?filter[entityType]=deal&filter[entityId]=741" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines?filter[entityType]=deal&filter[entityId]=741', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} комментариев`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines?filter[entityType]=deal&filter[entityId]=741', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив комментариев (все поля — см. [Поля комментария](/docs/entities/timelines/fields)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 66309, "entityId": 741, "entityType": "deal", "comment": "Первый контакт: клиент заинтересовался предложением", "authorId": 1, "createdAt": "2026-04-24T12:39:28.000Z" }, { "id": 66311, "entityId": 741, "entityType": "deal", "comment": "Уточнение: клиент готов подписать договор на следующей неделе", "authorId": 1, "createdAt": "2026-04-24T12:39:30.000Z" } ], "meta": { "total": 2, "hasMore": false } } ``` ## Пример ответа при ошибке 400 — не передан обязательный фильтр: ```json { "success": false, "error": { "code": "MISSING_REQUIRED_FILTER", "message": "GET /v1/timelines requires filter fields: entityType, entityId. Example: GET /v1/timelines?filter[entityType]=...&filter[entityId]=..." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_REQUIRED_FILTER` | Не переданы обязательные `filter[entityType]` и `filter[entityId]` | | 422 | `BITRIX_ERROR` | Неверное значение `entityType` (например, числовой код CRM вместо строки) | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`entityType` — строка.** Используйте строковые идентификаторы CRM-типов: `deal`, `lead`, `contact`, `company`. Для смарт-процессов — `DYNAMIC_` (например, `DYNAMIC_174`). В ответе значение приходит в нижнем регистре (`dynamic_174`). Числовые коды CRM в `entityType` не работают — возвращается `422 BITRIX_ERROR Access denied.`. **Фильтрация только по `entityType` + `entityId`.** Битрикс24 игнорирует любые дополнительные поля в фильтре (`authorId`, `comment`, диапазоны `>=createdAt` и т. п.) — ответ возвращается тот же, что и без них. Если нужен отбор по автору или тексту — получите все комментарии записи и отфильтруйте на стороне клиента. **Порядок результатов — по `id` ASC.** Список возвращается в порядке создания: самые ранние комментарии первыми. Если нужен обратный порядок — переверните массив на клиенте (`data.reverse()`). Параметры сортировки (`order[...]`, `sort=`) для этого эндпоинта не применяются. **Авто-пагинация.** При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 и возвращает все записи в одном ответе. ## Смотрите также - [Получить комментарий](/docs/entities/timelines/get) — получение одной записи по ID - [Добавить комментарий](/docs/entities/timelines/create) — создание нового - [Поля комментария](/docs/entities/timelines/fields) — полный список полей - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — select, пагинация - [Batch](/docs/batch) — объединение нескольких list-запросов - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Timelines: Update ## Обновить комментарий `PATCH /v1/timelines/:id` Изменяет текст существующего комментария таймлайна. Передайте только поле `comment` — остальные поля (`entityType`, `entityId`, `authorId`, `createdAt`) фиксируются при создании и через API не изменяются. ## Часто обновляемые поля | Поле | Тип | Описание | |------|-----|---------| | `comment` | string | Новый текст комментария | Полный список полей — [`GET /v1/timelines/fields`](/docs/entities/timelines/fields). ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/timelines/66303" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "comment": "Уточнение: клиент готов подписать договор на следующей неделе" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/timelines/66303" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "comment": "Уточнение: клиент готов подписать договор на следующей неделе" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/66303', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ comment: 'Уточнение: клиент готов подписать договор на следующей неделе', }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/timelines/66303', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ comment: 'Уточнение: клиент готов подписать договор на следующей неделе', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | object | Обновлённый объект комментария — все поля, см. [Поля комментария](/docs/entities/timelines/fields) | ## Пример ответа ```json { "success": true, "data": { "id": 66303, "entityId": 741, "entityType": "deal", "comment": "Уточнение: клиент готов подписать договор на следующей неделе", "authorId": 1, "createdAt": "2026-04-24T12:34:05.000Z" } } ``` ## Пример ответа при ошибке 404 — комментарий не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "Элемент не найден" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Комментарий с указанным ID не существует | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `crm` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Получить комментарий](/docs/entities/timelines/get) — текущее значение комментария - [Добавить комментарий](/docs/entities/timelines/create) — создание нового - [Удалить комментарий](/docs/entities/timelines/delete) - [Batch](/docs/batch) — массовое обновление комментариев - [Лимиты и оптимизация](/docs/optimization) — rate limits --- # Users: Aggregate ## Агрегация сотрудников `POST /v1/users/aggregate` Подсчёт количества сотрудников с фильтрацией: - **`count`** — работает на любом запросе (с фильтром или без). - **`groupBy`** — по стандартным полям из списка агрегации (`active`, `isAdmin`, `isOnline`, `departmentId`, `workPosition`, `personalGender`, `personalCity`) и по пользовательским (UF) полям любого типа. - **`sum` / `avg` / `min` / `max`** — только по UF-полям числовых типов: `integer`, `double`, `money`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ "field": "UF_*", "function": "sum" }`. Без параметра — только `count` | | `filter` | object | нет | Фильтрация по полям `GET /v1/users/fields`.
[Синтаксис фильтрации](/docs/filtering). Принимает `camelCase` и `UPPER_SNAKE_CASE` | | `groupBy` | string \| string[] | нет | Имя поля или массив (до 5). Поддерживаются: стандартные поля `active`, `isAdmin`, `isOnline`, `departmentId`, `workPosition`, `personalGender`, `personalCity`; а также любые UF-поля портала | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users/aggregate" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true } }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users/aggregate" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true } }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, }), }) const { success, data } = await res.json() console.log('Активных сотрудников:', data.count) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/aggregate', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, }), }) const { success, data } = await res.json() ``` > Для группировки по нескольким полям передайте массив: `"groupBy": ["active", "workPosition"]` (максимум 5). ## Другие сценарии Общее количество сотрудников портала — самый быстрый запрос, без выгрузки записей: ```json {} ``` Распределение по статусу активности — сколько сотрудников активно, сколько деактивировано: ```json { "groupBy": "active" } ``` Группировка по UF-полю «Внутренний номер»: ```json { "groupBy": "UF_PHONE_INNER" } ``` Сумма по числовому UF-полю с группировкой: ```json { "aggregate": [{ "field": "UF_SALARY", "function": "sum" }], "groupBy": "UF_DEPARTMENT" } ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.count` | number | Количество записей под фильтр | | `data.aggregates` | object | Результаты агрегаций (пустой объект, если в запросе не было `aggregate`) | | `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: значения полей группировки + `count` | | `data.meta.totalRecords` | number | Общее количество записей под фильтр | | `data.meta.recordsProcessed` | number | Количество обработанных записей | | `data.meta.truncated` | boolean | `true`, если попало больше 5000 записей и часть не вошла в выборку | ## Пример ответа Ответ на запрос `count` без `groupBy`: ```json { "success": true, "data": { "count": 57, "aggregates": {}, "meta": { "totalRecords": 57, "recordsProcessed": 0, "truncated": false } } } ``` Без `groupBy` поле `data.groups` в ответе отсутствует. ## Пример ответа при ошибке 400 — `groupBy` по несуществующему полю (сообщение содержит список доступных стандартных и UF-полей): ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "groupBy field 'nonexistent' is not aggregatable on this entity. Available: active, isAdmin, isOnline, departmentId, workPosition, personalGender, personalCity. User-defined: UF_DEPARTMENT (string), UF_PHONE_INNER (string), UF_EMPLOYMENT_DATE (string), UF_SKILLS (string), UF_INTERESTS (string), UF_LINKEDIN (string), UF_FACEBOOK (string)." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Несуществующее или недопустимое поле в `groupBy` или `aggregate.field` — сообщение содержит список доступных полей | | 400 | `INVALID_PARAMS` | UF-поле нечислового типа (`string`, `enumeration`, `date`) в `sum`/`avg`/`min`/`max` — сообщение называет тип | | 400 | `INVALID_PARAMS` | Больше 5 полей в `groupBy` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`count` vs числовые функции.** `count` считается одним вызовом Битрикс24 на любом объёме. `sum`/`avg`/`min`/`max` подгружают записи постранично (максимум 5000), считают на стороне Вайбкод. При более 5000 записей под фильтр — `meta.truncated: true`, агрегация по первым 5000. Для точного подсчёта на больших выборках — `count` или сужение фильтра. **Money-поля.** UF-поля типа `money` хранятся в формате `"сумма|валюта"` (`"50000|RUB"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга. ## Смотрите также - [Список сотрудников](/docs/entities/users/list) — выгрузка записей с пагинацией - [Поля сотрудника](/docs/entities/users/fields) — UF-поля приходят в общем списке - [Синтаксис фильтрации](/docs/filtering) - [Лимиты и оптимизация](/docs/optimization) --- # Users: Create ## Создать сотрудника `POST /v1/users` Создаёт нового сотрудника на портале. Минимальное обязательное поле — `email`. Возвращает ID и полную запись только что созданного сотрудника. > Для интеграций с пользовательским вводом удобнее [`POST /v1/users/invite`](/docs/entities/users/invite): он валидирует email на стороне Вайбкод (`EMAIL_REQUIRED`, `EMAIL_INVALID`) и автоматически проставляет `departmentId: [1]` для штатных сотрудников. Этот эндпоинт — низкоуровневая форма, ошибки прокидываются от Битрикс24 как есть. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `email` | string | да | Email — должен быть уникальным среди всех сотрудников портала | | `name` | string | нет | Имя | | `lastName` | string | нет | Фамилия | | `secondName` | string | нет | Отчество | | `workPosition` | string | нет | Должность | | `workPhone` | string | нет | Рабочий телефон | | `personalPhone` | string | нет | Личный телефон | | `personalMobile` | string | нет | Мобильный телефон | | `personalBirthday` | string | нет | Дата рождения (ISO 8601) | | `personalGender` | string | нет | Пол: `M` — мужской, `F` — женский | | `personalCity` | string | нет | Город | | `departmentId` | number[] | условно | Массив ID отделов. Для штатных сотрудников **обязателен** — без него Битрикс24 вернёт `wrong_email`. Для экстранета (`EXTRANET: "Y"`) не используется | | `xmlId` | string | нет | Внешний идентификатор | | `EXTRANET` | string | нет | `"Y"` для пользователя экстранета. Тогда вместо `departmentId` нужен `SONET_GROUP_ID` (массив ID рабочих групп) | | `SONET_GROUP_ID` | number[] | условно | Массив ID рабочих групп — обязателен при `EXTRANET: "Y"`. Список: [`GET /v1/workgroups`](/docs/entities/workgroups) | Полный список — [Поля сотрудника](/docs/entities/users/fields). Пользовательские поля (`UF_*`) тоже принимаются. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Иван", "lastName": "Петров", "email": "ivan.petrov@example.com", "workPosition": "Менеджер", "departmentId": [1] }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Иван", "lastName": "Петров", "email": "ivan.petrov@example.com", "workPosition": "Менеджер", "departmentId": [1] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Иван', lastName: 'Петров', email: 'ivan.petrov@example.com', workPosition: 'Менеджер', departmentId: [1], }), }) const { success, data } = await res.json() console.log('User ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Иван', lastName: 'Петров', email: 'ivan.petrov@example.com', workPosition: 'Менеджер', departmentId: [1], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | ID созданного сотрудника | Ответ содержит полную запись со всеми полями сотрудника — формат тот же, что у [`GET /v1/users/:id`](/docs/entities/users/get). URL карточки сотрудника в Битрикс24 строится из `id`: ``` https://.bitrix24.ru/company/personal/user// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": { "id": 1331, "xmlId": "74668002", "active": true, "name": "Иван", "lastName": "Петров", "email": "ivan.petrov@example.com", "lastLogin": null, "dateRegister": "2026-05-06T00:00:00.000Z", "isOnline": false, "timestampX": {}, "personalGender": null, "personalBirthday": null, "departmentId": [1], "workPosition": "Менеджер", "userType": "employee" } } ``` ## Пример ответа при ошибке 400 — email не передан или дублирует существующего сотрудника: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "wrong_email", "hint": "Bitrix24 `user.add` returns `wrong_email` for several distinct cases, not only malformed email: (a) the email is already used by ANOTHER Bitrix24 user globally — check with GET /v1/users?filter[EMAIL]=the-email first; (b) the email domain is not allowed by portal policy; (c) missing UF_DEPARTMENT for intranet users — try `departmentId: [1]`; (d) for external users pass `EXTRANET: \"Y\"` + `SONET_GROUP_ID: [groupId]`." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `BITRIX_ERROR` (`wrong_email`) | Email не передан, дублирует существующего сотрудника, не прошёл политику домена портала, либо для штатного сотрудника не указан `departmentId` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Email должен быть глобально уникальным.** Битрикс24 проверяет уникальность среди всех сотрудников портала включая ранее деактивированных. Перед созданием — поиск через `GET /v1/users?filter[EMAIL]=ivan.petrov@example.com`. Если запись найдена и деактивирована, верните её в строй через `PATCH /v1/users/:id { active: true }` — это сохранит историю действий и связи сотрудника, в отличие от создания дубля. **Неоднозначность ошибки `wrong_email`.** Битрикс24 возвращает `wrong_email` для нескольких разных ситуаций: email уже занят, домен запрещён политикой портала, у штатного сотрудника не указан `departmentId`, у внешнего — `SONET_GROUP_ID`. Сообщение не уточняет, какая именно. Чтобы разделить эти случаи на стороне Вайбкод, используйте [`POST /v1/users/invite`](/docs/entities/users/invite) — обёртка возвращает явные коды (`EMAIL_REQUIRED`, `EMAIL_INVALID`, `SONET_GROUP_ID_REQUIRED`) до запроса в Битрикс24. ## Смотрите также - [Пригласить сотрудника](/docs/entities/users/invite) — обёртка с валидацией и значениями по умолчанию - [Поля сотрудника](/docs/entities/users/fields) — полный список полей - [Список сотрудников](/docs/entities/users/list) — найти существующих - [Отделы](/docs/entities/departments) — источник `departmentId` - [Лимиты и оптимизация](/docs/optimization) --- # Users: Delete ## Деактивировать сотрудника `DELETE /v1/users/:id` Деактивирует сотрудника — снимает доступ к порталу, но сохраняет всю запись и её связи. Эндпоинт маппится на обновление поля активности (`active: false`); все данные и история действий остаются в Битрикс24. Восстановить доступ — `PATCH /v1/users/:id { active: true }`. Требует прав администратора портала. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сотрудника | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/users/1331" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/users/1331" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/1331', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() if (success && data.deactivated) { console.log(`Сотрудник ${data.id} деактивирован`) } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/1331', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успешной деактивации | | `data.id` | number | ID деактивированного сотрудника | | `data.active` | boolean | Всегда `false` после деактивации | | `data.deactivated` | boolean | Всегда `true` — явный маркер семантики операции | | `data.user` | object | Полная запись сотрудника после деактивации (best-effort: если повторное чтение записи не сработало, поле может отсутствовать — деактивация всё равно выполнена) | ## Пример ответа ```json { "success": true, "data": { "id": 1331, "active": false, "deactivated": true, "user": { "id": 1331, "name": "Иван", "lastName": "Петров", "email": "ivan.petrov@example.com", "active": false, "workPosition": "Менеджер", "departmentId": [1], "userType": "employee" } } } ``` ## Пример ответа при ошибке 403 — у владельца ключа нет прав администратора портала: ```json { "success": false, "error": { "code": "UPDATE_FAILED", "message": "Bitrix24 rejected user.update for deactivation (result: false)", "hint": "Bitrix24 returns false when the calling user lacks portal admin rights, or when the target user id does not exist. Verify the webhook/OAuth identity is a portal admin." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_ID` | `:id` не является положительным целым числом | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | | 403 | `UPDATE_FAILED` | Битрикс24 вернул `result: false`. Чаще всего — нет прав администратора портала; реже — сотрудника с таким ID не существует | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Связи остаются.** После деактивации сотрудник продолжает значиться ответственным за сделки, автором комментариев, участником чатов. Email остаётся занятым — повторно использовать его при создании нового сотрудника не получится без предварительной реактивации существующего: [`PATCH /v1/users/:id { active: true }`](/docs/entities/users/update). **Best-effort повторное чтение записи.** Вайбкод пытается получить актуальную запись после успешной деактивации и кладёт её в `data.user`. Если вспомогательный вызов упал — поле отсутствует, но сама деактивация уже произведена и подтверждена. Повторный [`GET /v1/users/:id`](/docs/entities/users/get) подгрузит запись с `active: false`. ## Смотрите также - [Обновить сотрудника](/docs/entities/users/update) — реактивация через `active: true` - [Список сотрудников](/docs/entities/users/list) — поиск перед деактивацией - [Получить сотрудника](/docs/entities/users/get) — проверить, что запись доступна - [Лимиты и оптимизация](/docs/optimization) --- # Users: Fields ## Поля сотрудника `GET /v1/users/fields` Возвращает полный список полей сущности «сотрудник», включая пользовательские (`UF_*`) поля портала. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/users/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/users/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Bitrix24 | Тип | RO | Описание | |------|----------|-----|:--:|---------| | `id` | `ID` | number | да | Идентификатор сотрудника | | `name` | `NAME` | string | | Имя | | `lastName` | `LAST_NAME` | string | | Фамилия | | `secondName` | `SECOND_NAME` | string | | Отчество | | `email` | `EMAIL` | string | | Email — обязательное при создании, должно быть уникальным | | `active` | `ACTIVE` | boolean | | Признак активности (`true` — работает, `false` — деактивирован) | | `workPosition` | `WORK_POSITION` | string | | Должность | | `workPhone` | `WORK_PHONE` | string | | Рабочий телефон | | `personalPhone` | `PERSONAL_PHONE` | string | | Личный телефон | | `personalMobile` | `PERSONAL_MOBILE` | string | | Мобильный телефон | | `personalBirthday` | `PERSONAL_BIRTHDAY` | string | | Дата рождения (формат ISO 8601) | | `personalGender` | `PERSONAL_GENDER` | string | | Пол: `M` — мужской, `F` — женский | | `personalCity` | `PERSONAL_CITY` | string | | Город | | `personalPhoto` | `PERSONAL_PHOTO` | string | | URL фотографии | | `departmentId` | `UF_DEPARTMENT` | number[] | | Массив ID отделов. Список: `GET /v1/departments` | | `xmlId` | `XML_ID` | string | | Внешний идентификатор для интеграций | | `isAdmin` | `IS_ADMIN` | boolean | да | Признак администратора портала | | `isOnline` | `IS_ONLINE` | boolean | да | Сотрудник сейчас в сети | | `dateRegister` | `DATE_REGISTER` | datetime | да | Дата регистрации в портале | | `lastLogin` | `LAST_LOGIN` | datetime | да | Дата последнего входа | | `lastActivityDate` | `LAST_ACTIVITY_DATE` | datetime | да | Дата последней активности | | `timeZone` | `TIME_ZONE` | string | | Часовой пояс сотрудника. Пример: `"Europe/Moscow"` | | `title` | `TITLE` | string | | Обращение / звание | | `personalWww` | `PERSONAL_WWW` | string | | Личный сайт | | `personalProfession` | `PERSONAL_PROFESSION` | string | | Профессия | | `personalIcq` | `PERSONAL_ICQ` | string | | ICQ (устаревшее поле Битрикс24) | | `personalFax` | `PERSONAL_FAX` | string | | Факс | | `personalPager` | `PERSONAL_PAGER` | string | | Пейджер | | `personalStreet` | `PERSONAL_STREET` | string | | Улица | | `userType` | `USER_TYPE` | string | да | Тип учётной записи: `"employee"` — штатный сотрудник, `"extranet"` — внешний пользователь | | `timestampX` | `TIMESTAMP_X` | datetime | да | Метка последнего изменения записи в Битрикс24. Для части пользователей возвращается пустым объектом `{}` | **Пользовательские поля** (`UF_*`) также возвращаются в ответах и принимаются при создании или обновлении. ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false }, "lastName": { "type": "string", "readonly": false }, "email": { "type": "string", "readonly": false }, "active": { "type": "boolean", "readonly": false }, "workPosition": { "type": "string", "readonly": false }, "departmentId": { "type": "array", "readonly": false }, "personalPhone": { "type": "string", "readonly": false }, "isAdmin": { "type": "boolean", "readonly": true }, "lastLogin": { "type": "datetime", "readonly": true }, "timeZone": { "type": "string", "readonly": false }, "userType": { "type": "string", "readonly": true }, "UF_DEPARTMENT": { "type": "string", "readonly": false, "label": "Отдел" }, "UF_PHONE_INNER": { "type": "string", "readonly": false, "label": "UF_PHONE_INNER" } }, "batch": ["create", "update", "delete"] } } ``` Показаны несколько полей из общего списка. Реальный ответ содержит 30+ полей схемы в `camelCase`, не-mapped поля Битрикс24 в `UPPER_SNAKE_CASE` (`WORK_*`, часть `PERSONAL_*`) и UF-поля конкретного портала. ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'user' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Создать сотрудника](/docs/entities/users/create) — какие поля можно передать - [Обновить сотрудника](/docs/entities/users/update) — какие поля можно изменить - [Список сотрудников](/docs/entities/users/list) — фильтрация и поиск - [Пользовательские поля](/docs/userfields) — управление UF-полями - [Лимиты и оптимизация](/docs/optimization) --- # Users: Get ## Получить сотрудника `GET /v1/users/:id` Возвращает данные сотрудника по ID со всеми полями, включая пользовательские (`UF_*`). ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | да | ID сотрудника | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/users/29" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/users/29" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/29', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log(`${data.name} ${data.lastName} — ${data.email}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/29', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа Объект сотрудника со всеми полями — см. [Поля сотрудника](/docs/entities/users/fields). ## Пример ответа ```json { "success": true, "data": { "id": 29, "xmlId": "28936832", "active": true, "name": "Violetta", "lastName": "Веточкина", "email": "violetwandere@yandex.ru", "lastLogin": "2026-03-30T14:39:25.000Z", "dateRegister": "2020-04-23T00:00:00.000Z", "timeZone": "Asia/Yekaterinburg", "isOnline": false, "timestampX": {}, "lastActivityDate": {}, "personalPhoto": "https://cdn-ru.bitrix24.ru/.../photo.png", "departmentId": [1], "userType": "employee" } } ``` ## Пример ответа при ошибке 404 — сотрудник не найден: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "user 999999999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_ID` | `:id` не является положительным целым числом | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | | 404 | `ENTITY_NOT_FOUND` | Сотрудник с таким ID не найден или деактивирован и недоступен текущему ключу | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поля `WORK_*` и часть полей `PERSONAL_*` приходят в `UPPER_SNAKE_CASE`.** `WORK_COMPANY`, `WORK_DEPARTMENT`, `WORK_WWW`, `WORK_FAX`, `WORK_CITY`, `WORK_STATE`, `WORK_ZIP`, `WORK_COUNTRY` и аналогичные; `PERSONAL_STATE`, `PERSONAL_ZIP`, `PERSONAL_COUNTRY`, `PERSONAL_MAILBOX`, `PERSONAL_NOTES` — в оригинальных именах Битрикс24. UF-поля портала тоже сохраняют свои имена. Стандартные поля (`name`, `email`, `active`, `timeZone`, `userType`, `departmentId` и др.) — `camelCase`. ## Смотрите также - [Поля сотрудника](/docs/entities/users/fields) — все поля - [Список сотрудников](/docs/entities/users/list) — поиск с фильтрами - [Обновить сотрудника](/docs/entities/users/update) — изменение полей - [Лимиты и оптимизация](/docs/optimization) --- # Users: Invite ## Пригласить сотрудника `POST /v1/users/invite` Создаёт нового сотрудника или приглашает внешнего пользователя на портал. Принимает поля в `camelCase` и `UPPER_SNAKE_CASE`, проставляет разумные значения по умолчанию и проверяет email до вызова Битрикс24 — возвращая понятные коды ошибок (`EMAIL_REQUIRED`, `EMAIL_INVALID`, `SONET_GROUP_ID_REQUIRED`) вместо общего `wrong_email`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `email` | string | да | Email — должен быть уникальным среди всех сотрудников портала. Базовая синтаксическая проверка происходит на стороне Вайбкод | | `name` | string | нет | Имя | | `lastName` | string | нет | Фамилия | | `secondName` | string | нет | Отчество | | `workPosition` | string | нет | Должность | | `workPhone` | string | нет | Рабочий телефон | | `workCompany` | string | нет | Название компании | | `personalPhone` | string | нет | Личный телефон | | `personalMobile` | string | нет | Мобильный телефон | | `personalBirthday` | string | нет | Дата рождения (ISO 8601) | | `personalGender` | string | нет | Пол: `M` — мужской, `F` — женский | | `personalCity` | string | нет | Город | | `departmentId` | number[] | нет | Массив ID отделов. По умолчанию `[1]` (корневой отдел) для штатных сотрудников. Список: `GET /v1/departments` | | `extranet` | string | нет | `"Y"` для приглашения внешнего пользователя. В этом случае `departmentId` игнорируется и обязателен `sonetGroupId` | | `sonetGroupId` | number[] | условно | Массив ID рабочих групп — обязателен при `extranet: "Y"`. Список: [`GET /v1/workgroups`](/docs/entities/workgroups) | | `active` | boolean | нет | Признак активности (по умолчанию `true`) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users/invite" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "email": "ivan.petrov@example.com", "name": "Иван", "lastName": "Петров", "workPosition": "Менеджер" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users/invite" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "email": "ivan.petrov@example.com", "name": "Иван", "lastName": "Петров", "workPosition": "Менеджер" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/invite', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'ivan.petrov@example.com', name: 'Иван', lastName: 'Петров', workPosition: 'Менеджер', }), }) const { success, data } = await res.json() console.log('Создан сотрудник ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/invite', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'ivan.petrov@example.com', name: 'Иван', lastName: 'Петров', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | ID созданного сотрудника | | `data.user` | object | Полная запись только что созданного сотрудника — те же поля, что у [`GET /v1/users/:id`](/docs/entities/users/get) | ## Пример ответа ```json { "success": true, "data": { "id": 1331, "user": { "id": 1331, "xmlId": "74668002", "active": true, "name": "Иван", "lastName": "Петров", "email": "ivan.petrov@example.com", "lastLogin": null, "dateRegister": "2026-05-06T00:00:00.000Z", "isOnline": false, "timestampX": {}, "personalGender": null, "departmentId": [1], "workPosition": "Менеджер", "userType": "employee" } } } ``` HTTP-статус ответа — `201 Created`. ## Пример ответа при ошибке 400 — email не передан: ```json { "success": false, "error": { "code": "EMAIL_REQUIRED", "message": "EMAIL (or `email`) is required to invite a user." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `EMAIL_REQUIRED` | В теле запроса нет `email` (или `EMAIL`) | | 400 | `EMAIL_INVALID` | Email не прошёл синтаксическую проверку Вайбкод | | 400 | `SONET_GROUP_ID_REQUIRED` | При `extranet: "Y"` не передан `sonetGroupId` | | 400 | `BITRIX_ERROR` (`wrong_email`) | Битрикс24 отклонил создание: email уже занят, домен запрещён политикой портала, или другая ошибка email | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Зачем дефолт `departmentId: [1]`.** Без `UF_DEPARTMENT` Битрикс24 возвращает обобщённый `wrong_email` без указания причины — отсутствие отдела у штатного сотрудника одна из самых частых ловушек. Подстановка корневого отдела `[1]` устраняет её для типового случая «приглашаем сотрудника, конкретный отдел неизвестен». Если структура отделов важна — передавайте `departmentId` явно. **Уникальность email на портале.** Email проверяется среди всех сотрудников включая ранее деактивированных — при дубле Битрикс24 отдаст `BITRIX_ERROR: wrong_email`. Перед приглашением — поиск через `GET /v1/users?filter[EMAIL]=ivan.petrov@example.com`. Если найден деактивированный, верните его в строй через [`PATCH /v1/users/:id { active: true }`](/docs/entities/users/update) — это сохранит историю и связи, в отличие от создания дубля. **Best-effort повторное чтение.** После успешного создания обёртка делает повторное чтение записи и кладёт её в `data.user`. Если вспомогательный вызов упал, `data.id` всё равно вернётся — сотрудник уже создан, повторное обращение [`GET /v1/users/:id`](/docs/entities/users/get) подгрузит запись. ## Смотрите также - [Создать сотрудника](/docs/entities/users/create) — низкоуровневая форма без значений по умолчанию - [Список сотрудников](/docs/entities/users/list) — поиск дубликата email перед приглашением - [Обновить сотрудника](/docs/entities/users/update) — реактивация через `active: true` - [Отделы](/docs/entities/departments) — источник `departmentId` - [Лимиты и оптимизация](/docs/optimization) --- # Users: List ## Список сотрудников `GET /v1/users` Возвращает список сотрудников портала с поддержкой фильтрации, сортировки и автопагинации. Метод не возвращает ботов, почтовых пользователей и пользователей Открытых линий. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 | | `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` | | `order` | object | — | Сортировка по любому полю записи. Пример: `?order[name]=asc` | | `filter` | object | — | Фильтрация по полям `GET /v1/users/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[name]=Иван` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/users?limit=10&filter[active]=true" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/users?limit=10&filter[active]=true" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users?limit=10&filter[active]=true', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, total } = await res.json() console.log(`Найдено ${total} сотрудников`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users?limit=10&filter[active]=true', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, total } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив сотрудников. Каждый элемент содержит все поля — см. [Поля сотрудника](/docs/entities/users/fields) | | `total` | number | Общее количество записей под фильтр | | `page` | number | Текущая страница | | `limit` | number | Размер страницы | URL карточки любого сотрудника из массива `data` — его `id`: ``` https://.bitrix24.ru/company/personal/user// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 1, "xmlId": "28889266", "active": true, "name": "Летта", "lastName": null, "secondName": "Отчество", "email": "kalashnikova@bitrix.ru", "lastLogin": "2026-05-05T08:25:11.000Z", "dateRegister": "2020-04-20T00:00:00.000Z", "timeZone": "Europe/Kaliningrad", "isOnline": false, "timestampX": {}, "lastActivityDate": {}, "personalGender": "F", "personalPhoto": "https://cdn-ru.bitrix24.ru/.../photo.jpg", "personalMobile": "+79638835976", "workPosition": null, "departmentId": [1, 107, 47], "userType": "employee" }, { "id": 29, "xmlId": "28936832", "active": true, "name": "Violetta", "lastName": "Веточкина", "email": "violetwandere@yandex.ru", "departmentId": [1], "userType": "employee" } ], "total": 30, "page": 1, "limit": 10 } ``` Показаны основные поля. Полный список — [Поля сотрудника](/docs/entities/users/fields). ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'user' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_FILTER_FIELD` | Фильтр по несуществующему полю — список полей в `GET /v1/users/fields` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Семантика `filter[active]`.** `active: true` исключает деактивированных. `active: false` Битрикс24 не интерпретирует как «только деактивированные» — возвращаются все. Чтобы получить только деактивированных, просеивайте результат на стороне клиента по полю `active`. **Поля `WORK_*` и часть полей `PERSONAL_*` приходят в `UPPER_SNAKE_CASE`.** `WORK_COMPANY`, `WORK_DEPARTMENT`, `WORK_WWW`, `WORK_FAX`, `WORK_CITY`, `WORK_STATE`, `WORK_ZIP`, `WORK_COUNTRY` и аналогичные; `PERSONAL_STATE`, `PERSONAL_ZIP`, `PERSONAL_COUNTRY`, `PERSONAL_MAILBOX`, `PERSONAL_NOTES` — в оригинальных именах Битрикс24. UF-поля портала тоже сохраняют свои имена. Стандартные поля (`name`, `email`, `active`, `timeZone`, `userType`, `departmentId` и др.) — `camelCase`. **Поле `lastActivityDate` (объявлено `datetime`).** На практике приходит **пустым объектом `{}`**, либо ключ **отсутствует** вовсе — ISO-строка по этому полю в проверках не наблюдалась. `{}` — истинное значение в JS, поэтому `if (u.lastActivityDate)` ложно-срабатывает. То же у `timestampX` (всегда `{}`). Не парсьте как дату и не полагайтесь на truthy-проверку; сравнивайте тип (`typeof x === 'string'`). См. сводку по «пусто» в datetime-полях в [обзоре сущности](/docs/entities/users) (п. 7). ## Смотрите также - [Получить сотрудника](/docs/entities/users/get) — один по ID - [Поиск сотрудников](/docs/entities/users/search) — POST с фильтрами в теле - [Поля сотрудника](/docs/entities/users/fields) — полный список полей - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) — order, пагинация - [Лимиты и оптимизация](/docs/optimization) --- # Users: Search ## Поиск сотрудников `POST /v1/users/search` Поиск сотрудников с фильтрами в теле запроса и автопагинацией. Аналогичен [`GET /v1/users`](/docs/entities/users/list), но через POST — удобнее для сложных запросов и больших массивов значений в фильтре. ## Поля запроса (body) | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` | object | — | Фильтрация по полям `GET /v1/users/fields`.
[Синтаксис фильтрации](/docs/filtering). Пример: `{ "filter": { "active": true, "lastName": "Иванов" } }` | | `limit` | number | `50` | Количество записей (до 5000) | | `offset` | number | `0` | Пропустить N записей | | `order` | object | — | Сортировка: `{ "NAME": "asc" }` | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true }, "limit": 10 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/users/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "active": true }, "limit": 10 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, limit: 10, }), }) const { success, data } = await res.json() console.log('Найдено:', data.length) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { active: true }, limit: 10, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив сотрудников. Каждый элемент содержит все поля — см. [Поля сотрудника](/docs/entities/users/fields) | URL карточки любого сотрудника из массива `data` — его `id`: ``` https://.bitrix24.ru/company/personal/user// ``` `` — домен портала. Доступ ограничен правами сотрудника в Битрикс24. ## Пример ответа ```json { "success": true, "data": [ { "id": 1, "active": true, "name": "Летта", "lastName": null, "email": "kalashnikova@bitrix.ru", "departmentId": [1, 107, 47] }, { "id": 29, "active": true, "name": "Violetta", "lastName": "Веточкина", "email": "violetwandere@yandex.ru", "departmentId": [1] } ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'user' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_FILTER_FIELD` | Фильтр по несуществующему полю — список полей в `GET /v1/users/fields` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Семантика `filter[active]: false`.** Возвращает всех сотрудников, а не только деактивированных — Битрикс24 интерпретирует `ACTIVE = "Y"` как «исключить деактивированных», а другие значения как «без фильтра по статусу». Чтобы получить только деактивированных, делайте отдельную фильтрацию на стороне клиента по полю `active`. **Когда использовать search вместо list.** POST-search удобнее для длинных списков значений в фильтре (`{ "id": [1, 5, 12, 27, 99] }`) — query-строка GET-запроса имеет ограничения на длину, а body POST — нет. Для коротких фильтров обе формы эквивалентны. ## Смотрите также - [Список сотрудников](/docs/entities/users/list) — GET-форма для простых фильтров - [Поля сотрудника](/docs/entities/users/fields) — какие поля доступны - [Синтаксис фильтрации](/docs/filtering) - [Batch](/docs/batch) — несколько search в одном запросе - [Лимиты и оптимизация](/docs/optimization) --- # Users: Update ## Обновить сотрудника `PATCH /v1/users/:id` Обновляет поля существующего сотрудника. Передавайте только изменяемые поля. Требует прав администратора портала на стороне Битрикс24 — без них вызов отклоняется. ## Поля запроса (body) | Параметр | Тип | Описание | |----------|-----|---------| | `workPosition` | string | Должность | | `departmentId` | number[] | Массив ID отделов. Список: `GET /v1/departments` | | `email` | string | Email — должен оставаться уникальным на портале | | `workPhone` / `personalPhone` / `personalMobile` | string | Телефоны | | `active` | boolean | Реактивировать (`true`) или деактивировать (`false`) — деактивация эквивалентна [`DELETE /v1/users/:id`](/docs/entities/users/delete) | Полный список полей — [Поля сотрудника](/docs/entities/users/fields). Пользовательские (`UF_*`) поля принимаются. ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/users/29" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "workPosition": "Старший менеджер", "departmentId": [1, 47] }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/users/29" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "workPosition": "Старший менеджер", "departmentId": [1, 47] }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/29', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ workPosition: 'Старший менеджер', departmentId: [1, 47], }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/users/29', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ workPosition: 'Старший менеджер', departmentId: [1, 47], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Обновлённый объект сотрудника со всеми полями — формат тот же, что у [`GET /v1/users/:id`](/docs/entities/users/get) | ## Пример ответа ```json { "success": true, "data": { "id": 29, "name": "Violetta", "lastName": "Веточкина", "email": "violetwandere@yandex.ru", "active": true, "workPosition": "Старший менеджер", "departmentId": [1, 47], "userType": "employee" } } ``` ## Пример ответа при ошибке 403 — обновление отклонено Битрикс24: ```json { "success": false, "error": { "code": "UPDATE_FAILED", "message": "Bitrix24 rejected user.update (result: false)", "hint": "Bitrix24 returns false when the calling user lacks portal admin rights, when a read-only field was touched (isOnline, lastLogin, dateRegister, isAdmin), or when the target user ID does not exist. Verify the webhook/OAuth identity is a portal admin." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_ID` | `:id` не является положительным целым числом | | 400 | `READONLY_FIELD` | В теле запроса передано readonly-поле (`id`, `isOnline`, `isAdmin`, `lastLogin`, `dateRegister`, `lastActivityDate`). Вайбкод отклоняет до вызова Битрикс24 | | 400 | `BITRIX_ERROR` | Битрикс24 отклонил поле — например, `wrong_email` при попытке поставить уже занятый email | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` | | 403 | `UPDATE_FAILED` | Битрикс24 вернул `result: false` для запроса на обновление. Чаще всего — у владельца ключа нет прав администратора портала | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Изменение email.** Если новый email уже занят другим сотрудником портала, Битрикс24 вернёт `BITRIX_ERROR: wrong_email`. Перед PATCH — проверка через `GET /v1/users?filter[EMAIL]=новый@example.com`. ## Смотрите также - [Получить сотрудника](/docs/entities/users/get) — текущие значения полей - [Поля сотрудника](/docs/entities/users/fields) — какие поля можно изменить - [Деактивировать сотрудника](/docs/entities/users/delete) — обратимое деактивирование - [Batch](/docs/batch) — массовое обновление - [Лимиты и оптимизация](/docs/optimization) --- # Warehouses: Create ## Создать склад `POST /v1/warehouses` Создаёт новый склад. Поля передаются плоско в корне JSON — без обёртки `fields`. ## Поля запроса (body) | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `title` | string | да | Название склада | | `address` | string | да | Адрес склада | | `active` | string | нет | Активность: `"Y"` / `"N"`. По умолчанию `"Y"` | | `issuingCenter` | string | нет | Пункт выдачи заказов: `"Y"` / `"N"`. По умолчанию `"N"` | | `description` | string | нет | Описание склада | | `phone` | string | нет | Контактный телефон | | `email` | string | нет | Контактная почта | | `schedule` | string | нет | Режим работы — произвольный текст | | `sort` | number | нет | Порядок сортировки. По умолчанию `100` | | `code` | string | нет | Символьный код | | `xmlId` | string | нет | Внешний идентификатор для синхронизации | | `gpsN` | number | нет | Географическая широта | | `gpsS` | number | нет | Географическая долгота | | `userId` | number | нет | Ответственный сотрудник — идентификатор из [`GET /v1/users`](/docs/entities/users) | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/warehouses" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Основной склад", "address": "г. Москва, ул. Складская, 1", "active": "Y" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/warehouses" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Основной склад", "address": "г. Москва, ул. Складская, 1", "active": "Y" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Основной склад', address: 'г. Москва, ул. Складская, 1', active: 'Y', }), }) const { success, data } = await res.json() console.log('ID склада:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Основной склад', address: 'г. Москва, ул. Складская, 1', active: 'Y', }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается объект созданного склада в поле `data`. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор склада | | `title` | string | Название склада | | `address` | string | Адрес склада | | `active` | string | Активность: `"Y"` / `"N"` | | `issuingCenter` | string | Признак пункта выдачи заказов: `"Y"` / `"N"` | | `description` | string | Описание склада | | `phone` | string | Контактный телефон | | `email` | string | Контактная почта | | `schedule` | string | Режим работы | | `sort` | number | Порядок сортировки | | `code` | string | Символьный код | | `xmlId` | string | Внешний идентификатор | | `gpsN` | number | Географическая широта | | `gpsS` | number | Географическая долгота | | `imageId` | object | Изображение склада: `{ "id", "url" }` или `null` | | `userId` | number | Ответственный сотрудник | | `modifiedBy` | number | Идентификатор пользователя, изменившего склад последним | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | ## Пример ответа ```json { "success": true, "data": { "id": 25, "title": "Основной склад", "address": "г. Москва, ул. Складская, 1", "active": "Y", "issuingCenter": "N", "description": null, "phone": null, "email": null, "schedule": null, "sort": 100, "code": null, "xmlId": null, "gpsN": null, "gpsS": null, "imageId": null, "userId": 1, "modifiedBy": 1, "dateCreate": "2026-06-02T12:04:24+03:00", "dateModify": "2026-06-02T12:04:24+03:00" } } ``` ## Пример ответа при ошибке 400 — не передано обязательное поле: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: title (string), address (string)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передано `title` либо `address` | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 422 | `BITRIX_ERROR` | Битрикс24 отклонил создание (например, недопустимое значение поля) | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Значения по умолчанию.** Если не передать `active`, `sort` и `issuingCenter`, склад создаётся со значениями `active: "Y"`, `sort: 100`, `issuingCenter: "N"`. Поля `userId` и `modifiedBy` в ответе заполняются текущим пользователем, под которым выпущен ключ. ## Смотрите также - [Список складов](/docs/entities/warehouses/list) - [Обновить склад](/docs/entities/warehouses/update) - [Удалить склад](/docs/entities/warehouses/delete) - [Справочник сущностей](/docs/entities-index) --- # Warehouses: Delete ## Удалить склад `DELETE /v1/warehouses/:id` Удаляет склад по идентификатору. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | Идентификатор склада | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/warehouses/1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/warehouses/1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) console.log(res.status) // 204 ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) console.log(res.status) // 204 ``` ## Поля ответа При успехе — статус `204 No Content`, тело ответа пустое. ## Пример ответа ``` HTTP/1.1 204 No Content ``` Тело ответа отсутствует. ## Пример ответа при ошибке 422 — склад с таким `id` не существует: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "store does not exist." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `id` не положительное целое | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 422 | `BITRIX_ERROR` | Склад с указанным `id` не существует | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Несуществующий склад — `422`, не `404`.** Удаление склада по неизвестному `id` возвращает `422` с кодом `BITRIX_ERROR`. Повторное удаление уже удалённого склада вернёт ту же ошибку. ## Смотрите также - [Список складов](/docs/entities/warehouses/list) - [Получить склад](/docs/entities/warehouses/get) - [Создать склад](/docs/entities/warehouses/create) - [Справочник сущностей](/docs/entities-index) --- # Warehouses: Get ## Получить склад `GET /v1/warehouses/:id` Возвращает один склад по идентификатору со всеми полями. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | Идентификатор склада | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses/1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses/1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log(data.title) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект склада — состав полей ниже | ### Поля склада | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор склада | | `title` | string | Название склада | | `address` | string | Адрес склада | | `active` | string | Активность: `"Y"` / `"N"` | | `issuingCenter` | string | Признак пункта выдачи заказов: `"Y"` / `"N"` | | `description` | string | Описание склада | | `phone` | string | Контактный телефон | | `email` | string | Контактная почта | | `schedule` | string | Режим работы | | `sort` | number | Порядок сортировки | | `code` | string | Символьный код | | `xmlId` | string | Внешний идентификатор | | `gpsN` | number | Географическая широта | | `gpsS` | number | Географическая долгота | | `imageId` | object | Изображение склада: `{ "id", "url" }` или `null` | | `userId` | number | Ответственный сотрудник | | `modifiedBy` | number | Идентификатор пользователя, изменившего склад последним | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | ## Пример ответа ```json { "success": true, "data": { "id": 1, "title": "Основной склад", "address": "г. Москва, ул. Складская, 1", "active": "Y", "issuingCenter": "N", "description": "Центральный склад", "phone": "+7 495 000 00 00", "email": "warehouse@example.com", "schedule": "Пн–Пт 9:00–20:00", "sort": 100, "code": "main", "xmlId": null, "gpsN": 55.751244, "gpsS": 37.618423, "imageId": { "id": 57, "url": "https://cdn.bitrix24.ru/b00000000/catalog/store.png" }, "userId": 1, "modifiedBy": 1, "dateCreate": "2024-01-15T09:00:00+03:00", "dateModify": "2024-06-20T14:30:00+03:00" } } ``` ## Пример ответа при ошибке 422 — склад с таким `id` не существует: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "store does not exist." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `id` не положительное целое | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 422 | `BITRIX_ERROR` | Склад с указанным `id` не существует | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Несуществующий склад — `422`, не `404`.** Запрос склада по неизвестному `id` возвращает `422` с кодом `BITRIX_ERROR`. Перед получением проверяйте наличие склада в [списке складов](/docs/entities/warehouses/list). **Изображение склада.** Поле `imageId` приходит объектом `{ "id", "url" }` со ссылкой на картинку склада либо `null`, если изображение не задано. ## Смотрите также - [Список складов](/docs/entities/warehouses/list) - [Обновить склад](/docs/entities/warehouses/update) - [Остатки склада](/docs/entities/warehouses/stock) - [Справочник сущностей](/docs/entities-index) --- # Warehouses: List ## Список складов `GET /v1/warehouses` Возвращает список складов портала. Постраничный вывод задаётся параметрами `limit` и `offset`. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` ответ автоматически собирается из нескольких страниц Битрикс24 | | `offset` | number | `0` | Смещение от начала выборки. При `offset ≥ 2500` держите `limit ≤ 500` | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Складов: ${meta.total}`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив складов — состав полей одного склада ниже | | `meta.total` | number | Общее количество складов на портале | ### Поля склада | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор склада | | `title` | string | Название склада | | `address` | string | Адрес склада | | `active` | string | Активность: `"Y"` / `"N"` | | `issuingCenter` | string | Признак пункта выдачи заказов: `"Y"` / `"N"` | | `description` | string | Описание склада | | `phone` | string | Контактный телефон | | `email` | string | Контактная почта | | `schedule` | string | Режим работы | | `sort` | number | Порядок сортировки | | `code` | string | Символьный код | | `xmlId` | string | Внешний идентификатор | | `gpsN` | number | Географическая широта | | `gpsS` | number | Географическая долгота | | `imageId` | object | Изображение склада: `{ "id", "url" }` или `null` | | `userId` | number | Ответственный сотрудник | | `modifiedBy` | number | Идентификатор пользователя, изменившего склад последним | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | ## Пример ответа ```json { "success": true, "data": [ { "id": 1, "title": "Основной склад", "address": "г. Москва, ул. Складская, 1", "active": "Y", "issuingCenter": "N", "description": null, "phone": null, "email": null, "schedule": null, "sort": 100, "code": null, "xmlId": null, "gpsN": null, "gpsS": null, "imageId": null, "userId": 1, "modifiedBy": 1, "dateCreate": "2024-01-15T09:00:00+03:00", "dateModify": "2024-06-20T14:30:00+03:00" }, { "id": 2, "title": "Пункт выдачи «Север»", "address": "г. Москва, ул. Полярная, 8", "active": "Y", "issuingCenter": "Y", "description": null, "phone": "+7 495 000 00 00", "email": null, "schedule": "Пн–Пт 10:00–20:00", "sort": 200, "code": "pvz-north", "xmlId": null, "gpsN": 55.85, "gpsS": 37.6, "imageId": null, "userId": 1, "modifiedBy": 1, "dateCreate": "2024-03-10T11:00:00+03:00", "dateModify": "2024-03-10T11:00:00+03:00" } ], "meta": { "total": 2 } } ``` ## Пример ответа при ошибке 400 — некорректное значение `limit`: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "limit must be a positive integer" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `limit` не положительное целое либо `offset` отрицательный | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только постраничный вывод.** Список принимает лишь `limit` и `offset`. Фильтрация, сортировка и выборка отдельных полей (`filter`, `sort`, `select`) на этом эндпоинте не поддерживаются — возвращаются все склады портала. Нужный склад отбирайте на стороне клиента по полю из ответа. ## Смотрите также - [Получить склад](/docs/entities/warehouses/get) - [Создать склад](/docs/entities/warehouses/create) - [Остатки склада](/docs/entities/warehouses/stock) - [Справочник сущностей](/docs/entities-index) --- # Warehouses: Stock ## Остатки склада `GET /v1/warehouses/:id/stock` Возвращает остатки товаров на складе — по строке на каждый товар, который числится на этом складе. Только для чтения: изменить количество через этот эндпоинт нельзя. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | Идентификатор склада | ## Параметры запроса | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `limit` | number | `50` | Количество строк (до 5000). При `limit > 50` ответ автоматически собирается из нескольких страниц Битрикс24 | | `offset` | number | `0` | Смещение от начала выборки | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses/1/stock" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses/1/stock" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1/stock', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1/stock', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Строки остатков на складе | | `data[].id` | number | Идентификатор строки остатка | | `data[].productId` | number | Идентификатор товара — см. [Товары каталога](/docs/entities/catalog-products) | | `data[].storeId` | number | Идентификатор склада | | `data[].amount` | number | Количество на складе. Может быть `null` — трактуйте как `0` | | `data[].quantityReserved` | number | Зарезервированное количество. Может быть `null` — трактуйте как `0` | | `meta.total` | number | Количество строк остатков на складе | ## Пример ответа ```json { "success": true, "data": [ { "id": 3, "productId": 200, "storeId": 1, "amount": 15, "quantityReserved": 30 }, { "id": 5, "productId": 201, "storeId": 1, "amount": 54, "quantityReserved": null }, { "id": 9, "productId": 202, "storeId": 1, "amount": null, "quantityReserved": null } ], "meta": { "total": 3 } } ``` ## Пример ответа при ошибке 400 — некорректный `id` склада: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "id must be a positive integer" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `id`, `limit` или `offset` заданы некорректно | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Пустой склад.** Если на складе нет товаров с остатками, `data` — пустой массив, `meta.total` — `0`. ## Смотрите также - [Сводные остатки по товарам](/docs/entities/warehouses/stock-totals) - [Получить склад](/docs/entities/warehouses/get) - [Товары каталога](/docs/entities/catalog-products) - [Справочник сущностей](/docs/entities-index) --- # Warehouses: Stock Totals ## Сводные остатки по товарам `GET /v1/warehouses/stock/totals` Складывает остатки каждого товара по всем складам портала. Для товара возвращает суммарное количество, суммарный резерв и список складов, где товар представлен. Только для чтения. ## Параметры запроса | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `productId` | number | — | Свести остатки только по одному товару | | `limit` | number | — | Сколько товаров вернуть в ответе | | `offset` | number | `0` | Смещение по списку товаров | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses/stock/totals?productId=200" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/warehouses/stock/totals?productId=200" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/stock/totals', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/stock/totals', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Сводка по товарам | | `data[].productId` | number | Идентификатор товара — см. [Товары каталога](/docs/entities/catalog-products) | | `data[].amount` | number | Суммарное количество товара по всем складам | | `data[].quantityReserved` | number | Суммарный резерв товара по всем складам | | `data[].storeIds` | array | Идентификаторы складов, где товар представлен | | `meta.total` | number | Количество товаров в ответе | | `meta.rawTotal` | number | Количество исходных строк остатков, обработанных при агрегации | | `meta.truncated` | boolean | `true`, если исходных строк остатков больше 5000 и часть не вошла в свод | ## Пример ответа ```json { "success": true, "data": [ { "productId": 200, "amount": 25, "quantityReserved": 30, "storeIds": [1, 2, 5] } ], "meta": { "total": 1, "truncated": false, "rawTotal": 3 } } ``` ## Пример ответа при ошибке 400 — некорректный `productId`: ```json { "success": false, "error": { "code": "INVALID_PARAMS", "message": "productId must be a positive integer" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `productId`, `limit` или `offset` заданы некорректно | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Суммирование по товару.** Количество и резерв одного товара суммируются по всем складам, где он представлен. Список таких складов — в `storeIds`. Если на отдельном складе количество не задано, при суммировании оно считается нулём. **Ограничение свода.** Свод считается по первым 5000 строкам остатков. Если строк больше, `meta.truncated` равно `true`, и свод получается неполным. В этом случае сузьте выборку параметром `productId`. ## Смотрите также - [Остатки склада](/docs/entities/warehouses/stock) - [Список складов](/docs/entities/warehouses/list) - [Товары каталога](/docs/entities/catalog-products) - [Справочник сущностей](/docs/entities-index) --- # Warehouses: Update ## Обновить склад `PATCH /v1/warehouses/:id` Обновляет склад. Передавайте только изменяемые поля — плоско в корне JSON. Переданные поля заменяют текущие значения, остальные остаются прежними. ## Параметры пути | Параметр | Тип | Описание | |----------|-----|---------| | `id` | number | Идентификатор склада | ## Поля запроса (body) Любое подмножество изменяемых полей склада — все необязательны. | Параметр | Тип | Описание | |----------|-----|---------| | `title` | string | Название склада | | `address` | string | Адрес склада | | `active` | string | Активность: `"Y"` / `"N"` | | `issuingCenter` | string | Пункт выдачи заказов: `"Y"` / `"N"` | | `description` | string | Описание склада | | `phone` | string | Контактный телефон | | `email` | string | Контактная почта | | `schedule` | string | Режим работы | | `sort` | number | Порядок сортировки | | `code` | string | Символьный код | | `xmlId` | string | Внешний идентификатор | | `gpsN` | number | Географическая широта | | `gpsS` | number | Географическая долгота | | `userId` | number | Ответственный сотрудник | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/warehouses/1" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Центральный склад", "sort": 50 }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/warehouses/1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Центральный склад", "sort": 50 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Центральный склад', sort: 50, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/warehouses/1', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: 'Центральный склад', sort: 50, }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается объект обновлённого склада в поле `data`. | Поле | Тип | Описание | |------|-----|---------| | `id` | number | Идентификатор склада | | `title` | string | Название склада | | `address` | string | Адрес склада | | `active` | string | Активность: `"Y"` / `"N"` | | `issuingCenter` | string | Признак пункта выдачи заказов: `"Y"` / `"N"` | | `description` | string | Описание склада | | `phone` | string | Контактный телефон | | `email` | string | Контактная почта | | `schedule` | string | Режим работы | | `sort` | number | Порядок сортировки | | `code` | string | Символьный код | | `xmlId` | string | Внешний идентификатор | | `gpsN` | number | Географическая широта | | `gpsS` | number | Географическая долгота | | `imageId` | object | Изображение склада: `{ "id", "url" }` или `null` | | `userId` | number | Ответственный сотрудник | | `modifiedBy` | number | Идентификатор пользователя, изменившего склад последним | | `dateCreate` | datetime | Дата создания | | `dateModify` | datetime | Дата последнего изменения | ## Пример ответа ```json { "success": true, "data": { "id": 1, "title": "Центральный склад", "address": "г. Москва, ул. Складская, 1", "active": "Y", "issuingCenter": "N", "description": "Центральный склад", "phone": "+7 495 000 00 00", "email": "warehouse@example.com", "schedule": "Пн–Пт 9:00–20:00", "sort": 50, "code": "main", "xmlId": null, "gpsN": 55.751244, "gpsS": 37.618423, "imageId": null, "userId": 1, "modifiedBy": 1, "dateCreate": "2024-01-15T09:00:00+03:00", "dateModify": "2026-06-02T12:04:25+03:00" } } ``` ## Пример ответа при ошибке 422 — склад с таким `id` не существует: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "store does not exist." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | `id` не положительное целое | | 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `catalog` | | 422 | `BITRIX_ERROR` | Склад с указанным `id` не существует | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Несуществующий склад — `422`, не `404`.** Обновление склада по неизвестному `id` возвращает `422` с кодом `BITRIX_ERROR`. Перед обновлением проверяйте наличие склада в [списке складов](/docs/entities/warehouses/list). ## Смотрите также - [Получить склад](/docs/entities/warehouses/get) - [Создать склад](/docs/entities/warehouses/create) - [Удалить склад](/docs/entities/warehouses/delete) - [Справочник сущностей](/docs/entities-index) --- # Workgroups: Create ## Создать рабочую группу `POST /v1/workgroups` Создаёт новую рабочую группу на портале. Возвращает полный объект созданной группы. Обязательное поле одно — `name`; остальные параметры опциональны. ## Поля запроса (body) | Поле | Тип | Обяз. | По умолч. | Описание | |------|-----|:-----:|-----------|---------| | `name` | string | ★ | — | Название рабочей группы | | `description` | string | нет | — | Описание | | `ownerId` | number | нет | текущий пользователь ключа | Идентификатор владельца группы. Список: `GET /v1/users` | | `subjectId` | number | нет | тема портала по умолчанию | Идентификатор темы | | `active` | boolean | нет | `true` | Активна ли группа | | `visible` | boolean | нет | `true` | Видна ли в общих списках | | `opened` | boolean | нет | `false` | Открыта ли для вступления без приглашения | | `archived` | boolean | нет | `false` | Поместить в архив сразу при создании | | `isProject` | boolean | нет | `false` | Создать как проект | | `isExtranet` | boolean | нет | `false` | Группа экстранета | | `keywords` | string | нет | — | Ключевые слова для поиска | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/workgroups" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Маркетинг 2026", "description": "Координация рекламных кампаний", "opened": true, "isProject": false }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/workgroups" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Маркетинг 2026", "description": "Координация рекламных кампаний", "opened": true, "isProject": false }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Маркетинг 2026', description: 'Координация рекламных кампаний', opened: true, isProject: false, }), }) const { success, data } = await res.json() console.log('Workgroup ID:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Маркетинг 2026', description: 'Координация рекламных кампаний', opened: true, isProject: false, }), }) const { success, data } = await res.json() ``` ## Поля ответа Возвращается полный объект созданной рабочей группы. | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Объект созданной рабочей группы. Полное описание полей — [Получить рабочую группу](./get.md) или [Поля рабочей группы](./fields.md) | ## Пример ответа ```json { "success": true, "data": { "id": 173, "siteId": "s1", "name": "Маркетинг 2026", "description": "Координация рекламных кампаний", "dateCreate": "2026-05-26T05:56:40.000Z", "dateUpdate": "2026-05-26T05:56:40.000Z", "active": true, "visible": true, "opened": true, "archived": false, "subjectId": 1, "ownerId": 1, "keywords": null, "membersCount": 1, "dateActivity": "2026-05-26T05:56:40.000Z", "subjectName": "Рабочие группы", "isProject": false, "isExtranet": false } } ``` ## Пример ответа при ошибке 422 — не передано обязательное поле `name`: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Не указано название" } } ``` ## Ошибки | HTTP | `error.code` | Описание | |------|--------------|---------| | 422 | `BITRIX_ERROR` | Битрикс24 отказал в создании группы — текст причины в `error.message`. Типичная причина: отсутствует обязательное поле `name` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Переданный ключ не распознан | | 403 | `SCOPE_DENIED` | У ключа нет скоупа `sonet_group` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список рабочих групп](./list.md) - [Получить рабочую группу](./get.md) - [Обновить рабочую группу](./update.md) - [Поля рабочей группы](./fields.md) --- # Workgroups: Delete ## Удалить рабочую группу `DELETE /v1/workgroups/:id` Удаляет рабочую группу и все связанные с ней данные. Операция необратимая. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `id` (path) | number | ★ да | — | Идентификатор рабочей группы. Список: [`GET /v1/workgroups`](./list.md) | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/workgroups/85" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/workgroups/85" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/85', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) if (res.status === 204) { console.log('Рабочая группа удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/85', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) if (res.status === 204) { console.log('Рабочая группа удалена') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по статусу. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — попытка удалить несуществующую группу: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "Socialnetwork group not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Битрикс24 отказал в удалении. Типичные причины: группа не существует, нет прав на удаление | | 401 | `MISSING_API_KEY` | Не передан `X-Api-Key` | | 401 | `INVALID_API_KEY` | Передан некорректный ключ | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `sonet_group` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности - Для временного скрытия группы без потери данных используйте [`PATCH /v1/workgroups/:id`](./update.md) с `archived: true` — группа перестанет показываться в активных списках, но останется доступной для восстановления. - Сообщение `Socialnetwork group not found` возвращается и при отсутствии группы, и при отсутствии прав на удаление — точную причину по ответу определить нельзя. ## Смотрите также - [Список рабочих групп](./list.md) - [Получить рабочую группу](./get.md) - [Обновить рабочую группу](./update.md) --- # Workgroups: Fields ## Поля рабочей группы `GET /v1/workgroups/fields` Возвращает схему полей рабочей группы и список операций, доступных в пакетных запросах. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/workgroups/fields" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/workgroups/fields" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/fields', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Полей:', Object.keys(data.fields).length) console.log('Доступные batch-операции:', data.batch) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/fields', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.fields` | object | Объект схемы полей рабочей группы | | `data.fields.<имя>` | object | Описание одного поля | | `data.fields.<имя>.type` | string | Тип значения: `number`, `string`, `boolean` или `datetime` | | `data.fields.<имя>.readonly` | boolean | Доступно ли поле для записи через `POST` / `PATCH` | | `data.batch` | array | Список операций сущности, доступных в [`POST /v1/batch`](/docs/batch): `create`, `update`, `delete` | ### Поля рабочей группы | Поле | Тип | Только чтение | Описание | |------|-----|:--:|---------| | `id` | number | да | Идентификатор рабочей группы | | `name` | string | | Название | | `description` | string | | Описание | | `active` | boolean | | Активна ли группа | | `visible` | boolean | | Видна ли в общих списках | | `opened` | boolean | | Открыта ли для вступления без приглашения | | `ownerId` | number | | Владелец (ответственный). Список: [`GET /v1/users`](/docs/entities/users) | | `subjectId` | number | | Идентификатор темы | | `subjectName` | string | да | Название темы | | `membersCount` | number | да | Количество участников | | `dateCreate` | datetime | да | Дата создания | | `dateUpdate` | datetime | да | Дата последнего обновления | | `dateActivity` | datetime | да | Дата последней активности | | `archived` | boolean | | Помещена ли в архив | | `isProject` | boolean | | Является ли проектом с задачами и сроками | | `isExtranet` | boolean | | Экстранет-группа | | `keywords` | string | | Ключевые слова | | `siteId` | string | да | Идентификатор сайта портала | | `imageUrl` | string | да | URL аватара группы | ## Пример ответа ```json { "success": true, "data": { "fields": { "id": { "type": "number", "readonly": true }, "name": { "type": "string", "readonly": false }, "description": { "type": "string", "readonly": false }, "active": { "type": "boolean", "readonly": false }, "visible": { "type": "boolean", "readonly": false }, "opened": { "type": "boolean", "readonly": false }, "ownerId": { "type": "number", "readonly": false }, "subjectId": { "type": "number", "readonly": false }, "subjectName": { "type": "string", "readonly": true }, "membersCount": { "type": "number", "readonly": true }, "dateCreate": { "type": "datetime", "readonly": true }, "dateUpdate": { "type": "datetime", "readonly": true }, "dateActivity": { "type": "datetime", "readonly": true }, "archived": { "type": "boolean", "readonly": false }, "isProject": { "type": "boolean", "readonly": false }, "isExtranet": { "type": "boolean", "readonly": false }, "keywords": { "type": "string", "readonly": false }, "siteId": { "type": "string", "readonly": true }, "imageUrl": { "type": "string", "readonly": true } }, "batch": ["create", "update", "delete"] } } ``` ## Пример ответа при ошибке 401 — нет ключа авторизации: ```json { "success": false, "error": { "code": "MISSING_API_KEY", "message": "API key is required" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Передан неверный ключ | | 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `sonet_group` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности - Список полей не зависит от прав пользователя ключа — возвращается полная схема сущности. - Кроме операций, перечисленных в `data.batch`, в [`POST /v1/batch`](/docs/batch) для рабочих групп можно вызывать `get`, `list` и `fields`. ## Смотрите также - [Список рабочих групп](./list.md) - [Создать рабочую группу](./create.md) - [Обновить рабочую группу](./update.md) - [Batch](/docs/batch) - [Entity API](/docs/entity-api) --- # Workgroups: Get ## Получить рабочую группу `GET /v1/workgroups/:id` Возвращает рабочую группу по идентификатору со всеми её полями. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `id` (path) | number | ★ да | — | Идентификатор рабочей группы. Список: [`GET /v1/workgroups`](./list.md) | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/workgroups/85" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/workgroups/85" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/85', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log('Группа:', data.name, '— участников:', data.membersCount) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/85', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Идентификатор рабочей группы (только чтение) | | `data.name` | string | Название | | `data.description` | string \| null | Описание | | `data.active` | boolean | Активна ли группа | | `data.visible` | boolean | Видна ли группа в общих списках | | `data.opened` | boolean | Открыта ли для вступления без приглашения | | `data.ownerId` | number | Идентификатор владельца (ответственного). Список: [`GET /v1/users`](/docs/entities/users) | | `data.subjectId` | number | Идентификатор темы | | `data.subjectName` | string | Название темы (только чтение) | | `data.membersCount` | number | Количество участников (только чтение) | | `data.dateCreate` | string | Дата создания, ISO 8601 (только чтение) | | `data.dateUpdate` | string | Дата последнего обновления, ISO 8601 (только чтение) | | `data.dateActivity` | string | Дата последней активности, ISO 8601 (только чтение) | | `data.archived` | boolean | Помещена ли в архив | | `data.isProject` | boolean | Является ли проектом с задачами и сроками | | `data.isExtranet` | boolean | Группа экстранета — с доступом для внешних пользователей | | `data.keywords` | string \| null | Ключевые слова | | `data.siteId` | string | Идентификатор сайта портала, для основного сайта — `s1` (только чтение) | | `data.imageUrl` | string \| null | URL аватара группы (только чтение) | ## Пример ответа ```json { "success": true, "data": { "id": 85, "siteId": "s1", "name": "Команда разработки нового продукта", "description": "Внутренний проект инфраструктуры", "dateCreate": "2026-03-20T06:45:10.000Z", "dateUpdate": "2026-03-20T06:45:10.000Z", "active": true, "visible": true, "opened": false, "archived": false, "subjectId": 1, "ownerId": 1271, "keywords": null, "membersCount": 2, "dateActivity": "2026-03-20T06:45:10.000Z", "subjectName": "Рабочие группы", "isProject": true, "isExtranet": false, "imageUrl": null } } ``` ## Пример ответа при ошибке 404 — рабочая группа с таким id не существует: ```json { "success": false, "error": { "code": "ENTITY_NOT_FOUND", "message": "workgroup 999999 not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 404 | `ENTITY_NOT_FOUND` | Рабочая группа с указанным `id` не найдена | | 401 | `MISSING_API_KEY` | Не передан `X-Api-Key` | | 401 | `INVALID_API_KEY` | Передан некорректный ключ | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `sonet_group` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности - Нечисловой `id` (например `abc`) возвращает `404 ENTITY_NOT_FOUND`, а не `400` — учитывайте это при обработке ошибок валидации на клиенте. - Чтобы сменить тему рабочей группы, передавайте числовой `subjectId` в [`PATCH /v1/workgroups/:id`](./update.md). Поле `subjectName` доступно только для чтения — попытка передать его в теле PATCH вернёт `400 READONLY_FIELD`. ## Смотрите также - [Список рабочих групп](./list.md) - [Создать рабочую группу](./create.md) - [Обновить рабочую группу](./update.md) - [Удалить рабочую группу](./delete.md) - [Поля рабочей группы](./fields.md) --- # Workgroups: List ## Список рабочих групп `GET /v1/workgroups` Возвращает список рабочих групп портала с поддержкой фильтрации, сортировки и автоматической пагинации. ## Параметры | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `filter` (query) | object | нет | — | Фильтрация по полям [GET /v1/workgroups/fields](./fields.md).
[Синтаксис фильтрации](/docs/filtering). Пример: `?filter[archived]=N` | | `select` (query) | array | нет | — | Список полей в ответе. Имена — из [GET /v1/workgroups/fields](./fields.md). | | `sort` (query) | object | нет | — | Сортировка: `sort[<поле>]=ASC\|DESC`. Пример: `?sort[dateCreate]=DESC`. | | `limit` (query) | number | нет | `50` | Максимум записей в ответе. Допустимо до 5000. | | `offset` (query) | number | нет | `0` | Смещение от начала выборки. | Для `limit > 50` Вайбкод автоматически пагинирует запрос на стороне сервера. Максимум — 5000 записей за вызов. Если под фильтр попадает больше — `meta.hasMore` придёт `true`. ### Получить только проекты В одной коллекции хранятся и рабочие группы, и проекты. Поле `isProject` различает их: `true` — проект, `false` — обычная рабочая группа. Для выборки проектов передавайте `filter[isProject]=Y`. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/workgroups?limit=3" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/workgroups?limit=3" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups?limit=3', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} рабочих групп`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups?limit=3', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив рабочих групп (все поля — см. [Поля рабочей группы](./fields.md)) | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 85, "siteId": "s1", "name": "Маркетинг 2026", "description": null, "dateCreate": "2026-03-20T06:45:10.000Z", "dateUpdate": "2026-03-20T06:45:10.000Z", "active": true, "visible": true, "opened": false, "archived": false, "subjectId": 1, "ownerId": 1271, "keywords": null, "membersCount": 2, "dateActivity": "2026-03-20T06:45:10.000Z", "subjectName": "Рабочие группы", "isProject": true, "isExtranet": false }, { "id": 83, "siteId": "s1", "name": "Команда разработки нового продукта", "description": null, "dateCreate": "2026-03-20T06:41:07.000Z", "dateUpdate": "2026-03-20T06:41:07.000Z", "active": true, "visible": true, "opened": false, "archived": false, "subjectId": 1, "ownerId": 1269, "keywords": null, "membersCount": 1, "dateActivity": "2026-03-20T06:41:07.000Z", "subjectName": "Рабочие группы", "isProject": true, "imageUrl": "https://cdn-ru.bitrix24.ru/example/disk/avatar.jpg", "isExtranet": false }, { "id": 81, "siteId": "s1", "name": "Запуск регионального офиса", "description": null, "dateCreate": "2026-03-20T06:29:07.000Z", "dateUpdate": "2026-03-20T06:29:07.000Z", "active": true, "visible": true, "opened": false, "archived": false, "subjectId": 1, "ownerId": 1271, "keywords": null, "membersCount": 1, "dateActivity": "2026-03-20T06:29:07.000Z", "subjectName": "Рабочие группы", "isProject": true, "isExtranet": false } ], "meta": { "total": 33, "hasMore": true } } ``` ## Пример ответа при ошибке 401 — нет ключа авторизации: ```json { "success": false, "error": { "code": "MISSING_API_KEY", "message": "API key required. Pass via X-Api-Key header." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Переданный ключ не распознан | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `sonet_group` | | 429 | `RATE_LIMITED` | Превышен лимит запросов | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Логические поля в фильтре принимают `Y` / `N`.** В ответе те же поля приходят как `true` / `false`, но при фильтрации используйте `filter[active]=Y` / `filter[archived]=N`. Значения `true` / `false` в фильтре не дадут совпадений и не вызовут ошибку. **Префикс `%` в имени поля — поиск по подстроке.** `?filter[%name]=Маркетинг` найдёт все группы, в названии которых встречается «Маркетинг». Без префикса фильтр требует точного совпадения. **`limit = 0` возвращает все записи**, а не пустой массив. Для пустой выборки используйте фильтр, который заведомо ничего не находит. ## Смотрите также - [Поля рабочей группы](./fields.md) - [Синтаксис фильтрации](/docs/filtering) - [Entity API](/docs/entity-api) - [Batch](/docs/batch) - [Лимиты и оптимизация](/docs/optimization) --- # Workgroups: Search ## Поиск рабочих групп `POST /v1/workgroups/search` Возвращает список рабочих групп по заданным фильтрам. Тот же контракт, что [GET /v1/workgroups](./list.md), но условия передаются в теле запроса — подходит для длинных фильтров и нелатинских значений. ## Поля запроса (body) | Поле | Тип | Описание | |------|-----|---------| | `filter` | object | Условия фильтрации. Список полей: [GET /v1/workgroups/fields](./fields.md). Синтаксис: [Фильтрация](/docs/filtering). | | `select` | array | Список полей в ответе. Имена — из [GET /v1/workgroups/fields](./fields.md). | | `sort` | object | Сортировка: `{"<поле>": "ASC"\|"DESC"}`. | | `limit` | number | Максимум записей. По умолчанию 50, максимум 5000. | | `offset` | number | Смещение от начала выборки. По умолчанию 0. | Для `limit > 50` Вайбкод автоматически пагинирует запрос на стороне сервера. Максимум — 5000 записей за вызов. Если под фильтр попадает больше — `meta.hasMore` придёт `true`. ### Получить только проекты В одной коллекции хранятся и рабочие группы, и проекты. Поле `isProject` различает их: `true` — проект, `false` — обычная рабочая группа. Для выборки проектов передавайте `"filter": { "isProject": "Y" }`. ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/workgroups/search" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filter": { "%name": "Маркетинг", "archived": "N" }, "select": ["id", "name", "ownerId", "membersCount"], "sort": { "dateCreate": "DESC" }, "limit": 5 }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/workgroups/search" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filter": { "%name": "Маркетинг", "archived": "N" }, "select": ["id", "name", "ownerId", "membersCount"], "sort": { "dateCreate": "DESC" }, "limit": 5 }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { '%name': 'Маркетинг', archived: 'N' }, select: ['id', 'name', 'ownerId', 'membersCount'], sort: { dateCreate: 'DESC' }, limit: 5, }), }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} рабочих групп`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/search', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ filter: { '%name': 'Маркетинг', archived: 'N' }, select: ['id', 'name', 'ownerId', 'membersCount'], sort: { dateCreate: 'DESC' }, limit: 5, }), }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив рабочих групп (все поля — см. [Поля рабочей группы](./fields.md)) | | `meta.total` | number | Общее количество записей по фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа ```json { "success": true, "data": [ { "id": 85, "name": "Маркетинг 2026", "ownerId": 1271, "membersCount": 2, "dateCreate": "2026-03-20T06:45:10.000Z" }, { "id": 83, "name": "Команда разработки нового продукта", "ownerId": 1269, "membersCount": 1, "dateCreate": "2026-03-20T06:41:07.000Z" }, { "id": 81, "name": "Запуск регионального офиса", "ownerId": 1271, "membersCount": 1, "dateCreate": "2026-03-20T06:29:07.000Z" } ], "meta": { "total": 3, "hasMore": false } } ``` ## Пример ответа при ошибке 401 — не передан ключ авторизации: ```json { "success": false, "error": { "code": "MISSING_API_KEY", "message": "API key required. Pass via X-Api-Key header." } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `INVALID_PARAMS` | Тело запроса не парсится или содержит недопустимые поля | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Переданный ключ не распознан | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `sonet_group` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Логические поля в фильтре можно передавать двумя способами.** В теле POST допустимы и `Y` / `N`, и нативные JSON `true` / `false`: `"filter": {"active": "Y"}` и `"filter": {"active": true}` дают одинаковую выборку. В ответе те же поля всегда приходят как `true` / `false`. **Префикс `%` в имени поля — поиск по подстроке.** `"filter": {"%name": "Маркетинг"}` найдёт все группы, в названии которых встречается «Маркетинг». Без префикса фильтр требует точного совпадения. **Параметр сортировки в теле — `sort`.** Ключ `order` в теле игнорируется без ошибки — выборка возвращается в порядке по умолчанию. Используйте `"sort": {"dateCreate": "DESC"}` или строковую форму `"sort": "dateCreate"` (направление по умолчанию — `ASC`). ## Смотрите также - [Список рабочих групп](./list.md) - [Получить рабочую группу](./get.md) - [Поля рабочей группы](./fields.md) - [Синтаксис фильтрации](/docs/filtering) --- # Workgroups: Update ## Обновить рабочую группу `PATCH /v1/workgroups/:id` Обновляет указанные поля рабочей группы. Возвращает полный объект группы после обновления. Неупомянутые в теле поля остаются без изменений. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `id` (path) | number | ★ | Идентификатор рабочей группы. Список: [`GET /v1/workgroups`](./list.md) | ## Поля запроса (body) Передавайте только те поля, которые нужно изменить. Остальные сохраняют текущие значения. | Поле | Тип | Обяз. | По умолч. | Описание | |------|-----|:-----:|-----------|---------| | `name` | string | нет | текущее значение | Название рабочей группы | | `description` | string | нет | текущее значение | Описание | | `ownerId` | number | нет | текущее значение | Идентификатор нового владельца группы. Список: `GET /v1/users` | | `subjectId` | number | нет | текущее значение | Идентификатор темы | | `active` | boolean | нет | текущее значение | Активна ли группа | | `visible` | boolean | нет | текущее значение | Видна ли в общих списках | | `opened` | boolean | нет | текущее значение | Открыта ли для вступления без приглашения | | `archived` | boolean | нет | текущее значение | Помещена ли в архив | | `isProject` | boolean | нет | текущее значение | Является ли проектом | | `isExtranet` | boolean | нет | текущее значение | Группа экстранета | | `keywords` | string | нет | текущее значение | Ключевые слова для поиска | Поля `id`, `subjectName`, `membersCount`, `dateCreate`, `dateUpdate`, `dateActivity`, `siteId`, `imageUrl` доступны только для чтения. Передача любого из них в теле возвращает `400 READONLY_FIELD`. ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/workgroups/85" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "description": "Обновлённое описание команды", "opened": true, "archived": false }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/workgroups/85" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "description": "Обновлённое описание команды", "opened": true, "archived": false }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/85', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ description: 'Обновлённое описание команды', opened: true, archived: false, }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/workgroups/85', { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ description: 'Обновлённое описание команды', opened: true, archived: false, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Полный объект рабочей группы после обновления — все поля см. [Получить рабочую группу](./get.md) | ## Пример ответа ```json { "success": true, "data": { "id": 85, "siteId": "s1", "name": "Маркетинг 2026", "description": "Обновлённое описание команды", "dateCreate": "2026-05-12T08:14:21.000Z", "dateUpdate": "2026-05-26T05:58:08.000Z", "active": true, "visible": true, "opened": true, "archived": false, "subjectId": 1, "ownerId": 1, "keywords": "проект,команда", "membersCount": 7, "dateActivity": "2026-05-26T05:58:08.000Z", "subjectName": "Рабочие группы", "isProject": false, "isExtranet": false } } ``` ## Пример ответа при ошибке Битрикс24 не различает «группа не существует» и «нет прав на обновление»: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "User has no permissions to update group" } } ``` ## Ошибки | HTTP | `error.code` | Описание | |------|--------------|---------| | 400 | `READONLY_FIELD` | В теле передано поле, доступное только для чтения (`id`, `subjectName`, `membersCount`, `dateCreate`, `dateUpdate`, `dateActivity`, `siteId`, `imageUrl`) | | 422 | `BITRIX_ERROR` | Битрикс24 отказал в обновлении. Текст в `error.message`. Типичные причины: ошибка валидации, конфликт значений, отсутствие прав на изменение, отсутствие рабочей группы с указанным `id` (два последних случая возвращают одинаковое сообщение) | | 401 | `MISSING_API_KEY` | В запросе не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Переданный ключ недействителен или отозван | | 403 | `SCOPE_DENIED` | У ключа нет скоупа `sonet_group` | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности - Сообщение `User has no permissions to update group` возвращается и при отсутствии рабочей группы с указанным `id`, и при отсутствии прав на её изменение. Чтобы различить эти два случая, сделайте дополнительный запрос [`GET /v1/workgroups/:id`](./get.md): ответ `404` — группы нет, успешный ответ — нет прав на изменение. ## Смотрите также - [Создать рабочую группу](./create.md) - [Получить рабочую группу](./get.md) - [Список рабочих групп](./list.md) --- # Telephony: Analytics # Аналитика и справочники Чтение статистики прошедших звонков с фильтрацией по дате, типу, оператору и другим полям, и справочник доступных голосов для синтеза речи в автозвонках. Bitrix24 API: `voximplant.statistic.get`, `voximplant.tts.voices.get` Скоуп: `telephony` ## Операции - [Статистика звонков](./analytics/statistics.md) — `GET /v1/calls/statistics` - [Справочник голосов](./analytics/voices.md) — `GET /v1/calls/voices` ## Смотрите также - [Телефония — обзор](../telephony.md) - [Исходящие звонки](../outbound.md) — голоса используются как `voice` в автозвонке с синтезом речи --- # Telephony Analytics: Statistics ## Статистика звонков `GET /v1/calls/statistics` Возвращает список записей о прошедших звонках с поддержкой фильтрации по полям, сортировки и пагинации. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` (query) | object | — | Фильтрация по полям записи (UPPER_SNAKE_CASE). Поддерживаются операторы `>`, `>=`, `<`, `<=`, `!` в виде префикса к имени поля. Пример: `?filter[CALL_TYPE]=1`, `?filter[>CALL_START_DATE]=2026-01-01T00:00:00` | | `sort` (query) | string | — | Поле для сортировки в UPPER_SNAKE_CASE. Пример: `CALL_START_DATE` | | `order` (query) | string | — | Направление сортировки: `ASC` или `DESC` | | `limit` (query) | number | `50` | Максимальное количество записей в ответе (до 500) | | `offset` (query) | number | `0` | Смещение для пагинации | Диапазон дат задаётся двумя операторами одновременно. Пример: `filter[>CALL_START_DATE]=2026-04-01T00:00:00&filter[` — арендованная линия Voximplant, `sip` — SIP-линия, `REST_APP:` — линия через REST-приложение | | `data[].PHONE_NUMBER` | string | Номер телефона клиента | | `data[].CALL_ID` | string | Идентификатор звонка. Префиксы: `externalCall.` — от [`register`](../crm/register.md), `callback.` — от [обратного звонка](../outbound/callback.md), `infocall.` — от [автозвонка](../outbound/auto-call.md) | | `data[].EXTERNAL_CALL_ID` | string \| null | Внешний идентификатор, переданный при регистрации | | `data[].CALL_CATEGORY` | string | Категория: `external` для звонков через REST API | | `data[].CALL_LOG` | string \| null | URL детального лога Voximplant. `null` для звонков через REST-приложение | | `data[].CALL_DURATION` | string | Длительность звонка в секундах (строка) | | `data[].CALL_START_DATE` | string | Дата начала звонка, ISO 8601 с тайм-зоной портала | | `data[].CALL_RECORD_URL` | string | URL аудиозаписи звонка | | `data[].CALL_VOTE` | string \| null | Оценка звонка от `1` до `5` | | `data[].COST` | string | Стоимость звонка (десятичная строка) | | `data[].COST_CURRENCY` | string | Код валюты (`RUR` и др.) | | `data[].CALL_FAILED_CODE` | string | Код результата: `200` — успех, `603-S` — отменён, `304` — пропущен, `500` — ошибка сценария, `402` — недостаточно средств, `403` — запрещено | | `data[].CALL_FAILED_REASON` | string | Текстовая причина результата | | `data[].CRM_ENTITY_TYPE` | string | Тип привязанной CRM-сущности: `LEAD`, `CONTACT` или пустая строка. Источник: [лиды](/docs/entities/leads), [контакты](/docs/entities/contacts) | | `data[].CRM_ENTITY_ID` | string | ID привязанной CRM-сущности | | `data[].CRM_ACTIVITY_ID` | string | ID CRM-активности. `"0"` — активность не создана | | `data[].REST_APP_ID` | string \| null | ID приложения-инициатора звонка | | `data[].REST_APP_NAME` | string \| null | Название приложения-инициатора звонка | | `data[].TRANSCRIPT_ID` | string \| null | ID прикреплённой транскрипции. Прикрепить: [`POST /v1/calls/:callId/transcription`](../crm/transcription.md) | | `data[].TRANSCRIPT_PENDING` | string | `Y` — транскрипция в обработке, `N` — транскрипция готова или отсутствует | | `data[].SESSION_ID` | string | Идентификатор сессии Voximplant | | `data[].REDIAL_ATTEMPT` | string \| null | Номер попытки перенабора | | `data[].COMMENT` | string \| null | Комментарий оператора | | `data[].RECORD_DURATION` | string \| null | Длительность записи разговора в секундах | | `data[].RECORD_FILE_ID` | string \| null | ID файла записи на Диске | | `data[].CALL_TYPE` | string | Тип звонка: `"1"` — исходящий, `"2"` — входящий, `"3"` — входящий с перенаправлением, `"4"` — [обратный звонок](../outbound/callback.md), `"5"` — информационный ([автозвонок](../outbound/auto-call.md)) | | `total` | number | Общее количество записей, соответствующих фильтру | ## Пример ответа ```json { "success": true, "data": [ { "ID": "1", "PORTAL_USER_ID": "1", "PORTAL_NUMBER": "reg133788", "PHONE_NUMBER": "+79638835976", "CALL_ID": "11018129443EB80D.1754478520.11438214", "EXTERNAL_CALL_ID": null, "CALL_CATEGORY": "external", "CALL_LOG": "https://storage-gw-ru-02.voximplant.com/voximplant-logs/2025/08/06/...", "CALL_DURATION": "0", "CALL_START_DATE": "2025-08-06T14:08:40+03:00", "CALL_RECORD_URL": "", "CALL_VOTE": null, "COST": "0.0000", "COST_CURRENCY": "RUR", "CALL_FAILED_CODE": "603-S", "CALL_FAILED_REASON": "Decline self", "CRM_ENTITY_TYPE": "CONTACT", "CRM_ENTITY_ID": "275", "CRM_ACTIVITY_ID": "7739", "REST_APP_ID": null, "REST_APP_NAME": null, "TRANSCRIPT_ID": null, "TRANSCRIPT_PENDING": "N", "SESSION_ID": "3841557776", "REDIAL_ATTEMPT": null, "COMMENT": null, "RECORD_DURATION": null, "RECORD_FILE_ID": null, "CALL_TYPE": "1" } ], "total": 30 } ``` ## Пример ответа при ошибке 403 — нет скоупа `telephony`: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'telephony' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`total` находится в корне ответа.** В отличие от других list-эндпоинтов Вайбкод, поле `total` расположено непосредственно в корне ответа, а не в `meta.total`. **Фильтр по несуществующему полю** не возвращает ошибку — некорректное имя поля молча игнорируется и возвращаются все записи. ## Смотрите также - [Зарегистрировать звонок](../crm/register.md) — возвращает `CALL_ID`, который появляется в статистике - [Обратный звонок](../outbound/callback.md) - [Автозвонок с синтезом речи](../outbound/auto-call.md) - [Автозвонок с аудиофайлом](../outbound/auto-call-audio.md) - [Справочник голосов](./voices.md) — доступные голоса для автозвонка - [Лиды](/docs/entities/leads), [Контакты](/docs/entities/contacts) — сущности из полей `CRM_ENTITY_TYPE` / `CRM_ENTITY_ID` - [Телефония — обзор](/docs/telephony) --- # Telephony Analytics: Voices ## Справочник голосов `GET /v1/calls/voices` Возвращает словарь доступных голосов для синтеза речи. Идентификаторы из ответа передаются как параметр `voice` в [`POST /v1/calls/auto-call`](../outbound/auto-call.md). ## Примеры ### curl — личный ключ ```bash curl https://vibecode.bitrix24.tech/v1/calls/voices \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl https://vibecode.bitrix24.tech/v1/calls/voices \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/voices', { headers: { 'X-Api-Key': 'YOUR_API_KEY' }, }) const { success, data } = await res.json() const voices = Object.entries(data) // [['ruinternalfemale', 'Русский (женский) (Default)'], ...] ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/voices', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | object | Словарь голосов: ключ — идентификатор голоса, значение — название для отображения с указанием источника синтеза в скобках | | `data.` | string | Название голоса. В скобках — источник синтеза: `Amazon` или `Default`. Передавайте `voiceId` как параметр `voice` в автозвонке | ## Пример ответа ```json { "success": true, "data": { "auenglishfemale": "Австралийский английский (женский) (Amazon)", "brportuguesefemale": "Бразильский португальский (женский) (Amazon)", "ruinternalfemale": "Русский (женский) (Default)", "ruinternalmale": "Русский (мужской) (Default)", "ukenglishfemale": "Английский (женский) (Amazon)", "ukenglishmale": "Английский (мужской) (Amazon)", "usenglishfemale": "Американский английский (женский) (Default)", "usenglishmale": "Американский английский (мужской) (Default)", "eurfrenchfemale": "Французский (женский) (Amazon)", "eurfrenchmale": "Французский (мужской) (Amazon)", "eurgermanfemale": "Немецкий (женский) (Default)", "eurgermanmale": "Немецкий (мужской) (Default)", "jpjapanesefemale": "Японский (женский) (Default)", "chchinesefemale": "Китайский (женский) (Default)" } } ``` ## Пример ответа при ошибке 403 — нет скоупа `telephony`: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'telephony' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`data` — объект-словарь, не массив.** Для перебора всех голосов используйте `Object.entries(data)`. Получить конкретный голос по идентификатору: `data['ruinternalfemale']`. **Голос по умолчанию.** При вызове автозвонка без параметра `voice` Битрикс24 выбирает голос по умолчанию исходя из языка портала. Для русскоязычного портала — `ruinternalfemale`. **Набор голосов зависит от тарифа.** Доступные голоса и их идентификаторы могут различаться в зависимости от тарифного плана портала. ## Смотрите также - [Автозвонок с синтезом речи](../outbound/auto-call.md) — использует идентификатор голоса из этого справочника - [Автозвонок с аудиофайлом](../outbound/auto-call-audio.md) - [Статистика звонков](./statistics.md) - [Телефония — обзор](/docs/telephony) --- # Telephony: Crm # Звонки в CRM Регистрация входящих и исходящих внешних звонков в CRM Битрикс24, отображение карточки звонка оператору, завершение со статусом и длительностью, прикрепление текстовой транскрипции диалога. Bitrix24 API: `telephony.externalcall.*`, `telephony.call.attachTranscription` Скоуп: `telephony` ## Операции - [Зарегистрировать звонок](./crm/register.md) — `POST /v1/calls/register` - [Завершить звонок](./crm/finish.md) — `POST /v1/calls/:callId/finish` - [Показать карточку](./crm/show.md) — `POST /v1/calls/:callId/show` - [Скрыть карточку](./crm/hide.md) — `POST /v1/calls/:callId/hide` - [Прикрепить транскрипцию](./crm/transcription.md) — `POST /v1/calls/:callId/transcription` ## Типовой сценарий 1. Входящий звонок поступил во внешнюю АТС → `POST /v1/calls/register` с `crmCreate: true` создаёт лид, если номер не найден в CRM. В ответе — `CALL_ID` и `CRM_ENTITY_ID`. 2. Карточка показывается оператору: `POST /v1/calls/:callId/show`. 3. Звонок завершается: `POST /v1/calls/:callId/finish` с длительностью и кодом результата. 4. После распознавания речи прикрепляется транскрипция: `POST /v1/calls/:callId/transcription` со списком реплик. ## Смотрите также - [Телефония — обзор](../telephony.md) - [Линии](../lines.md) — линии для параметра `lineNumber` в register - [Исходящие звонки](../outbound.md) — для инициации звонков через API --- # Telephony Crm: Finish ## Завершить звонок `POST /v1/calls/:callId/finish` Завершает зарегистрированный звонок: фиксирует длительность и итоговый статус, создаёт дело в связанной CRM-сущности. Вызывайте после окончания разговора, до прикрепления транскрипции. ## Параметры | Параметр | В | Тип | Обяз. | Описание | |----------|---|-----|:-----:|---------| | `callId` | path | string | да | `CALL_ID` из ответа [`POST /v1/calls/register`](./register.md) | ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `userId` | number | да | — | ID пользователя Битрикс24, завершившего звонок. [Список пользователей](/docs/entities/users) | | `duration` | number | да | — | Длительность звонка в секундах | | `statusCode` | string | нет | `"200"` при duration > 0, иначе `"304"` | Код завершения: `"200"` успешно, `"304"` пропущен, `"403"` запрещено, `"486"` занято, `"603"` отклонён, `"603-S"` отменён клиентом, `"402"` нет средств, `"404"` неверный номер, `"423"` заблокирован, `"480"` временно недоступен, `"484"` / `"503"` недоступное направление, `"OTHER"` | | `add_to_chat` | boolean | нет | — | Добавить событие о звонке в чат сотрудника | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/finish \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userId": 1, "duration": 120, "statusCode": "200" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/finish \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "userId": 1, "duration": 120, "statusCode": "200" }' ``` ### JavaScript — личный ключ ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/finish`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1, duration: 120, statusCode: '200', }), }) const { success, data } = await res.json() console.log('Дело:', data.CRM_ACTIVITY_ID) ``` ### JavaScript — OAuth-приложение ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/finish`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1, duration: 120, statusCode: '200', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `CALL_ID` | string | Идентификатор звонка | | `EXTERNAL_CALL_ID` | string \| null | Внешний идентификатор, переданный при регистрации | | `PORTAL_USER_ID` | number | ID пользователя Битрикс24 | | `PHONE_NUMBER` | string | Номер телефона | | `PORTAL_NUMBER` | string | Номер линии на портале | | `INCOMING` | string | Тип звонка: `"1"` — исходящий, `"2"` — входящий, `"3"` — входящий с перенаправлением, `"4"` — обратный звонок, `"5"` — информационный | | `CALL_DURATION` | number | Длительность в секундах | | `CALL_START_DATE` | object | Дата начала звонка. Возвращается как пустой объект `{}` — см. [особенности](#известные-особенности) | | `CALL_STATUS` | number | Статус завершения | | `CALL_VOTE` | number | Оценка звонка | | `COST` | number | Стоимость звонка | | `COST_CURRENCY` | string | Валюта стоимости | | `CALL_FAILED_CODE` | string | Переданный `statusCode` | | `CALL_FAILED_REASON` | string | Текстовое описание причины завершения | | `REST_APP_ID` | number \| null | ID приложения | | `REST_APP_NAME` | string \| false | Имя приложения | | `CRM_ACTIVITY_ID` | number \| false | ID созданного дела. `false`, если сущность не привязана | | `COMMENT` | string \| null | Комментарий к звонку | | `ID` | number | Внутренний ID записи о звонке | | `ERRORS` | object \| null | Ошибки, не прервавшие завершение (например `ACTIVITY_CREATION`) | | `CRM_ENTITY_TYPE` | string | Тип привязанной CRM-сущности (только при наличии привязки) | | `CRM_ENTITY_ID` | number | ID привязанной CRM-сущности (только при наличии привязки) | ## Пример ответа HTTP 200 — звонок завершён, дело создано: ```json { "success": true, "data": { "CALL_ID": "externalCall.00b1e735843c558431be668e3687a58b.1777974304", "EXTERNAL_CALL_ID": null, "PORTAL_USER_ID": 1, "PHONE_NUMBER": "+79161234567", "PORTAL_NUMBER": "REST_APP:", "INCOMING": "2", "CALL_DURATION": 120, "CALL_START_DATE": {}, "CALL_STATUS": 1, "CALL_VOTE": 0, "COST": 0, "COST_CURRENCY": "", "CALL_FAILED_CODE": "200", "CALL_FAILED_REASON": "", "REST_APP_ID": null, "REST_APP_NAME": false, "CRM_ACTIVITY_ID": 7995, "COMMENT": null, "CRM_ENTITY_TYPE": "LEAD", "CRM_ENTITY_ID": 1001069, "ID": 61 } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные параметры: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: userId (number), duration (number, seconds)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `userId` или `duration` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`CALL_START_DATE` всегда возвращается как пустой объект `{}`.** Реальную дату начала звонка смотрите в [статистике](/docs/telephony/analytics/statistics). **`CRM_ACTIVITY_ID: false` при отсутствии привязки.** В поле `ERRORS.ACTIVITY_CREATION` возвращается текстовое описание причины. Звонок при этом считается завершённым. **Значение `statusCode` влияет на метку в CRM.** Явная передача позволяет зафиксировать причину завершения независимо от длительности. ## Смотрите также - [Зарегистрировать звонок](./register.md) - [Прикрепить транскрипцию](./transcription.md) - [Показать карточку](./show.md) - [Статистика звонков](/docs/telephony/analytics/statistics) — дата начала и другие поля - [Лиды](/docs/entities/leads) — CRM-сущность, создаваемая при регистрации - [Контакты](/docs/entities/contacts) — CRM-сущность, к которой может быть привязан звонок - [Сделки](/docs/entities/deals) — звонок попадает в таймлайн связанной сделки --- # Telephony Crm: Hide ## Скрыть карточку звонка `POST /v1/calls/:callId/hide` Убирает карточку активного звонка поверх открытых окон Битрикс24 у указанного пользователя. Симметричен [`POST /v1/calls/:callId/show`](./show.md). ## Параметры | Параметр | В | Тип | Обяз. | Описание | |----------|---|-----|:-----:|---------| | `callId` | path | string | да | `CALL_ID` из ответа [`POST /v1/calls/register`](./register.md) | ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `userId` | number | да | — | ID пользователя Битрикс24, у которого скрывается карточка. [Список пользователей](/docs/entities/users) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/hide \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"userId": 1}' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/hide \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"userId": 1}' ``` ### JavaScript — личный ключ ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/hide`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1 }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/hide`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | boolean | `true` — карточка скрыта успешно; `false` — карточка не найдена (звонок не существует или уже завершён) | ## Пример ответа ```json { "success": true, "data": true } ``` ## Пример ответа при ошибке 400 — не передан обязательный параметр: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: userId (number)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `userId` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Признак успеха — поле `data`, не HTTP-статус.** При несуществующем `callId` Битрикс24 возвращает `HTTP 200` с `data: false`. Проверяйте значение поля, а не код ответа. **`userId` не обязан совпадать с тем, кто регистрировал звонок.** Карточку можно скрыть у любого пользователя портала. ## Смотрите также - [Показать карточку](./show.md) - [Зарегистрировать звонок](./register.md) - [Завершить звонок](./finish.md) --- # Telephony Crm: Register ## Зарегистрировать звонок `POST /v1/calls/register` Регистрирует входящий или исходящий звонок в Битрикс24 CRM. При `crmCreate: true` создаёт лид, если номер телефона не найден среди существующих сущностей. Возвращает `CALL_ID` для всех последующих операций со звонком. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `userId` | number | да | — | ID пользователя Битрикс24, принимающего звонок. [Список пользователей](/docs/entities/users) | | `phoneNumber` | string | да | — | Номер телефона звонящего в международном формате | | `type` | number | нет | — | Направление: `1` — исходящий, `2` — входящий, `3` — входящий с перенаправлением, `4` — обратный звонок, `5` — информационный | | `lineNumber` | string | нет | — | Номер внешней линии приложения. [Список линий](/docs/telephony/lines/list) | | `crmCreate` | boolean | нет | `false` | `true` — создать лид, если номер не найден в CRM | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/register \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userId": 1, "phoneNumber": "+79161234567", "type": 2, "crmCreate": true }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/register \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "userId": 1, "phoneNumber": "+79161234567", "type": 2, "crmCreate": true }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/register', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1, phoneNumber: '+79161234567', type: 2, crmCreate: true, }), }) const { success, data } = await res.json() const callId = data.CALL_ID ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/register', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1, phoneNumber: '+79161234567', type: 2, crmCreate: true, }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `CALL_ID` | string | Идентификатор звонка для всех последующих операций | | `CRM_CREATED_LEAD` | number \| null | ID созданного лида. `null`, если лид не создан | | `CRM_CREATED_ENTITIES` | array | Массив созданных CRM-сущностей `[{ENTITY_TYPE, ENTITY_ID}]` | | `CRM_ENTITY_TYPE` | string | Тип привязанной CRM-сущности: `LEAD`, `CONTACT`, `COMPANY` или пустая строка | | `CRM_ENTITY_ID` | number \| null | ID привязанной CRM-сущности. `null`, если сущность не привязана | ## Пример ответа HTTP 201 — звонок зарегистрирован, создан новый лид: ```json { "success": true, "data": { "CALL_ID": "externalCall.00b1e735843c558431be668e3687a58b.1777974304", "CRM_CREATED_LEAD": 1001069, "CRM_CREATED_ENTITIES": [{"ENTITY_TYPE": "LEAD", "ENTITY_ID": 1001069}], "CRM_ENTITY_TYPE": "LEAD", "CRM_ENTITY_ID": 1001069 } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные параметры: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: userId (number), phoneNumber (string)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `userId` или `phoneNumber` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Поиск существующей CRM-сущности при `crmCreate: true`.** Битрикс24 сначала ищет лид, контакт или компанию с совпадающим номером телефона. При нахождении `CRM_ENTITY_ID` указывает на существующую сущность, а `CRM_CREATED_LEAD` остаётся `null`. Новый лид создаётся только если совпадений нет. **`CRM_*` поля пустые при `crmCreate: false`.** Привязка к CRM может произойти автоматически при завершении через [`POST /v1/calls/:callId/finish`](./finish.md), если Битрикс24 найдёт совпадение по номеру в момент завершения. **`CALL_ID` — обязательный параметр для всех следующих шагов.** Сохраните его сразу: все операции `show`, `hide`, `finish`, `transcription` принимают `callId` в пути запроса. ## Смотрите также - [Завершить звонок](./finish.md) - [Показать карточку](./show.md) - [Скрыть карточку](./hide.md) - [Прикрепить транскрипцию](./transcription.md) - [Лиды](/docs/entities/leads) — сущности, создаваемые при `crmCreate: true` - [Контакты](/docs/entities/contacts) — альтернативная привязка по номеру телефона - [Линии](/docs/telephony/lines) — источник значений для `lineNumber` --- # Telephony Crm: Show ## Показать карточку звонка `POST /v1/calls/:callId/show` Отображает карточку активного звонка поверх открытых окон Битрикс24 у указанного пользователя. Вызывайте после [`POST /v1/calls/register`](./register.md), пока звонок не завершён. ## Параметры | Параметр | В | Тип | Обяз. | Описание | |----------|---|-----|:-----:|---------| | `callId` | path | string | да | `CALL_ID` из ответа [`POST /v1/calls/register`](./register.md) | ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `userId` | number | да | — | ID пользователя Битрикс24, которому показывается карточка. [Список пользователей](/docs/entities/users) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/show \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"userId": 1}' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/show \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"userId": 1}' ``` ### JavaScript — личный ключ ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/show`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1 }), }) const { success, data } = await res.json() ``` ### JavaScript — OAuth-приложение ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/show`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: 1 }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `data` | boolean | `true` — карточка показана успешно; `false` — карточка не показана (звонок не найден или уже завершён) | ## Пример ответа ```json { "success": true, "data": true } ``` ## Пример ответа при ошибке 400 — не передан обязательный параметр: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: userId (number)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `userId` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Признак успеха — поле `data`, не HTTP-статус.** При несуществующем или уже завершённом `callId` Битрикс24 возвращает `HTTP 200` с `data: false`. Проверяйте значение поля, а не код ответа. **`userId` не обязан совпадать с тем, кто регистрировал звонок.** Карточку можно показать любому пользователю портала — например, супервизору или замещающему оператору. ## Смотрите также - [Зарегистрировать звонок](./register.md) - [Скрыть карточку](./hide.md) - [Завершить звонок](./finish.md) --- # Telephony Crm: Transcription ## Прикрепить транскрипцию `POST /v1/calls/:callId/transcription` Прикрепляет текстовую транскрипцию диалога к завершённому звонку в Битрикс24. Звонок должен быть предварительно завершён через [`POST /v1/calls/:callId/finish`](./finish.md). ## Параметры | Параметр | В | Тип | Обяз. | Описание | |----------|---|-----|:-----:|---------| | `callId` | path | string | да | `CALL_ID` из ответа [`POST /v1/calls/register`](./register.md) | ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `messages` | array | да | — | Массив реплик диалога. Каждый элемент: `{side, startTime, stopTime, message}`. Не может быть пустым | | `messages[].side` | string | да | — | Сторона диалога: `"User"` — оператор, `"Client"` — клиент | | `messages[].startTime` | number | да | — | Время начала реплики в секундах от начала записи (≥ 0) | | `messages[].stopTime` | number | да | — | Время окончания реплики в секундах (> 0) | | `messages[].message` | string | да | — | Текст реплики (непустая строка) | | `cost` | number | нет | — | Стоимость распознавания | | `costCurrency` | string | нет | — | Валюта стоимости (например `"RUB"`) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/transcription \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "messages": [ {"side": "User", "startTime": 0, "stopTime": 3, "message": "Здравствуйте, чем могу помочь?"}, {"side": "Client", "startTime": 4, "stopTime": 9, "message": "Здравствуйте, хотел уточнить статус заказа"} ] }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/CALL_ID/transcription \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messages": [ {"side": "User", "startTime": 0, "stopTime": 3, "message": "Здравствуйте, чем могу помочь?"}, {"side": "Client", "startTime": 4, "stopTime": 9, "message": "Здравствуйте, хотел уточнить статус заказа"} ] }' ``` ### JavaScript — личный ключ ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/transcription`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ messages: [ { side: 'User', startTime: 0, stopTime: 3, message: 'Здравствуйте, чем могу помочь?' }, { side: 'Client', startTime: 4, stopTime: 9, message: 'Здравствуйте, хотел уточнить статус заказа' }, ], }), }) const { success, data } = await res.json() console.log('ID транскрипции:', data.TRANSCRIPT_ID) ``` ### JavaScript — OAuth-приложение ```javascript const callId = 'externalCall.00b1e735843c558431be668e3687a58b.1777974304' const res = await fetch(`https://vibecode.bitrix24.tech/v1/calls/${callId}/transcription`, { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ messages: [ { side: 'User', startTime: 0, stopTime: 3, message: 'Здравствуйте, чем могу помочь?' }, { side: 'Client', startTime: 4, stopTime: 9, message: 'Здравствуйте, хотел уточнить статус заказа' }, ], }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `TRANSCRIPT_ID` | number | Внутренний ID транскрипции на портале Битрикс24 | ## Пример ответа HTTP 200 — транскрипция прикреплена: ```json { "success": true, "data": { "TRANSCRIPT_ID": 3 } } ``` ## Пример ответа при ошибке 400 — не передан массив реплик: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: messages (non-empty array of {side, startTime, stopTime, message})" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `messages` или массив пустой | | 400 | `INVALID_MESSAGE_SHAPE` | Некорректная структура элемента `messages[i]`: неверный `side`, тип или диапазон `startTime`/`stopTime`, пустой `message`. В тексте ошибки — индекс некорректного элемента и нарушенное поле | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (текст в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **На незавершённом звонке Битрикс24 вернёт ошибку.** Порядок операций: `register` → `finish` → `transcription`. **Вайбкод валидирует структуру `messages` локально.** Каждый элемент проверяется до отправки в Битрикс24. Ошибка `INVALID_MESSAGE_SHAPE` содержит индекс некорректного элемента и точное описание нарушенного ограничения — это позволяет исправить конкретный элемент без повторной отправки всего массива. **`TRANSCRIPT_ID` используется только внутри портала.** Внешних эндпоинтов для чтения транскрипций по этому ID нет. ## Смотрите также - [Завершить звонок](./finish.md) — обязательный шаг перед транскрипцией - [Зарегистрировать звонок](./register.md) - [Статистика звонков](/docs/telephony/analytics/statistics) — просмотр записей завершённых звонков --- # Telephony: Lines # Линии Создание, обновление и удаление внешних линий приложения, а также чтение списка линий, арендованных у Voximplant или подключённых по SIP. Bitrix24 API: `telephony.externalLine.*`, `voximplant.line.get` Скоуп: `telephony` ## Операции - [Список линий приложения](./lines/list.md) — `GET /v1/telephony-lines` - [Добавить линию](./lines/create.md) — `POST /v1/telephony-lines` - [Обновить линию](./lines/update.md) — `PATCH /v1/telephony-lines/:number` - [Удалить линию](./lines/delete.md) — `DELETE /v1/telephony-lines/:number` - [Линии Voximplant](./lines/voximplant.md) — `GET /v1/voximplant-lines` ## Что нужно знать Два эндпоинта возвращают линии из разных источников: - `GET /v1/telephony-lines` — линии, **добавленные приложением** через `POST /v1/telephony-lines`. Актуально для приложений, подключающих собственную АТС к порталу. - `GET /v1/voximplant-lines` — линии, **арендованные у Voximplant** или подключённые по SIP, видимые порталу. Только чтение. Идентификатор линии приложения — строка `number`, заданная при создании. URL обновления и удаления использует именно её (URL-кодировать спецсимволы). ## Смотрите также - [Телефония — обзор](../telephony.md) - [Исходящие звонки](../outbound.md) — линии используются как `fromLine` --- # Telephony Lines: Create ## Добавить линию `POST /v1/telephony-lines` Регистрирует новую внешнюю линию приложения на портале. После создания линия доступна в [`GET /v1/telephony-lines`](./list.md) и может использоваться как `fromLine` в исходящих звонках. Поля передаются плоско в корне JSON — без обёртки `fields`. ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `number` | string | да | Уникальный идентификатор линии на портале | | `name` | string | нет | Отображаемое название линии | | `serverName` | string | нет | Имя сервера АТС | ## Примеры ### curl — личный ключ ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/telephony-lines" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "number": "sip-line-1", "name": "Основная линия", "serverName": "pbx.example.com" }' ``` ### curl — OAuth-приложение ```bash curl -X POST "https://vibecode.bitrix24.tech/v1/telephony-lines" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "number": "sip-line-1", "name": "Основная линия", "serverName": "pbx.example.com" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/telephony-lines', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ number: 'sip-line-1', name: 'Основная линия', serverName: 'pbx.example.com', }), }) const { success, data } = await res.json() console.log('Внутренний ID записи:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/telephony-lines', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ number: 'sip-line-1', name: 'Основная линия', serverName: 'pbx.example.com', }), }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | number | Внутренний идентификатор записи в Битрикс24. Для последующих операций не используется — обновление и удаление ведутся по `number` | ## Пример ответа ```json { "success": true, "data": { "id": 17 } } ``` ## Пример ответа при ошибке 422 — поле `number` не передано: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "NUMBER should not be empty" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку — текст в `error.message`. Причины: не передан `number`, дублирующий идентификатор | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`data.id` — внутренний идентификатор, не используется для других операций.** Обновление и удаление линии выполняются по `number` из тела запроса, а не по `data.id` из ответа. Сохраните переданное `number` — именно оно подставляется в URL `PATCH /v1/telephony-lines/:number` и `DELETE /v1/telephony-lines/:number`. Значения с `+`, пробелами или `/` допустимы; при подстановке в URL их нужно кодировать: `+79161234567` → `%2B79161234567`. ## Смотрите также - [Список линий приложения](./list.md) — `GET /v1/telephony-lines` - [Обновить линию](./update.md) — `PATCH /v1/telephony-lines/:number` - [Удалить линию](./delete.md) — `DELETE /v1/telephony-lines/:number` - [Исходящие звонки](/docs/telephony/outbound) — использование `number` как `fromLine` --- # Telephony Lines: Delete ## Удалить линию `DELETE /v1/telephony-lines/:number` Удаляет внешнюю линию приложения по идентификатору `number`. Восстановить удалённую линию через API нельзя — создайте новую с тем же `number` при необходимости. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `number` (path) | string | да | Идентификатор линии, заданный при создании. Если содержит спецсимволы — URL-кодировать | ## Примеры ### curl — личный ключ ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/telephony-lines/sip-line-1" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl -X DELETE "https://vibecode.bitrix24.tech/v1/telephony-lines/sip-line-1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const number = 'sip-line-1' const res = await fetch( `https://vibecode.bitrix24.tech/v1/telephony-lines/${encodeURIComponent(number)}`, { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY', }, } ) if (res.status === 204) { console.log('Линия удалена') } ``` ### JavaScript — OAuth-приложение ```javascript const number = 'sip-line-1' const res = await fetch( `https://vibecode.bitrix24.tech/v1/telephony-lines/${encodeURIComponent(number)}`, { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, } ) if (res.status === 204) { console.log('Линия удалена') } ``` ## Ответ При успешном удалении возвращается HTTP-статус `204 No Content` с пустым телом — успех проверяется по коду ответа. ## Пример ответа ```http HTTP/1.1 204 No Content ``` ## Пример ответа при ошибке 422 — ошибка Битрикс24: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "External line not found" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку — текст в `error.message`. Возникает в том числе при попытке удалить несуществующую линию | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Смотрите также - [Список линий приложения](./list.md) — найти `number` нужной линии перед удалением - [Добавить линию](./create.md) — создать новую линию с тем же `number` - [Обновить линию](./update.md) — `PATCH /v1/telephony-lines/:number` --- # Telephony Lines: List ## Список линий приложения `GET /v1/telephony-lines` Возвращает список внешних линий, добавленных приложением через `POST /v1/telephony-lines`. Поддерживает фильтрацию, сортировку и пагинацию. ## Параметры | Параметр | Тип | По умолч. | Описание | |----------|-----|-----------|---------| | `filter` (query) | object | — | Фильтрация по полям. Имена полей в UPPER_SNAKE_CASE: `NUMBER`, `NAME`, `SERVER_NAME`, `CRM_AUTO_CREATE`. [Синтаксис фильтрации](/docs/filtering). Пример: `?filter[NUMBER]=sip-line-1` | | `select` (query) | string | — | Выборка полей: `?select=number,name` | | `order` (query) | object | — | Сортировка: `?order[NUMBER]=asc` | | `limit` (query) | number | `50` | Количество записей (до 500) | | `offset` (query) | number | `0` | Смещение для пагинации | ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/telephony-lines" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/telephony-lines" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/telephony-lines', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data, meta } = await res.json() console.log(`Найдено ${meta.total} линий`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/telephony-lines', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data, meta } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив линий | | `data[].number` | string | Идентификатор линии, заданный при создании | | `data[].name` | string | Отображаемое название | | `data[].serverName` | string | Имя сервера АТС; присутствует только если задавалось при создании | | `data[].CRM_AUTO_CREATE` | string | Автосоздание CRM-сущности при входящем звонке через эту линию: `"Y"` — создавать, `"N"` — не создавать | | `meta.total` | number | Общее количество записей, соответствующих фильтру | | `meta.hasMore` | boolean | Есть ли ещё записи за пределами `limit` | ## Пример ответа HTTP 200, пустая выборка: ```json {"success":true,"data":[],"meta":{"total":0,"hasMore":false}} ``` HTTP 200, одна линия: ```json { "success": true, "data": [ { "number": "doc-test-line-001", "name": "Тестовая линия (аудит)", "CRM_AUTO_CREATE": "Y" } ], "meta": { "total": 1, "hasMore": false } } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'telephony' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Только линии этого приложения.** Список содержит линии, созданные через `POST /v1/telephony-lines` в рамках текущего API-ключа. Линии, арендованные у Voximplant или подключённые по SIP, доступны через [`GET /v1/voximplant-lines`](./voximplant.md). **Поле `CRM_AUTO_CREATE` в UPPER_SNAKE_CASE.** Остальные поля ответа — в camelCase. ## Смотрите также - [Добавить линию](./create.md) — `POST /v1/telephony-lines` - [Обновить линию](./update.md) — `PATCH /v1/telephony-lines/:number` - [Удалить линию](./delete.md) — `DELETE /v1/telephony-lines/:number` - [Линии Voximplant](./voximplant.md) — `GET /v1/voximplant-lines` - [Синтаксис фильтрации](/docs/filtering) - [Исходящие звонки](/docs/telephony/outbound) — линии используются как `fromLine` --- # Telephony Lines: Update ## Обновить линию `PATCH /v1/telephony-lines/:number` Обновляет параметры существующей внешней линии приложения. Идентификатор `number` задаётся при создании и не меняется. Поля передаются плоско в корне JSON — без обёртки `fields`. ## Параметры | Параметр | Тип | Обяз. | Описание | |----------|-----|:-----:|---------| | `number` (path) | string | да | Идентификатор линии, заданный при создании. Если содержит спецсимволы — URL-кодировать | ## Поля запроса (body) | Поле | Тип | Обяз. | Описание | |------|-----|:-----:|---------| | `name` | string | нет | Новое отображаемое название линии | | `serverName` | string | нет | Новое имя сервера АТС | ## Примеры ### curl — личный ключ ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/telephony-lines/sip-line-1" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Основная линия (обновлено)" }' ``` ### curl — OAuth-приложение ```bash curl -X PATCH "https://vibecode.bitrix24.tech/v1/telephony-lines/sip-line-1" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Основная линия (обновлено)" }' ``` ### JavaScript — личный ключ ```javascript const number = 'sip-line-1' const res = await fetch( `https://vibecode.bitrix24.tech/v1/telephony-lines/${encodeURIComponent(number)}`, { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Основная линия (обновлено)', }), } ) const { success, data } = await res.json() console.log('Идентификатор линии:', data.id) ``` ### JavaScript — OAuth-приложение ```javascript const number = 'sip-line-1' const res = await fetch( `https://vibecode.bitrix24.tech/v1/telephony-lines/${encodeURIComponent(number)}`, { method: 'PATCH', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Основная линия (обновлено)', }), } ) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data.id` | string | Идентификатор обновлённой линии (значение `number` из URL) | ## Пример ответа ```json { "success": true, "data": { "id": "sip-line-1" } } ``` ## Пример ответа при ошибке 422 — линия не найдена или ошибка Битрикс24: ```json { "success": false, "error": { "code": "BITRIX_ERROR", "message": "NUMBER should not be empty" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку — текст в `error.message` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **`data.id` — это `number` из URL, не целое число.** В отличие от ответа `POST /v1/telephony-lines`, где `data.id` является внутренним числовым идентификатором записи, ответ обновления возвращает строку — значение `number` из пути запроса. **Изменить `number` через обновление нельзя.** Идентификатор фиксируется при создании. Чтобы сменить `number` — удалите линию и создайте новую с нужным значением. ## Смотрите также - [Список линий приложения](./list.md) — `GET /v1/telephony-lines` - [Добавить линию](./create.md) — `POST /v1/telephony-lines` - [Удалить линию](./delete.md) — `DELETE /v1/telephony-lines/:number` --- # Telephony Lines: Voximplant ## Линии Voximplant `GET /v1/voximplant-lines` Возвращает список линий, арендованных у Voximplant или подключённых по SIP, которые видит портал. Операции создания, обновления и удаления для этих линий недоступны — только чтение. Идентификаторы из этого списка можно передавать как `fromLine` в исходящих звонках. ## Примеры ### curl — личный ключ ```bash curl "https://vibecode.bitrix24.tech/v1/voximplant-lines" \ -H "X-Api-Key: YOUR_API_KEY" ``` ### curl — OAuth-приложение ```bash curl "https://vibecode.bitrix24.tech/v1/voximplant-lines" \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/voximplant-lines', { headers: { 'X-Api-Key': 'YOUR_API_KEY', }, }) const { success, data } = await res.json() console.log(`Доступно ${data.length} линий`) ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/voximplant-lines', { headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', }, }) const { success, data } = await res.json() ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `success` | boolean | Всегда `true` при успехе | | `data` | array | Массив линий | | `data[].id` | string | Идентификатор линии. Префикс `reg` — арендованный у Voximplant номер, `sip` — подключённый SIP-канал | | `data[].name` | string | Отображаемое название | ## Пример ответа ```json { "success": true, "data": [ {"id": "reg133788", "name": "test"}, {"id": "reg150907", "name": "+79179087621"}, {"id": "sip7", "name": "Office PBX 1"}, {"id": "reg151083", "name": "Облачная АТС (9)"}, {"id": "sip11", "name": "Офисная АТС (11)"}, {"id": "reg151085", "name": "SIP line 2"} ] } ``` ## Пример ответа при ошибке 403 — нет скоупа: ```json { "success": false, "error": { "code": "SCOPE_DENIED", "message": "This endpoint requires 'telephony' scope" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 403 | `BITRIX_ACCESS_DENIED` | Скоуп есть, но у владельца ключа нет прав администратора телефонии (управление линиями) в Битрикс24 | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Два типа линий по префиксу `id`.** Идентификаторы `reg` соответствуют номерам, арендованным у Voximplant; `sip` — каналам, подключённым по SIP. Оба типа принимаются в качестве `fromLine` в исходящих звонках. **Источник для исходящих звонков.** В параметр `fromLine` методов [callback](../outbound/callback.md), [auto-call](../outbound/auto-call.md) и [auto-call-audio](../outbound/auto-call-audio.md) можно передавать как `id` из этого списка, так и `number` линии приложения из [`GET /v1/telephony-lines`](./list.md). Выбор зависит от того, через какой тип линии выполняется звонок. **Нужны права администратора телефонии.** Скоупа `telephony` у ключа недостаточно: список линий отдаётся только если у владельца ключа (для `vibe_app_` — у авторизованного пользователя) есть право управления линиями телефонии в Битрикс24. Без него запрос возвращает `403 BITRIX_ACCESS_DENIED`. Право управления линиями телефонии выдаёт администратор портала в настройках телефонии Битрикс24. Та же модель прав распространяется на статистику звонков — без прав администратора телефонии выборка приходит пустой. Это ограничение Битрикс24, а не Вайбкод. ## Смотрите также - [Список линий приложения](./list.md) — `GET /v1/telephony-lines` - [Callback](../outbound/callback.md) — `POST /v1/calls/callback` - [Автодозвон](../outbound/auto-call.md) — `POST /v1/calls/auto-call` - [Автодозвон с аудио](../outbound/auto-call-audio.md) — `POST /v1/calls/auto-call-audio` --- # Telephony: Outbound # Исходящие звонки Инициация исходящих звонков через инфраструктуру Voximplant: обратный звонок с соединением оператора и клиента, автоматические информационные звонки с синтезом речи или с воспроизведением аудиофайла. Bitrix24 API: `voximplant.callback.start`, `voximplant.infocall.*` Скоуп: `telephony` ## Операции - [Обратный звонок](./outbound/callback.md) — `POST /v1/calls/callback` - [Автозвонок с синтезом речи](./outbound/auto-call.md) — `POST /v1/calls/auto-call` - [Автозвонок с аудиофайлом](./outbound/auto-call-audio.md) — `POST /v1/calls/auto-call-audio` ## Типовой сценарий 1. Получить список доступных линий: [`GET /v1/voximplant-lines`](../lines/voximplant.md). 2. Выбрать `fromLine` из ответа. 3. Инициировать звонок одним из трёх эндпоинтов выше. 4. После завершения звонка запись появится в [статистике](../analytics/statistics.md) с типом 4 (обратный звонок) или 5 (информационный). ## Смотрите также - [Телефония — обзор](../telephony.md) - [Линии](../lines.md) — источник `fromLine` - [Справочник голосов](../analytics/voices.md) — для параметра `voice` в автозвонке с синтезом речи --- # Telephony Outbound: Auto Call ## Запустить автозвонок с синтезом речи `POST /v1/calls/auto-call` Набирает `toNumber` и после принятия звонка воспроизводит синтезированный текст (`textToPronounce`). Оператор не задействован. Применяется для автоматических уведомлений, напоминаний и роботизированных обзвонов. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `fromLine` | string | да | — | ID линии исходящего звонка. Список линий — [`GET /v1/voximplant-lines`](../lines/voximplant.md) | | `toNumber` | string | да | — | Номер телефона в международном формате | | `textToPronounce` | string | да | — | Текст для синтеза речи | | `voice` | string | нет | голос языка портала | ID голоса. Список доступных — [`GET /v1/calls/voices`](../analytics/voices.md) | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/auto-call \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "fromLine": "YOUR_LINE_ID", "toNumber": "+79161234567", "textToPronounce": "Здравствуйте! Ваш заказ готов к выдаче." }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/auto-call \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fromLine": "YOUR_LINE_ID", "toNumber": "+79161234567", "textToPronounce": "Здравствуйте! Ваш заказ готов к выдаче." }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/auto-call', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ fromLine: 'YOUR_LINE_ID', toNumber: '+79161234567', textToPronounce: 'Здравствуйте! Ваш заказ готов к выдаче.', }), }) const { success, data } = await res.json() const callId = data.CALL_ID ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/auto-call', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ fromLine: 'YOUR_LINE_ID', toNumber: '+79161234567', textToPronounce: 'Здравствуйте! Ваш заказ готов к выдаче.', }), }) const { success, data } = await res.json() const callId = data.CALL_ID ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `RESULT` | boolean | `true` при успешном инициировании звонка | | `CALL_ID` | string | Идентификатор инициированного звонка с префиксом `infocall.` | ## Пример ответа HTTP 200 — звонок инициирован: ```json { "success": true, "data": { "RESULT": true, "CALL_ID": "infocall.a3f2c1e4b8d06f7a9e2c5d1b4f8a3e06.1777974900" } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные параметры: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: fromLine (string — ID from GET /v1/voximplant-lines), toNumber (string), textToPronounce (string)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `fromLine`, `toNumber` или `textToPronounce` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (сообщение в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Голос по умолчанию.** Если `voice` не указан, Битрикс24 использует голос, соответствующий языку портала. Для русскоязычных порталов — `ruinternalfemale`. Полный список доступных голосов — [`GET /v1/calls/voices`](../analytics/voices.md). **Превышение месячного лимита.** При исчерпании квоты автозвонков Битрикс24 возвращает `BITRIX_ERROR` с сообщением `"Infocall limit for this month is exceeded"`. Квота обновляется в начале следующего расчётного периода. **Базовая линия не поддерживается.** Попытка использовать базовую линию портала вместо выделенной возвращает `BITRIX_ERROR: "Making infocall using LINK_BASE_NUMBER is not allowed"`. **Запись в статистике.** После завершения звонок появляется в [статистике](../analytics/statistics.md) с `CALL_TYPE: "5"`. ## Смотрите также - [Обратный звонок](./callback.md) - [Автозвонок с аудиофайлом](./auto-call-audio.md) - [Справочник голосов](../analytics/voices.md) - [Статистика звонков](../analytics/statistics.md) - [Список линий Voximplant](../lines/voximplant.md) --- # Telephony Outbound: Auto Call Audio ## Запустить автозвонок с воспроизведением аудиофайла `POST /v1/calls/auto-call-audio` Набирает `toNumber` и после принятия звонка воспроизводит MP3-файл по ссылке `url`. Битрикс24 загружает файл в момент звонка. Оператор не задействован. Применяется для обзвонов с заранее записанным голосовым сообщением. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `fromLine` | string | да | — | ID линии исходящего звонка. Список линий — [`GET /v1/voximplant-lines`](../lines/voximplant.md) | | `toNumber` | string | да | — | Номер телефона в международном формате | | `url` | string | да | — | Прямая HTTPS-ссылка на MP3-файл | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/auto-call-audio \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "fromLine": "YOUR_LINE_ID", "toNumber": "+79161234567", "url": "https://example.com/audio/greeting.mp3" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/auto-call-audio \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fromLine": "YOUR_LINE_ID", "toNumber": "+79161234567", "url": "https://example.com/audio/greeting.mp3" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/auto-call-audio', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ fromLine: 'YOUR_LINE_ID', toNumber: '+79161234567', url: 'https://example.com/audio/greeting.mp3', }), }) const { success, data } = await res.json() const callId = data.CALL_ID ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/auto-call-audio', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ fromLine: 'YOUR_LINE_ID', toNumber: '+79161234567', url: 'https://example.com/audio/greeting.mp3', }), }) const { success, data } = await res.json() const callId = data.CALL_ID ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `RESULT` | boolean | `true` при успешном инициировании звонка | | `CALL_ID` | string | Идентификатор инициированного звонка с префиксом `infocall.` | ## Пример ответа HTTP 200 — звонок инициирован: ```json { "success": true, "data": { "RESULT": true, "CALL_ID": "infocall.b7e1d4c2a9f03e8b6d5c2a1f4e9b7d03.1777975100" } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные параметры: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: fromLine (string — ID from GET /v1/voximplant-lines), toNumber (string), url (string — URL to audio file)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `fromLine`, `toNumber` или `url` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (сообщение в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Формат и доступность файла.** Файл должен быть в формате MP3 и доступен по прямой HTTPS-ссылке без авторизации. Битрикс24 загружает файл в момент совершения звонка — если ссылка недоступна, возвращается `BITRIX_ERROR`. **Запись в статистике.** После завершения звонок появляется в [статистике](../analytics/statistics.md) с `CALL_TYPE: "5"`. **Ограничения лимита и линии** — те же, что у [автозвонка с синтезом речи](./auto-call.md#известные-особенности): месячная квота и запрет базовой линии. ## Смотрите также - [Обратный звонок](./callback.md) - [Автозвонок с синтезом речи](./auto-call.md) - [Статистика звонков](../analytics/statistics.md) - [Список линий Voximplant](../lines/voximplant.md) --- # Telephony Outbound: Callback ## Инициировать обратный звонок `POST /v1/calls/callback` Инициирует обратный звонок: Битрикс24 сначала звонит на линию оператора (`fromLine`), после принятия звонка соединяет с клиентом (`toNumber`). Применяется для исходящих звонков из CRM без ручного набора номера. ## Поля запроса (body) | Параметр | Тип | Обяз. | По умолч. | Описание | |----------|-----|:-----:|-----------|---------| | `fromLine` | string | да | — | ID линии оператора. Список линий — [`GET /v1/voximplant-lines`](../lines/voximplant.md) | | `toNumber` | string | да | — | Номер телефона клиента в международном формате | ## Примеры ### curl — личный ключ ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/callback \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "fromLine": "YOUR_LINE_ID", "toNumber": "+79161234567" }' ``` ### curl — OAuth-приложение ```bash curl -X POST https://vibecode.bitrix24.tech/v1/calls/callback \ -H "X-Api-Key: YOUR_APP_KEY" \ -H "Authorization: Bearer USER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fromLine": "YOUR_LINE_ID", "toNumber": "+79161234567" }' ``` ### JavaScript — личный ключ ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/callback', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ fromLine: 'YOUR_LINE_ID', toNumber: '+79161234567', }), }) const { success, data } = await res.json() const callId = data.CALL_ID ``` ### JavaScript — OAuth-приложение ```javascript const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/callback', { method: 'POST', headers: { 'X-Api-Key': 'YOUR_APP_KEY', 'Authorization': 'Bearer USER_SESSION_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ fromLine: 'YOUR_LINE_ID', toNumber: '+79161234567', }), }) const { success, data } = await res.json() const callId = data.CALL_ID ``` ## Поля ответа | Поле | Тип | Описание | |------|-----|---------| | `RESULT` | boolean | `true` при успешном инициировании звонка | | `CALL_ID` | string | Идентификатор инициированного звонка с префиксом `callback.` | ## Пример ответа HTTP 200 — звонок инициирован: ```json { "success": true, "data": { "RESULT": true, "CALL_ID": "callback.e7804636435209e12c9cef1ec1bcead1.1777974876" } } ``` ## Пример ответа при ошибке 400 — не переданы обязательные параметры: ```json { "success": false, "error": { "code": "MISSING_PARAMS", "message": "Required: fromLine (string), toNumber (string)" } } ``` ## Ошибки | HTTP | Код | Описание | |------|-----|---------| | 400 | `MISSING_PARAMS` | Не передан `fromLine` или `toNumber` | | 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` | | 401 | `INVALID_API_KEY` | Неверный API-ключ | | 401 | `TOKEN_MISSING` | Ключ не имеет настроенных токенов Битрикс24 | | 401 | `KEY_INACTIVE` | API-ключ неактивен или отозван | | 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `telephony` | | 422 | `BITRIX_ERROR` | Битрикс24 вернул ошибку (сообщение в `error.message`) | | 429 | `RATE_LIMITED` | Превышен лимит запросов | | 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен | Полный список общих ошибок API — [Ошибки](/docs/errors). ## Известные особенности **Порядок соединения.** Битрикс24 сначала звонит на линию оператора. Звонок клиенту совершается только после того, как оператор принял звонок. Если оператор не отвечает — клиент не будет потревожен. **Префикс `CALL_ID`.** Идентификаторы обратных звонков начинаются с `callback.` — в отличие от зарегистрированных звонков (`externalCall.`) и информационных (`infocall.`). **Запись в статистике.** После завершения звонок появляется в [статистике](../analytics/statistics.md) с `CALL_TYPE: "4"`. **Реальные расходы.** Каждый вызов инициирует звонок на номер оператора и тратит средства портала. ## Смотрите также - [Автозвонок с синтезом речи](./auto-call.md) - [Автозвонок с аудиофайлом](./auto-call-audio.md) - [Статистика звонков](../analytics/statistics.md) - [Список линий Voximplant](../lines/voximplant.md) --- # Recipe: Ai Assistant # AI-ассистент с OpenAI 🧠 **Сложность:** advanced | **Скоупы:** crm, task | **Стек:** Node.js, openai SDK ## Что делаем Создаём интеллектуального помощника, который анализирует историю сделки в CRM (активности, таймлайн) с помощью GPT и предлагает следующее действие. На основе рекомендации ассистент автоматически создаёт задачу с конкретным описанием. Это ускоряет работу менеджеров и повышает конверсию сделок. ## Необходимо - API-ключ Вайбкод с правами `crm, task` - OpenAI API Key - Node.js 18+ - Пакеты: `openai` ## Полный код ```javascript // ai-crm-assistant.js // AI-ассистент: анализирует сделку и создаёт задачу с рекомендацией import OpenAI from 'openai'; const API_KEY = process.env.VIBE_API_KEY; const BASE_URL = process.env.VIBE_BASE_URL; const OPENAI_API_KEY = process.env.OPENAI_API_KEY; const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); const HEADERS = { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json', }; // Получаем данные сделки через Entity API async function getDeal(dealId) { const response = await fetch(`${BASE_URL}/v1/deals/${dealId}`, { headers: { 'X-Api-Key': API_KEY }, }); const { data } = await response.json(); return data; } // Получаем активности сделки через Entity API async function getDealActivities(dealId) { const response = await fetch(`${BASE_URL}/v1/activities/search`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ filter: { ownerTypeId: 2, // Сделка ownerId: dealId, }, select: ['id', 'subject', 'description', 'typeId', 'createdAt', 'completed'], sort: { createdAt: 'desc' }, }), }); const { data } = await response.json(); return data || []; } // Отправляем контекст сделки в GPT для анализа async function analyzeWithGPT(deal, activities) { // Формируем текстовое описание истории сделки const activitiesText = activities .map((item) => { const status = item.completed ? 'завершено' : 'в работе'; return `- [${item.createdAt}] ${item.subject} (${status})`; }) .join('\n'); const prompt = `Ты — опытный менеджер по продажам. Проанализируй сделку и предложи конкретное следующее действие. Сделка: - Название: ${deal.title} - Стадия: ${deal.stageId} - Сумма: ${deal.amount} ${deal.currency} - Дата создания: ${deal.createdAt} История активностей: ${activitiesText || 'Активностей пока нет'} Ответь в формате JSON: { "analysis": "краткий анализ текущей ситуации (2-3 предложения)", "nextAction": "конкретное следующее действие", "taskTitle": "заголовок задачи для менеджера", "taskDescription": "подробное описание задачи", "priority": "high/medium/low", "deadlineDays": число дней на выполнение }`; const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: prompt }], response_format: { type: 'json_object' }, temperature: 0.3, }); return JSON.parse(completion.choices[0].message.content); } // Создаём задачу через Entity API async function createTask(recommendation, dealId, responsibleId) { const deadline = new Date(); deadline.setDate(deadline.getDate() + (recommendation.deadlineDays || 3)); const priorityMap = { high: 2, medium: 1, low: 0 }; const response = await fetch(`${BASE_URL}/v1/tasks`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ title: `[AI] ${recommendation.taskTitle}`, description: [ recommendation.taskDescription, '', '---', `Анализ AI: ${recommendation.analysis}`, `Сделка ID: ${dealId}`, ].join('\n'), responsibleId: responsibleId, priority: priorityMap[recommendation.priority] || 1, deadline: deadline.toISOString(), ufCrmTask: [`D_${dealId}`], // Привязка к сделке }), }); const { data } = await response.json(); return data; } // Основная функция: анализ сделки и создание задачи async function processDeal(dealId) { console.log(`\n📋 Загружаем сделку #${dealId}...`); const deal = await getDeal(dealId); if (!deal) { console.error('Сделка не найдена'); return; } console.log(` Название: ${deal.title}`); console.log(` Стадия: ${deal.stageId}, Сумма: ${deal.amount}`); console.log('📜 Загружаем историю активностей...'); const activities = await getDealActivities(dealId); console.log(` Найдено активностей: ${activities.length}`); console.log('🧠 Анализируем с помощью GPT...'); const recommendation = await analyzeWithGPT(deal, activities); console.log('\n💡 Рекомендация AI:'); console.log(` Анализ: ${recommendation.analysis}`); console.log(` Действие: ${recommendation.nextAction}`); console.log(` Приоритет: ${recommendation.priority}`); console.log('\n📝 Создаём задачу...'); const task = await createTask(recommendation, dealId, deal.assignedById); console.log(` Задача создана, ID: ${task.id}`); } // Запуск: передаём ID сделки аргументом const dealId = process.argv[2]; if (!dealId) { console.log('Использование: node ai-crm-assistant.js '); process.exit(1); } processDeal(dealId).catch(console.error); ``` ## Как это работает 1. Скрипт принимает ID сделки и загружает её данные через Entity API (`GET /v1/deals/:id`). 2. Далее через Entity API (`POST /v1/activities/search`) запрашиваются активности сделки — звонки, письма, встречи, комментарии. 3. Вся информация о сделке и её истории формируется в промпт и отправляется в GPT-4o с запросом на анализ и рекомендацию. 4. GPT возвращает структурированный JSON с анализом ситуации, рекомендованным действием и параметрами задачи. 5. На основе ответа GPT автоматически создаётся задача через Entity API (`POST /v1/tasks`), привязанная к сделке. 6. Задача назначается ответственному менеджеру из сделки с дедлайном и приоритетом по рекомендации AI. ## Что можно улучшить - Запускать анализ автоматически при смене стадии сделки (через polling или webhooks) - Добавить память: сохранять предыдущие рекомендации и учитывать их при следующем анализе - Использовать Function Calling в OpenAI для более точного управления действиями (создание звонков, писем) - Добавить Slack/Telegram уведомление менеджеру с кратким описанием рекомендации --- # Recipe: Crm Analytics # CRM-аналитика: воронка 📊 **Сложность:** beginner | **Скоупы:** crm | **Стек:** Python, requests ## Что делаем Пишем Python-скрипт, который выгружает все сделки из CRM через Вайбкод Entity API, группирует их по стадиям воронки и рассчитывает конверсию между этапами и средний чек. Результат выводится в консоль в виде наглядной таблицы. Полезно для быстрого анализа эффективности продаж без сторонних BI-инструментов. ## Необходимо - API-ключ Вайбкод с правами `crm` - Python 3.8+ - Пакет: `requests` ## Полный код ```python # crm_analytics.py # Анализ воронки продаж: конверсия по стадиям и средний чек import os import requests from collections import defaultdict API_KEY = os.environ["VIBE_API_KEY"] BASE_URL = os.environ["VIBE_BASE_URL"] # например https://vibecode.bitrix24.tech HEADERS = { "X-Api-Key": API_KEY, } # Названия стадий воронки (стандартные для Bitrix24) # Примечание: на порталах с несколькими воронками стадии имеют C-префикс: # C2:WON, C4:NEW и т.д. Функция get_stage_name() обрабатывает оба формата. STAGE_NAMES = { "NEW": "Новая", "PREPARATION": "Подготовка", "PREPAYMENT_INVOICE": "Счёт на предоплату", "EXECUTING": "В работе", "FINAL_INVOICE": "Финальный счёт", "WON": "Успешная", "LOSE": "Проигранная", } def get_stage_name(stage_id): """Получает название стадии, обрабатывая C-префиксы множественных воронок""" # C2:WON → WON, C4:NEW → NEW base = stage_id.split(":")[-1] if ":" in stage_id else stage_id return STAGE_NAMES.get(base, stage_id) def fetch_all_deals(): """Загружаем все сделки через Entity API с авто-пагинацией""" all_deals = [] offset = 0 limit = 200 while True: response = requests.get( f"{BASE_URL}/v1/deals", headers=HEADERS, params={ "select": "id,stageId,amount,currency", "limit": limit, "offset": offset, }, ) data = response.json() deals = data.get("data", []) all_deals.extend(deals) # Если вернулось меньше limit — всё загружено if len(deals) < limit: break offset += limit return all_deals def analyze_funnel(deals): """Группируем сделки по стадиям и считаем метрики""" stages = defaultdict(lambda: {"count": 0, "total_amount": 0}) for deal in deals: stage = deal.get("stageId", "UNKNOWN") amount = float(deal.get("amount", 0) or 0) stages[stage]["count"] += 1 stages[stage]["total_amount"] += amount return stages def print_funnel_report(stages, total_deals): """Выводим отчёт по воронке""" print("\n" + "=" * 65) print(" АНАЛИЗ ВОРОНКИ ПРОДАЖ") print("=" * 65) print(f"\n Всего сделок: {total_deals}\n") # Порядок стадий для отображения stage_order = [ "NEW", "PREPARATION", "PREPAYMENT_INVOICE", "EXECUTING", "FINAL_INVOICE", "WON", "LOSE", ] print(f" {'Стадия':<25} {'Кол-во':>8} {'Конверсия':>10} {'Ср. чек':>12}") print(" " + "-" * 58) for stage_id in stage_order: if stage_id not in stages: continue info = stages[stage_id] count = info["count"] name = get_stage_name(stage_id) # Конверсия относительно общего количества conversion = (count / total_deals * 100) if total_deals > 0 else 0 # Средний чек avg_check = info["total_amount"] / count if count > 0 else 0 # Визуальная шкала bar = "█" * int(conversion / 3) print(f" {name:<25} {count:>8} {conversion:>9.1f}% {avg_check:>11,.0f}₽") print(f" {bar}") # Итоговые метрики (суммируем все WON/LOSE стадии, включая C-префиксы) won = {"count": 0, "total_amount": 0} lost = {"count": 0, "total_amount": 0} for sid, info in stages.items(): base = sid.split(":")[-1] if ":" in sid else sid if base == "WON": won["count"] += info["count"] won["total_amount"] += info["total_amount"] elif base == "LOSE": lost["count"] += info["count"] lost["total_amount"] += info["total_amount"] closed = won["count"] + lost["count"] print("\n" + "-" * 65) print(f" Общая выручка (WON): {won['total_amount']:>15,.0f}₽") if closed > 0: win_rate = won["count"] / closed * 100 print(f" Win Rate: {win_rate:>14.1f}%") if won["count"] > 0: avg_won = won["total_amount"] / won["count"] print(f" Средний чек (WON): {avg_won:>15,.0f}₽") print("=" * 65) def main(): print("📊 Загружаем сделки из CRM...") deals = fetch_all_deals() print(f" Загружено: {len(deals)} сделок") stages = analyze_funnel(deals) print_funnel_report(stages, len(deals)) if __name__ == "__main__": main() ``` ## Как это работает 1. Скрипт загружает все сделки из CRM через Entity API (`GET /v1/deals`) с авто-пагинацией через limit/offset. 2. Каждая сделка группируется по стадии (`stageId`), подсчитывается количество и суммируется бюджет. 3. Для каждой стадии рассчитывается конверсия относительно общего числа сделок и средний чек. 4. Результаты выводятся в виде текстовой таблицы с визуальными шкалами. 5. Отдельно рассчитываются итоговые метрики: общая выручка, Win Rate и средний чек успешных сделок. ## Что можно улучшить - Использовать `POST /v1/deals/aggregate` с `groupBy: ["stageId"]` вместо загрузки всех записей — быстрее и экономнее - Добавить фильтрацию по периоду (месяц, квартал, год) для сравнения динамики - Экспортировать результат в CSV или Excel для дальнейшей работы - Визуализировать воронку с помощью matplotlib или plotly --- # Recipe: Disk Files # Работа с файлами Диска **Сложность:** beginner | **Скоупы:** disk | **Стек:** cURL / Node.js ## Что делаем Управляем хранилищами, папками и файлами Bitrix24 Диска через Entity API. Получаем список хранилищ, просматриваем содержимое корневой папки (через обходной путь), создаём подпапки, получаем информацию о файлах. Примеры даны в cURL и Node.js. > **Ограничение:** загрузка файлов (`disk.folder.uploadfile`) пока не покрывается Entity API. Этот метод требует multipart-загрузку и не имеет entity-обёртки. Когда обёртка появится, рецепт будет обновлён. ## Доступные entity-эндпоинты | Entity | Эндпоинт | Операции | |--------|----------|----------| | **storages** | `GET /v1/storages`, `GET /v1/storages/:id` | list, get (только чтение) | | **folders** | `GET /v1/folders`, `GET /v1/folders/:id`, `POST /v1/folders`, `PATCH /v1/folders/:id`, `DELETE /v1/folders/:id` | list, get, create, update, delete | | **files** | `GET /v1/files`, `GET /v1/files/:id`, `PATCH /v1/files/:id`, `DELETE /v1/files/:id` | list, get, update, delete (без create) | ## Необходимо - API-ключ Вайбкод с правами `disk` - cURL (установлен в большинстве ОС) или Node.js 18+ ## Полный код ```bash #!/bin/bash # disk-operations.sh # Операции с Bitrix24 Диском через Entity API API_KEY="${VIBE_API_KEY}" BASE_URL="${VIBE_BASE_URL}" # ────────────────────────────────────────── # 1. Получаем список хранилищ # GET /v1/storages # ────────────────────────────────────────── echo "Список хранилищ:" curl -s -H "X-Api-Key: ${API_KEY}" \ "${BASE_URL}/v1/storages" | python3 -m json.tool # Ответ содержит поля: id, name, entityType, entityId, rootObjectId # rootObjectId — это ID корневой папки хранилища (нужен дальше) # ────────────────────────────────────────── # 2. Получаем конкретное хранилище и его rootObjectId # GET /v1/storages/:id # ────────────────────────────────────────── STORAGE_ID=1 echo -e "\nХранилище #${STORAGE_ID}:" curl -s -H "X-Api-Key: ${API_KEY}" \ "${BASE_URL}/v1/storages/${STORAGE_ID}" | python3 -m json.tool # ────────────────────────────────────────── # 3. Содержимое корневой папки хранилища # Метода disk.storage.getchildren нет в Entity API. # Обходной путь: берём rootObjectId из хранилища # и запрашиваем GET /v1/folders?filter[parentId]=ROOT_OBJECT_ID # ────────────────────────────────────────── ROOT_FOLDER_ID=3 # rootObjectId из шага 2 echo -e "\nСодержимое корневой папки #${ROOT_FOLDER_ID}:" curl -s -H "X-Api-Key: ${API_KEY}" \ "${BASE_URL}/v1/folders?filter[parentId]=${ROOT_FOLDER_ID}" | python3 -m json.tool # ────────────────────────────────────────── # 4. Создаём подпапку # POST /v1/folders # parentId — ID родительской папки (rootObjectId или любая другая) # ────────────────────────────────────────── echo -e "\nСоздаём папку 'Документы клиентов':" curl -s -X POST "${BASE_URL}/v1/folders" \ -H "X-Api-Key: ${API_KEY}" \ -H "Content-Type: application/json" \ -d "{ \"parentId\": ${ROOT_FOLDER_ID}, \"name\": \"Документы клиентов\" }" | python3 -m json.tool # ────────────────────────────────────────── # 5. Список файлов # GET /v1/files # ────────────────────────────────────────── echo -e "\nФайлы на диске:" curl -s -H "X-Api-Key: ${API_KEY}" \ "${BASE_URL}/v1/files?limit=10" | python3 -m json.tool # ────────────────────────────────────────── # 6. Информация о конкретном файле # GET /v1/files/:id # ────────────────────────────────────────── FILE_ID=42 echo -e "\nФайл #${FILE_ID}:" curl -s -H "X-Api-Key: ${API_KEY}" \ "${BASE_URL}/v1/files/${FILE_ID}" | python3 -m json.tool # ────────────────────────────────────────── # 7. Пакетный запрос: получить хранилища + файлы за один вызов # POST /v1/batch (entity-формат) # ────────────────────────────────────────── echo -e "\nПакетный запрос — хранилища + файлы:" curl -s -X POST "${BASE_URL}/v1/batch" \ -H "X-Api-Key: ${API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "calls": [ { "entity": "storages", "action": "list" }, { "entity": "files", "action": "list", "params": { "limit": 5 } } ] }' | python3 -m json.tool ``` ```javascript // disk-operations.js // Node.js: работа с Диском через Entity API const API_KEY = process.env.VIBE_API_KEY; const BASE_URL = process.env.VIBE_BASE_URL; const HEADERS = { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json', }; // Хелпер для GET-запросов async function apiGet(path) { const response = await fetch(`${BASE_URL}${path}`, { headers: { 'X-Api-Key': API_KEY }, }); return response.json(); } // Хелпер для POST-запросов async function apiPost(path, body) { const response = await fetch(`${BASE_URL}${path}`, { method: 'POST', headers: HEADERS, body: JSON.stringify(body), }); return response.json(); } // 1. Список хранилищ (GET /v1/storages) async function listStorages() { console.log('Хранилища:'); const { data } = await apiGet('/v1/storages'); for (const s of data) { console.log(` [${s.id}] ${s.name} (${s.entityType}) — корневая папка: ${s.rootObjectId}`); } return data; } // 2. Содержимое корневой папки хранилища // Обходной путь: storage.rootObjectId → GET /v1/folders?filter[parentId]=... async function listStorageRootContents(storageId) { console.log(`\nСодержимое хранилища #${storageId}:`); // Получаем хранилище, чтобы узнать rootObjectId const { data: storage } = await apiGet(`/v1/storages/${storageId}`); const rootFolderId = storage.rootObjectId; console.log(` Корневая папка: #${rootFolderId}`); // Запрашиваем дочерние элементы корневой папки const { data: children } = await apiGet( `/v1/folders?filter[parentId]=${rootFolderId}` ); for (const item of children) { console.log(` [${item.id}] ${item.name}`); } return { rootFolderId, children }; } // 3. Создание подпапки (POST /v1/folders) async function createFolder(parentId, folderName) { console.log(`\nСоздаём папку "${folderName}" в папке #${parentId}...`); const { data } = await apiPost('/v1/folders', { parentId, name: folderName, }); console.log(` Папка создана: id=${data.id}`); return data; } // 4. Информация о файле (GET /v1/files/:id) async function getFileInfo(fileId) { const { data } = await apiGet(`/v1/files/${fileId}`); console.log(`\nФайл #${fileId}: ${data.name} (${data.size} байт)`); return data; } // 5. Список файлов с фильтром (GET /v1/files) async function listFiles(folderId) { console.log(`\nФайлы в папке #${folderId}:`); const { data } = await apiGet( `/v1/files?filter[folderId]=${folderId}` ); for (const f of data) { console.log(` [${f.id}] ${f.name} — ${f.size} байт`); } return data; } // 6. Пакетный запрос: хранилища + файлы за один вызов // POST /v1/batch (entity-формат) async function batchDiskInfo() { console.log('\nПакетный запрос:'); const result = await apiPost('/v1/batch', { calls: [ { entity: 'storages', action: 'list' }, { entity: 'files', action: 'list', params: { limit: 5 } }, ], }); const [storagesResult, filesResult] = result.data.results; console.log(` Хранилищ: ${storagesResult.data?.length ?? 0}`); console.log(` Файлов (первые 5): ${filesResult.data?.length ?? 0}`); return result.data; } // 7. Переименование файла (PATCH /v1/files/:id) async function renameFile(fileId, newName) { console.log(`\nПереименование файла #${fileId} → "${newName}"...`); const response = await fetch(`${BASE_URL}/v1/files/${fileId}`, { method: 'PATCH', headers: HEADERS, body: JSON.stringify({ name: newName }), }); const { data } = await response.json(); console.log(` Готово: ${data.name}`); return data; } // Демонстрация async function demo() { // Список хранилищ const storages = await listStorages(); if (storages.length === 0) { console.log('Хранилищ не найдено'); return; } // Содержимое корневой папки первого хранилища const storageId = storages[0].id; const { rootFolderId } = await listStorageRootContents(storageId); // Создаём папку в корне хранилища const folder = await createFolder(rootFolderId, `Проект_${Date.now()}`); // Пакетный запрос await batchDiskInfo(); console.log('\nВсе операции выполнены.'); console.log('Загрузка файлов (disk.folder.uploadfile) пока не поддерживается через Entity API.'); } demo().catch(console.error); ``` ## Как это работает 1. **Список хранилищ** — `GET /v1/storages` возвращает все доступные хранилища (личное, общее, хранилища отделов). Ключевое поле: `rootObjectId` — ID корневой папки. 2. **Содержимое хранилища** — прямого эндпоинта `disk.storage.getchildren` в Entity API нет. Обходной путь: - Получаем хранилище: `GET /v1/storages/:id` - Извлекаем `rootObjectId` - Запрашиваем содержимое: `GET /v1/folders?filter[parentId]=` 3. **Создание папки** — `POST /v1/folders` с параметрами `parentId` и `name`. Можно создавать вложенные структуры, указывая ID родительской папки. 4. **Работа с файлами** — `GET /v1/files` (список), `GET /v1/files/:id` (информация), `PATCH /v1/files/:id` (переименование), `DELETE /v1/files/:id` (удаление). 5. **Пакетные запросы** — `POST /v1/batch` принимает entity-формат: `{ entity: "storages", action: "list" }`. До 50 вызовов за один запрос, одна единица rate-limit. ## Ограничения | Операция | Статус | Комментарий | |----------|--------|-------------| | Загрузка файла (`disk.folder.uploadfile`) | Недоступна | Метод требует multipart-загрузку, entity-обёртки нет | | `disk.storage.getchildren` | Недоступна | Используйте обходной путь через `rootObjectId` + `GET /v1/folders` | | Создание файла (`POST /v1/files`) | Недоступна | Файлы создаются только через загрузку | | Создание/изменение хранилища | Недоступна | Хранилища доступны только для чтения | ## Что можно улучшить - Добавить рекурсивный обход вложенных папок для полной структуры диска - Автоматически создавать структуру папок по шаблону (например, для каждого клиента) - Комбинировать с CRM: при создании сделки автоматически создавать папку и добавлять комментарий в таймлайн с ссылкой на неё --- # Recipe: Erp Sync # Синхронизация с 1С/ERP 🔄 **Сложность:** advanced | **Скоупы:** crm | **Стек:** Node.js, node-cron ## Что делаем Реализуем двустороннюю синхронизацию контактов между Bitrix24 CRM и внешней ERP-системой (1С или аналог). Скрипт сравнивает данные по ключевому полю (ИНН или email), создаёт недостающие записи в обоих системах и обновляет изменённые поля. Синхронизация запускается по расписанию и использует Entity API для оптимальной работы. Это обеспечивает единую базу клиентов без ручного ввода. ## Необходимо - API-ключ Вайбкод с правами `crm` - Node.js 18+ - Пакет: `node-cron` - Доступ к API внешней ERP-системы (в примере используется mock-заглушка) ## Полный код ```javascript // erp-sync.js // Двусторонняя синхронизация контактов Bitrix24 <-> 1С/ERP import cron from 'node-cron'; const API_KEY = process.env.VIBE_API_KEY; const BASE_URL = process.env.VIBE_BASE_URL; const HEADERS = { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json', }; // ============================================================ // Mock: имитация данных из 1С/ERP // В реальном проекте замените на запросы к API вашей ERP-системы // ============================================================ function fetchErpContacts() { return [ { id: 'erp-001', name: 'Иван', lastName: 'Петров', email: 'petrov@example.com', phone: '+79001234567', inn: '7701234567', company: 'ООО Ромашка', updatedAt: new Date('2026-03-15'), }, { id: 'erp-002', name: 'Мария', lastName: 'Сидорова', email: 'sidorova@example.com', phone: '+79009876543', inn: '7709876543', company: 'ИП Сидорова', updatedAt: new Date('2026-03-16'), }, { id: 'erp-003', name: 'Алексей', lastName: 'Козлов', email: 'kozlov@example.com', phone: '+79005551234', inn: '7705551234', company: 'АО Берёзка', updatedAt: new Date('2026-03-17'), }, ]; } function createErpContact(contact) { console.log(` [1С] Создан контакт: ${contact.name} ${contact.lastName}`); return { id: `erp-${Date.now()}` }; } function updateErpContact(erpId, fields) { console.log(` [1С] Обновлён контакт ${erpId}: ${JSON.stringify(fields)}`); } // ============================================================ // Загружаем все контакты из Bitrix24 через Entity API async function fetchBitrixContacts() { const allContacts = []; let offset = 0; const limit = 200; while (true) { const response = await fetch( `${BASE_URL}/v1/contacts?limit=${limit}&offset=${offset}&select=id,name,lastName,email,phone,ufCrmInn,companyTitle,updatedAt`, { headers: { 'X-Api-Key': API_KEY } } ); const { data } = await response.json(); allContacts.push(...(data || [])); if (!data || data.length < limit) break; offset += limit; } return allContacts; } // Сопоставляем контакты по ИНН (основной ключ) или email (запасной) function matchContacts(bitrixContacts, erpContacts) { const matched = []; // совпавшие пары const onlyInBitrix = []; // есть только в Bitrix24 const onlyInErp = []; // есть только в 1С const bitrixByInn = new Map(); const bitrixByEmail = new Map(); for (const bc of bitrixContacts) { const inn = bc.ufCrmInn; const email = bc.email?.[0]?.VALUE; if (inn) bitrixByInn.set(inn, bc); if (email) bitrixByEmail.set(email.toLowerCase(), bc); } const matchedBitrixIds = new Set(); for (const erp of erpContacts) { const bitrixMatch = bitrixByInn.get(erp.inn) || bitrixByEmail.get(erp.email?.toLowerCase()); if (bitrixMatch) { matched.push({ bitrix: bitrixMatch, erp }); matchedBitrixIds.add(bitrixMatch.id); } else { onlyInErp.push(erp); } } for (const bc of bitrixContacts) { if (!matchedBitrixIds.has(bc.id)) { onlyInBitrix.push(bc); } } return { matched, onlyInBitrix, onlyInErp }; } // Создаём контакт в Bitrix24 через Entity API async function createBitrixContact(erpContact) { const response = await fetch(`${BASE_URL}/v1/contacts`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ name: erpContact.name, lastName: erpContact.lastName, email: [{ VALUE: erpContact.email, VALUE_TYPE: 'WORK' }], phone: [{ VALUE: erpContact.phone, VALUE_TYPE: 'WORK' }], ufCrmInn: erpContact.inn, companyTitle: erpContact.company, sourceId: 'OTHER', sourceDescription: 'Импорт из 1С/ERP', }), }); const { data } = await response.json(); console.log(` [B24] Создан контакт: ${erpContact.name} ${erpContact.lastName} → ID: ${data.id}`); return data; } // Обновляем изменённые поля через Entity API async function syncMatchedContact(bitrix, erp) { const updates = {}; let hasChanges = false; if (bitrix.name !== erp.name) { updates.name = erp.name; hasChanges = true; } if (bitrix.lastName !== erp.lastName) { updates.lastName = erp.lastName; hasChanges = true; } if (hasChanges) { await fetch(`${BASE_URL}/v1/contacts/${bitrix.id}`, { method: 'PATCH', headers: HEADERS, body: JSON.stringify(updates), }); console.log(` [B24] Обновлён контакт #${bitrix.id}: ${JSON.stringify(updates)}`); } return hasChanges; } // Основная функция синхронизации async function synchronize() { const startTime = Date.now(); console.log(`\n${'='.repeat(60)}`); console.log(`🔄 Синхронизация: ${new Date().toLocaleString('ru-RU')}`); console.log('='.repeat(60)); // Загружаем данные из обоих источников console.log('\n📥 Загрузка данных...'); const [bitrixContacts, erpContacts] = await Promise.all([ fetchBitrixContacts(), Promise.resolve(fetchErpContacts()), ]); console.log(` Bitrix24: ${bitrixContacts.length} контактов`); console.log(` 1С/ERP: ${erpContacts.length} контактов`); // Сопоставляем console.log('\n🔍 Сопоставление...'); const { matched, onlyInBitrix, onlyInErp } = matchContacts(bitrixContacts, erpContacts); console.log(` Совпадений: ${matched.length}`); console.log(` Только в B24: ${onlyInBitrix.length}`); console.log(` Только в 1С: ${onlyInErp.length}`); let created = 0; let updated = 0; // Создаём недостающие контакты в Bitrix24 if (onlyInErp.length > 0) { console.log('\n➕ Создание в Bitrix24...'); for (const erp of onlyInErp) { await createBitrixContact(erp); created++; } } // Создаём недостающие контакты в 1С if (onlyInBitrix.length > 0) { console.log('\n➕ Создание в 1С/ERP...'); for (const bc of onlyInBitrix) { createErpContact(bc); created++; } } // Обновляем совпавшие записи if (matched.length > 0) { console.log('\n🔄 Обновление совпавших...'); for (const { bitrix, erp } of matched) { const changed = await syncMatchedContact(bitrix, erp); if (changed) updated++; } } // Итоги const duration = ((Date.now() - startTime) / 1000).toFixed(1); console.log(`\n${'─'.repeat(60)}`); console.log(`📊 Итоги: создано ${created}, обновлено ${updated}, время ${duration}с`); console.log('─'.repeat(60)); } // Запуск по расписанию: каждый час console.log('🔄 Сервис синхронизации с 1С/ERP запущен'); console.log(' Расписание: каждый час'); // Первый запуск сразу synchronize().catch(console.error); // Далее по крону cron.schedule('0 * * * *', () => { synchronize().catch(console.error); }); ``` ## Как это работает 1. Сервис параллельно загружает контакты из Bitrix24 через Entity API (`GET /v1/contacts` с авто-пагинацией через limit/offset) и из внешней ERP-системы. 2. Контакты сопоставляются по ИНН как основному ключу и по email как запасному. В результате формируются три группы: совпавшие, только в Bitrix24, только в ERP. 3. Контакты, которые есть только в ERP, создаются в Bitrix24 через Entity API (`POST /v1/contacts`) с пометкой об источнике. 4. Контакты, которые есть только в Bitrix24, создаются во внешней системе (в примере — mock-функция). 5. Для совпавших записей сравниваются поля, и при расхождении обновляется Bitrix24 через Entity API (`PATCH /v1/contacts/:id`). 6. Синхронизация запускается каждый час через node-cron и при старте сервиса. ## Что можно улучшить - Заменить mock-функции ERP на реальные запросы к API 1С (например, через OData) - Добавить журнал синхронизации в базу данных для отслеживания истории изменений - Реализовать conflict resolution: кто главнее при расхождении — Bitrix24 или ERP - Использовать `POST /v1/contacts/batch` для создания/обновления контактов пачками по 500 штук --- # Recipe: Mass Messaging # Массовая рассылка контактам 📨 **Сложность:** medium | **Скоупы:** crm, im | **Стек:** Node.js ## Что делаем Создаём скрипт для персонализированной рассылки уведомлений контактам из CRM. Скрипт выбирает контакты по фильтру (например, по типу или источнику), формирует персональное сообщение с подстановкой имени и отправляет уведомление через систему сообщений Bitrix24. Это удобно для информирования клиентов о акциях, изменениях или важных событиях. ## Необходимо - API-ключ Вайбкод с правами `crm, im` - Node.js 18+ ## Полный код ```javascript // mass-messaging.js // Персонализированная рассылка уведомлений контактам CRM const API_KEY = process.env.VIBE_API_KEY; const BASE_URL = process.env.VIBE_BASE_URL; const HEADERS = { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json', }; // Шаблон сообщения с плейсхолдерами const MESSAGE_TEMPLATE = `Здравствуйте, {{NAME}}! Рады сообщить, что мы обновили условия сотрудничества. Новые тарифы действуют с 1 числа следующего месяца. Подробности можно узнать у вашего менеджера или на сайте. С уважением, команда продаж`; // Настройки рассылки const CONFIG = { // Фильтр контактов filter: { typeId: 'CLIENT', // тип: клиент // sourceId: 'WEB', // источник: сайт (раскомментируйте при необходимости) }, // Задержка между сообщениями (мс) — чтобы не перегружать API delayBetweenMessages: 1000, // ID отправителя (пользователь Bitrix24) senderId: 1, // Максимум контактов за один запуск maxContacts: 100, }; // Загружаем контакты через Entity API async function fetchContacts() { const response = await fetch(`${BASE_URL}/v1/contacts/search`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ filter: CONFIG.filter, select: ['id', 'name', 'lastName', 'assignedById'], sort: { id: 'asc' }, limit: CONFIG.maxContacts, }), }); const { data } = await response.json(); return data || []; } // Подставляем данные контакта в шаблон function personalizeMessage(template, contact) { const fullName = [contact.name, contact.lastName].filter(Boolean).join(' ') || 'уважаемый клиент'; return template.replace(/\{\{NAME\}\}/g, fullName); } // Отправляем системное уведомление через Entity API (POST /v1/notifications) async function sendNotification(contact, message) { const response = await fetch(`${BASE_URL}/v1/notifications`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ userId: contact.assignedById || CONFIG.senderId, message: `[Рассылка] Контакт: ${contact.name} ${contact.lastName}\n\n${message}`, type: 'system', }), }); const result = await response.json(); if (!result.success) { throw new Error(result.error?.message || 'Failed to send notification'); } } // Задержка function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } // Основная функция рассылки async function runMailing() { console.log('📨 Запуск рассылки'); console.log(` Фильтр: ${JSON.stringify(CONFIG.filter)}`); console.log(` Макс. контактов: ${CONFIG.maxContacts}\n`); // Загружаем контакты console.log('👥 Загружаем контакты...'); const contacts = await fetchContacts(); console.log(` Найдено: ${contacts.length} контактов\n`); if (contacts.length === 0) { console.log('Контакты не найдены. Проверьте фильтр.'); return; } // Статистика let sent = 0; let failed = 0; const errors = []; // Отправляем сообщения for (const contact of contacts) { const fullName = `${contact.name || ''} ${contact.lastName || ''}`.trim(); try { const message = personalizeMessage(MESSAGE_TEMPLATE, contact); await sendNotification(contact, message); sent++; console.log(` ✉️ [${sent}/${contacts.length}] ${fullName} — отправлено`); } catch (error) { failed++; errors.push({ contact: fullName, error: error.message }); console.log(` ❌ [${sent + failed}/${contacts.length}] ${fullName} — ошибка: ${error.message}`); } // Пауза между отправками await delay(CONFIG.delayBetweenMessages); } // Итоги console.log('\n' + '='.repeat(50)); console.log('📊 Итоги рассылки:'); console.log(` Отправлено: ${sent}`); console.log(` Ошибок: ${failed}`); console.log(` Всего: ${contacts.length}`); if (errors.length > 0) { console.log('\n❌ Ошибки:'); errors.forEach((e) => console.log(` - ${e.contact}: ${e.error}`)); } console.log('='.repeat(50)); } runMailing().catch(console.error); ``` ## Как это работает 1. Скрипт загружает список контактов из CRM через Entity API (`POST /v1/contacts/search`) с заданным фильтром (тип контакта, источник и др.). 2. Для каждого контакта шаблон сообщения персонализируется — подставляется имя и фамилия. 3. Персональное сообщение отправляется как системное уведомление ответственному менеджеру контакта через `POST /v1/notifications` с параметром `type: "system"`. 4. Между отправками выдерживается пауза, чтобы не превысить лимиты API. 5. По завершении выводится статистика: сколько сообщений отправлено, сколько с ошибками. ## Что можно улучшить - Добавить поддержку HTML-шаблонов с форматированием и ссылками - Реализовать отправку email через Entity API (`POST /v1/activities`) вместо системных уведомлений - Использовать `POST /v1/contacts/search` с пагинацией для обработки тысяч контактов - Сохранять лог рассылки в файл или базу данных для аудита --- # Recipe: Task Automation # Автоматизация задач ✅ **Сложность:** medium | **Скоупы:** task, crm | **Стек:** Node.js ## Что делаем Создаём сервис, который следит за изменением стадий сделок в CRM и автоматически создаёт задачи при переходе сделки на определённый этап. Например, когда сделка переходит в стадию «В работе», создаётся задача для менеджера с описанием и дедлайном. Это устраняет человеческий фактор и стандартизирует бизнес-процессы. ## Необходимо - API-ключ Вайбкод с правами `task, crm` - Node.js 18+ ## Полный код ```javascript // task-automation.js // Автоматическое создание задач при смене стадии сделки const API_KEY = process.env.VIBE_API_KEY; const BASE_URL = process.env.VIBE_BASE_URL; // например https://vibecode.bitrix24.tech const HEADERS = { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json', }; // Конфигурация: какие задачи создавать при переходе на стадию const STAGE_TASKS = { EXECUTING: { title: 'Подготовить документы и начать исполнение', description: 'Сделка перешла в работу. Необходимо подготовить все документы и начать исполнение обязательств.', deadlineDays: 5, priority: 2, // высокий }, PREPAYMENT_INVOICE: { title: 'Выставить счёт и проконтролировать оплату', description: 'Необходимо выставить счёт на предоплату и отследить поступление средств.', deadlineDays: 3, priority: 2, }, FINAL_INVOICE: { title: 'Финальная сверка и закрытие', description: 'Финальный этап сделки. Подготовить закрывающие документы.', deadlineDays: 7, priority: 1, }, }; // Хранилище последних известных стадий сделок const dealStages = new Map(); // Получаем активные сделки через Entity API async function fetchActiveDeals() { const response = await fetch( `${BASE_URL}/v1/deals/search`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ // Фильтруем незакрытые сделки (исключаем WON и LOSE стадии) // Примечание: стадии с множественными воронками имеют C-префикс (C2:WON, C4:LOSE) filter: { '!stageId': 'WON', }, select: ['id', 'title', 'stageId', 'assignedById'], }), } ); const { data } = await response.json(); return data || []; } // Создаём задачу через Entity API async function createTask(deal, taskConfig) { const deadline = new Date(); deadline.setDate(deadline.getDate() + taskConfig.deadlineDays); const response = await fetch(`${BASE_URL}/v1/tasks`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ title: `${taskConfig.title} — ${deal.title}`, description: [ taskConfig.description, '', `Сделка: ${deal.title} (ID: ${deal.id})`, ].join('\n'), responsibleId: deal.assignedById, priority: taskConfig.priority, deadline: deadline.toISOString(), }), }); const { data } = await response.json(); console.log(` 📝 Задача создана: #${data.id} — ${taskConfig.title}`); return data.id; } // Основной цикл: проверка изменений стадий async function checkStageChanges() { const timestamp = new Date().toISOString(); console.log(`\n[${timestamp}] Проверяем изменения стадий...`); const deals = await fetchActiveDeals(); for (const deal of deals) { const dealId = deal.id; const currentStage = deal.stageId; const previousStage = dealStages.get(dealId); // Обновляем известную стадию dealStages.set(dealId, currentStage); // Если стадия изменилась и для новой стадии есть конфигурация задачи if (previousStage && previousStage !== currentStage) { console.log(`\n🔄 Сделка #${dealId} "${deal.title}": ${previousStage} → ${currentStage}`); const taskConfig = STAGE_TASKS[currentStage]; if (taskConfig) { await createTask(deal, taskConfig); } else { console.log(` Для стадии ${currentStage} задача не настроена`); } } } // Очищаем закрытые сделки из хранилища const activeIds = new Set(deals.map((d) => d.id)); for (const [id] of dealStages) { if (!activeIds.has(id)) { dealStages.delete(id); } } } // Запуск с интервалом async function start() { console.log('✅ Сервис автоматизации задач запущен'); console.log(` Отслеживаемые стадии: ${Object.keys(STAGE_TASKS).join(', ')}`); // Первый запуск — заполняем начальное состояние console.log('\nЗагружаем текущее состояние сделок...'); const deals = await fetchActiveDeals(); for (const deal of deals) { dealStages.set(deal.id, deal.stageId); } console.log(`Загружено ${deals.length} активных сделок\n`); // Запускаем проверку каждые 60 секунд setInterval(checkStageChanges, 60_000); } start().catch(console.error); ``` ## Как это работает 1. При запуске сервис загружает все открытые сделки через Entity API (`POST /v1/deals/search`) и запоминает их текущие стадии. 2. Каждые 60 секунд происходит повторный опрос сделок. 3. Если у сделки изменилась стадия, сервис проверяет конфигурацию `STAGE_TASKS` — определены ли задачи для новой стадии. 4. При совпадении создаётся задача через Entity API (`POST /v1/tasks`) с заголовком, описанием и дедлайном. 5. Закрытые сделки автоматически удаляются из отслеживания для экономии памяти. > **Примечание:** Чек-листы задач пока создаются через интерфейс Битрикс24 или прямой REST API. Метод `task.checklistitem.add` не имеет entity-обёртки в Вайбкод. ## Что можно улучшить - Использовать webhooks вместо polling для мгновенной реакции на изменения - Добавить конфигурацию через YAML/JSON файл, чтобы менеджеры могли настраивать правила без кода - Реализовать дедупликацию: не создавать задачу, если аналогичная уже существует для этой сделки - Добавить логирование в файл и уведомления об ошибках в Telegram/Slack --- # Recipe: Telegram Bot # Telegram-бот для CRM 🤖 **Сложность:** medium | **Скоупы:** crm | **Стек:** Node.js, grammy ## Что делаем Создаём Telegram-бота, который периодически опрашивает CRM через Вайбкод Entity API и уведомляет менеджера о новых сделках. Бот отправляет форматированное сообщение с названием сделки, суммой и контактом. Это позволяет моментально реагировать на входящие лиды, не заходя в Bitrix24. ## Необходимо - API-ключ Вайбкод с правами `crm` - Telegram Bot Token (получить у @BotFather) - Node.js 18+ - Пакеты: `grammy`, `node-cron` ## Полный код ```javascript // telegram-crm-bot.js // Telegram-бот для уведомлений о новых сделках из Bitrix24 import { Bot } from 'grammy'; import cron from 'node-cron'; // Конфигурация из переменных окружения const API_KEY = process.env.VIBE_API_KEY; const BASE_URL = process.env.VIBE_BASE_URL; // например https://vibecode.bitrix24.tech const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN; const CHAT_ID = process.env.TELEGRAM_CHAT_ID; // ID чата менеджера const bot = new Bot(BOT_TOKEN); const HEADERS = { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json', }; // Храним ID последней обработанной сделки let lastSeenDealId = 0; // Запрос новых сделок через Entity API async function fetchNewDeals() { try { const response = await fetch( `${BASE_URL}/v1/deals/search`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ filter: { id: { $gt: lastSeenDealId }, // Примечание: на порталах с несколькими воронками стадия может быть // C2:NEW, C4:NEW и т.д. Используйте $contains или фильтрацию на клиенте. stageId: 'NEW', }, sort: 'id', select: ['id', 'title', 'amount', 'currency', 'contactId', 'createdAt'], }), } ); const { data } = await response.json(); return data || []; } catch (error) { console.error('Ошибка при получении сделок:', error.message); return []; } } // Получаем имя контакта по ID async function fetchContactName(contactId) { if (!contactId) return 'Не указан'; try { const response = await fetch(`${BASE_URL}/v1/contacts/${contactId}`, { headers: { 'X-Api-Key': API_KEY }, }); const { data } = await response.json(); return `${data.name || ''} ${data.lastName || ''}`.trim(); } catch { return 'Не удалось загрузить'; } } // Форматируем сообщение для Telegram function formatDealMessage(deal, contactName) { return [ `🆕 Новая сделка`, ``, `📋 Название: ${deal.title}`, `💰 Сумма: ${deal.amount || '0'} ${deal.currency || 'RUB'}`, `👤 Контакт: ${contactName}`, `📅 Создана: ${new Date(deal.createdAt).toLocaleString('ru-RU')}`, `🔗 ID: ${deal.id}`, ].join('\n'); } // Проверяем новые сделки и отправляем уведомления async function checkAndNotify() { console.log(`[${new Date().toISOString()}] Проверяем новые сделки...`); const deals = await fetchNewDeals(); for (const deal of deals) { const contactName = await fetchContactName(deal.contactId); const message = formatDealMessage(deal, contactName); await bot.api.sendMessage(CHAT_ID, message, { parse_mode: 'HTML' }); console.log(`Уведомление отправлено: сделка #${deal.id}`); // Обновляем последний обработанный ID lastSeenDealId = Math.max(lastSeenDealId, deal.id); } if (deals.length === 0) { console.log('Новых сделок нет'); } } // Команды бота bot.command('start', (ctx) => { ctx.reply('👋 Бот CRM-уведомлений запущен! Вы будете получать сообщения о новых сделках.'); }); bot.command('status', (ctx) => { ctx.reply(`📊 Последний обработанный ID сделки: ${lastSeenDealId}`); }); // Запускаем опрос каждые 2 минуты cron.schedule('*/2 * * * *', checkAndNotify); // Запускаем бота bot.start(); console.log('🤖 Telegram CRM-бот запущен'); ``` ## Как это работает 1. Бот запускается и подключается к Telegram API через библиотеку grammy. 2. Каждые 2 минуты cron-задача вызывает функцию `checkAndNotify`, которая запрашивает новые сделки через Entity API (`POST /v1/deals/search`) с фильтром по ID больше последнего обработанного. 3. Для каждой новой сделки бот загружает имя контакта через `GET /v1/contacts/:id`. 4. Полученные данные форматируются в HTML-сообщение и отправляются в указанный Telegram-чат. 5. ID последней обработанной сделки сохраняется в памяти, чтобы не отправлять дубликаты при следующем опросе. ## Что можно улучшить - Сохранять `lastSeenDealId` в файл или Redis, чтобы не терять прогресс при перезапуске - Добавить инлайн-кнопки для быстрых действий прямо из Telegram (взять в работу, назначить ответственного) - Поддержать несколько менеджеров: маршрутизировать уведомления по ответственному в сделке - Добавить фильтры по сумме или типу сделки через команды бота --- # Recipe: Web Search With Llm # Веб-поиск + LLM (RAG) Связка [`POST /v1/search`](/docs/search/run) с [`POST /v1/ai/chat/completions`](/docs/ai/chat) для ответов LLM, опирающихся на свежие источники из интернета. ## Сценарий 1. AI-агент получает вопрос от пользователя. 2. Делает веб-поиск через `/v1/search` — получает массив `results` со ссылками на релевантные страницы. 3. Передаёт LLM системный промпт с инструкцией цитировать источники по `[N]` и блок `Sources:` со списком `id`, `title`, `url`, `content`. 4. LLM формирует ответ с маркерами `[N]`, которые соответствуют `results[].id`. ## Полный пример ```javascript const VIBE_KEY = process.env.VIBE_API_KEY const BASE = 'https://vibecode.bitrix24.tech' // ── 1. Веб-поиск ──────────────────────────────────────────── const searchRes = await fetch(`${BASE}/v1/search`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ query: 'обновления Битрикс24 за последний месяц', search_depth: 'advanced', max_results: 5, lang: 'ru', }), }) const search = await searchRes.json() // ── 2. Собираем блок источников для LLM ───────────────────── const sourcesBlock = search.results .map((r) => `[${r.id}] ${r.title}\n${r.url}\n${r.content}`) .join('\n\n') // ── 3. Запрос к LLM с инструкцией цитировать ──────────────── const chatRes = await fetch(`${BASE}/v1/ai/chat/completions`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'bitrix/bitrixgpt-5.5', messages: [ { role: 'system', content: 'Отвечай только на основе источников ниже. Каждый факт сопровождай маркером [N], где N — id источника.', }, { role: 'user', content: `Вопрос: ${search.query}\n\nИсточники:\n${sourcesBlock}`, }, ], }), }) const chat = await chatRes.json() console.log(chat.choices[0].message.content) ``` ## Стоимость одного цикла - **Поиск:** 5 Ꝟ для `bitrix-search` в режиме `advanced`. Для BYOK Tavily / Brave — 0 Ꝟ. - **LLM:** зависит от модели и количества токенов. Прайс — в [AI Router](/docs/ai). ## Какой провайдер выбрать - **Русскоязычные источники** → `provider: "bitrix-search"` (используется по умолчанию). Выдача уже содержит синтезированный `answer` с маркерами `[N]` — иногда LLM-шаг можно пропустить. - **Англоязычные источники с фильтрами по доменам или времени** → `provider: "tavily"` (BYOK). Нужен токен Tavily — добавляется через [`POST /v1/search/credentials`](/docs/search/credentials/create). - **Англоязычный поиск без синтеза, для RAG поверх своей LLM** → `provider: "brave"` (BYOK). Подробнее о различиях — [Web Search для AI](/docs/search#когда-какой-провайдер-выбрать). ## Потоковый вариант Когда интерфейс показывает прогресс (chat-приложение, ассистент), используйте `stream: true` — события приходят по мере готовности. ```javascript const streamRes = await fetch(`${BASE}/v1/search`, { method: 'POST', headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application/json', Accept: 'text/event-stream', }, body: JSON.stringify({ query: 'обновления Битрикс24 за последний месяц', search_depth: 'advanced', stream: true, }), }) const reader = streamRes.body.getReader() const decoder = new TextDecoder() let buffer = '' while (true) { const { value, done } = await reader.read() if (done) break buffer += decoder.decode(value, { stream: true }) let idx while ((idx = buffer.indexOf('\n\n')) !== -1) { const block = buffer.slice(0, idx) buffer = buffer.slice(idx + 2) const eventLine = block.match(/^event: (.+)$/m) const dataLine = block.match(/^data: (.+)$/m) if (!eventLine || !dataLine) continue const event = eventLine[1] const payload = JSON.parse(dataLine[1]) if (event === 'thinking') process.stdout.write('.') if (event === 'answer_delta') process.stdout.write(payload.content) if (event === 'done') console.log('\nГотово') } } ``` Полный список SSE-событий и полей — [`POST /v1/search`](/docs/search/run#потоковая-передача-sse). ## Смотрите также - [Web Search для AI](/docs/search) — обзор раздела, тарификация, миграция с Tavily - [Поиск (POST /v1/search)](/docs/search/run) — параметры запроса, формат потоковой передачи - [Свои ключи (BYOK)](/docs/search/credentials) — добавление BYOK-ключей Tavily и Brave - [AI Router](/docs/ai) — единый интерфейс к чат-моделям - [Лимиты и оптимизация](/docs/optimization) — общие правила частоты запросов --- # Recipe: Webhook Handler # Webhook-обработчик событий 🕐 **Сложность:** medium | **Скоупы:** crm | **Стек:** Node.js, Express ## Что делаем Создаём Express-сервер, который принимает webhook-события от Bitrix24, валидирует их, логирует и выполняет действия в зависимости от типа события. Например, при создании новой сделки сервер автоматически запрашивает её детали через Entity API и записывает в лог. Это основа для построения event-driven интеграций, которые реагируют на изменения в реальном времени. > **Приложение на Black Hole-сервере?** Тогда публичный URL и ngrok не нужны — есть управляемый путь доставки событий через туннель. Платформа сама регистрирует обработчик в Битрикс24 и доставляет события в приложение с повторами и пробуждением спящего сервера. Подробнее: [Подписки на события портала](/docs/infra/event-subscriptions). Рецепт ниже — для приложений вне Black Hole, у которых есть собственный публичный адрес. ## Необходимо - API-ключ Вайбкод с правами `crm` - Node.js 18+ - Пакеты: `express` - Публичный URL для приёма webhooks (ngrok для разработки) ## Полный код ```javascript // webhook-handler.js // Express-сервер для обработки webhook-событий Bitrix24 import express from 'express'; const API_KEY = process.env.VIBE_API_KEY; const BASE_URL = process.env.VIBE_BASE_URL; const PORT = process.env.PORT || 3001; const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Получаем сделку через Entity API async function getDeal(dealId) { const response = await fetch(`${BASE_URL}/v1/deals/${dealId}`, { headers: { 'X-Api-Key': API_KEY }, }); const { data } = await response.json(); return data; } // ────────────────────────────────────────── // Обработчики событий // ────────────────────────────────────────── // Обработка создания новой сделки async function handleDealAdd(eventData) { const dealId = eventData.data?.FIELDS?.ID; if (!dealId) { console.log(' ⚠️ ID сделки отсутствует в данных события'); return; } console.log(` 📋 Загружаем данные сделки #${dealId}...`); try { const deal = await getDeal(dealId); console.log(` Название: ${deal.title}`); console.log(` Сумма: ${deal.amount} ${deal.currency}`); console.log(` Стадия: ${deal.stageId}`); console.log(` Ответственный: ID ${deal.assignedById}`); // Здесь можно добавить дополнительную логику: // - отправить уведомление в Slack/Telegram // - создать задачу для менеджера // - обновить внешнюю систему } catch (error) { console.error(` ❌ Ошибка при загрузке сделки: ${error.message}`); } } // Обработка обновления сделки async function handleDealUpdate(eventData) { const dealId = eventData.data?.FIELDS?.ID; if (!dealId) return; console.log(` 📋 Сделка #${dealId} обновлена`); try { const deal = await getDeal(dealId); console.log(` Текущая стадия: ${deal.stageId}`); console.log(` Сумма: ${deal.amount}`); } catch (error) { console.error(` ❌ Ошибка: ${error.message}`); } } // Обработка удаления сделки function handleDealDelete(eventData) { const dealId = eventData.data?.FIELDS?.ID; console.log(` 🗑️ Сделка #${dealId} удалена`); } // Карта обработчиков по типу события const EVENT_HANDLERS = { ONCRMDEALADD: handleDealAdd, ONCRMDEALUPDATE: handleDealUpdate, ONCRMDEALDELETE: handleDealDelete, }; // ────────────────────────────────────────── // HTTP-эндпоинты // ────────────────────────────────────────── // Основной эндпоинт для приёма webhook-событий app.post('/webhook', async (req, res) => { const timestamp = new Date().toLocaleString('ru-RU'); const eventData = req.body; const eventName = eventData.event || 'UNKNOWN'; console.log(`\n[${timestamp}] 📥 Получено событие: ${eventName}`); console.log(` Данные: ${JSON.stringify(eventData.data?.FIELDS || {})}`); // Ищем обработчик для данного события const handler = EVENT_HANDLERS[eventName]; if (handler) { try { await handler(eventData); } catch (error) { console.error(` ❌ Ошибка обработки: ${error.message}`); } } else { console.log(` ℹ️ Обработчик для события ${eventName} не зарегистрирован`); } // Bitrix24 ожидает ответ 200, иначе будет повторять запрос res.status(200).json({ status: 'ok' }); }); // Проверка работоспособности app.get('/health', (req, res) => { res.json({ status: 'running', uptime: process.uptime(), events: Object.keys(EVENT_HANDLERS), }); }); // ────────────────────────────────────────── // Запуск // ────────────────────────────────────────── app.listen(PORT, () => { console.log('🕐 Webhook-сервер запущен'); console.log(` Порт: ${PORT}`); console.log(` Endpoint: POST /webhook`); console.log(` Health: GET /health\n`); console.log('💡 Для разработки используйте ngrok:'); console.log(' npx ngrok http 3001'); }); ``` ## Как это работает 1. Express-сервер запускается и слушает POST-запросы на эндпоинте `/webhook`. 2. Bitrix24 отправляет HTTP POST с данными события (тип события, ID сущности и др.) при каждом изменении в CRM. 3. Сервер определяет тип события (создание, обновление, удаление сделки) и находит соответствующий обработчик. 4. Обработчик запрашивает актуальные данные сделки через Entity API (`GET /v1/deals/:id`) для получения полной информации. 5. Сервер всегда отвечает статусом 200 — иначе Bitrix24 будет повторять отправку события. > **Примечание:** Регистрация обработчиков событий (`event.bind`, `event.get`) выполняется через настройки портала Битрикс24 или прямой REST API. Эти методы не имеют entity-обёртки в Вайбкод, и являются разовыми инфраструктурными операциями. Для приложения на Black Hole-сервере регистрация управляемая — см. [Подписки на события портала](/docs/infra/event-subscriptions). ## Что можно улучшить - Добавить очередь событий (Redis/BullMQ) для надёжной обработки при большой нагрузке - Реализовать верификацию подписи запроса для защиты от поддельных вызовов - Добавить обработчики для других сущностей: контакты, компании, задачи, лиды - Сохранять историю полученных событий в базу данных для отладки и аналитики