[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-bots":3,"docs-tabs-bots":6},{"content":4,"lastmod":5},"\n# Бот-платформа\n\nСоздавайте чат-ботов Битрикс24: регистрируйте бота, получайте сообщения и команды пользователей, отвечайте текстом, кнопками и вложениями, управляйте групповыми чатами и участниками. Не нужны вебхуки и публичный сервер — бот опрашивает события и отвечает обычными HTTP-запросами.\n\n**Скоуп:** `imbot` | **Базовый URL:** `https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1` | **Авторизация:** `X-Api-Key`\n\n[Какой ключ выбрать](#какой-ключ-выбрать) | [Владение ботом](#владение-ботом) | [Быстрый старт](#быстрый-старт) | [Echo-бот (пример)](#полный-пример-echo-бот) | [Диагностика проблем](\u002Fdocs\u002Fbots\u002Ftroubleshooting) | [Коды ошибок](#коды-ошибок) | [Справочник эндпоинтов](#справочник-эндпоинтов)\n\n## Разделы документации\n\n- [Управление ботами](\u002Fdocs\u002Fbots\u002Fmanagement) — регистрация, обновление, удаление\n- [События](\u002Fdocs\u002Fbots\u002Fevents) — опрос входящих сообщений и команд\n- [Сообщения](\u002Fdocs\u002Fbots\u002Fmessages) — отправка, редактирование, удаление, форматирование\n- [Чаты](\u002Fdocs\u002Fbots\u002Fchats) — создание чатов, управление участниками и менеджерами\n- [Команды](\u002Fdocs\u002Fbots\u002Fcommands) — slash-команды бота\n- [Интерфейс](\u002Fdocs\u002Fbots\u002Fui) — реакции, индикатор набора, поле ввода\n- [Файлы](\u002Fdocs\u002Fbots\u002Ffiles) — загрузка и скачивание\n- [Диагностика проблем](\u002Fdocs\u002Fbots\u002Ftroubleshooting) — что делать, если бот не получает события или возвращает ошибки\n\n## Оформление сообщений\n\nСправочники по оформлению текста при отправке и редактировании сообщений:\n\n- [Форматирование текста (BB-коды)](\u002Fdocs\u002Fbots\u002Fmessages\u002Fformatting)\n- [Клавиатура](\u002Fdocs\u002Fbots\u002Fmessages\u002Fkeyboard)\n- [Вложения (ATTACH-блоки)](\u002Fdocs\u002Fbots\u002Fmessages\u002Fattach)\n\n---\n\n## Какой ключ выбрать\n\nБот-платформа работает с двумя типами ключей. Выбор определяется тем, от чьего имени бот будет обращаться к Битрикс24.\n\n| Сценарий | Ключ | Заголовки запроса |\n|---------|------|-------------------|\n| Бот для своего портала: собственный сервер, фоновый процесс, личный скрипт | Личный API-ключ `vibe_api_…` | `X-Api-Key: vibe_api_…` |\n| Бот внутри OAuth-приложения, опубликованного в каталоге Вайбкод и установленного на портал | Ключ авторизации `vibe_app_…` | `X-Api-Key: vibe_app_…` + `Authorization: Bearer \u003Csession_token>` |\n\n**Личный ключ `vibe_api_…`.** Создаётся в личном кабинете Вайбкод и привязан к одному порталу Битрикс24. Все запросы идут от лица владельца ключа, дополнительный токен сессии не требуется. Подходит для одноразовых ботов, которые не публикуются как приложение.\n\n**Ключ авторизации `vibe_app_…`.** Привязан к OAuth-приложению из каталога. Каждый запрос отправляется от лица того пользователя, который установил приложение на свой портал и прошёл OAuth-авторизацию — поэтому обязателен заголовок `Authorization: Bearer \u003Csession_token>`. Без Bearer бот-эндпоинты вернут `401 TOKEN_MISSING`. Подходит для ботов, которые работают от лица разных пользователей того портала, где приложение зарегистрировано.\n\nПодробное описание типов ключей, форматов и получения `session_token` — [Ключи и авторизация](\u002Fdocs\u002Fkeys-auth).\n\n---\n\n## Владение ботом\n\nБот привязан к тому API-ключу, которым зарегистрирован. Все операции с ботом — получение событий, отправка сообщений, обновление — выполняются тем же ключом. Запрос с другого ключа возвращает `403 BOT_ACCESS_DENIED`.\n\nЭто важно при деплое: если приложение развёрнуто с одним ключом, а бот создан другим, обращения к бот-эндпоинтам этим ключом не пройдут. Регистрируйте бота и работайте с ним одним и тем же ключом.\n\nПередать бота на другой ключ можно через [`POST \u002Fv1\u002Fbots\u002F:botId\u002Ftransfer`](\u002Fdocs\u002Fbots\u002Fmanagement\u002Ftransfer) — например, когда исходный ключ отозван после пересоздания приложения. Целевой ключ должен быть активен и принадлежать тому же пользователю, либо перенос выполняет администратор аккаунта. Меняется только привязка ключа, `botId` и история чатов сохраняются.\n\n---\n\n## Быстрый старт\n\n### 1. Зарегистрируйте бота\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fbots \\\n  -H \"X-Api-Key: $VIBE_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"code\": \"my_helper_bot\",\n    \"name\": \"Помощник\",\n    \"type\": \"bot\",\n    \"eventMode\": \"fetch\"\n  }'\n```\n\nОтвет:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"bot\": {\n      \"id\": 42,\n      \"code\": \"my_helper_bot\",\n      \"name\": \"Помощник\",\n      \"type\": \"bot\",\n      \"eventMode\": \"fetch\"\n    }\n  }\n}\n```\n\n> ID бота берите из `data.bot.id` — `botToken` платформа хранит сама и в ответ не возвращает.\n\n### 2. Получайте события (длинный опрос)\n\n```bash\ncurl -H \"X-Api-Key: $VIBE_KEY\" \\\n  \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fbots\u002F42\u002Fevents\"\n```\n\nОтвет содержит `nextOffset` — передайте его как `offset` в следующем запросе:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"events\": [\n      {\n        \"eventId\": 35,\n        \"type\": \"ONIMBOTV2MESSAGEADD\",\n        \"date\": \"2026-04-13T10:05:00+03:00\",\n        \"data\": {\n          \"dialogId\": \"12\",\n          \"bot\": { \"id\": 42, \"code\": \"my_helper_bot\", \"type\": \"bot\" },\n          \"message\": {\n            \"id\": 1501,\n            \"chatId\": 87,\n            \"authorId\": 1,\n            \"date\": \"2026-04-13T10:05:00+03:00\",\n            \"text\": \"Привет, бот!\"\n          },\n          \"chat\": { \"id\": 87, \"dialogId\": \"12\", \"type\": \"private\" },\n          \"user\": { \"id\": 1, \"name\": \"Иван Петров\", \"firstName\": \"Иван\", \"lastName\": \"Петров\" }\n        }\n      }\n    ],\n    \"nextOffset\": 36,\n    \"hasMore\": false,\n    \"storedOffset\": 35,\n    \"persisted\": true\n  }\n}\n```\n\nСледующий запрос:\n\n```bash\ncurl -H \"X-Api-Key: $VIBE_KEY\" \\\n  \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fbots\u002F42\u002Fevents?offset=42\"\n```\n\n### 3. Отправьте ответ\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fbots\u002F42\u002Fmessages \\\n  -H \"X-Api-Key: $VIBE_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"dialogId\": \"12\",\n    \"fields\": { \"message\": \"Привет! Чем могу помочь?\" }\n  }'\n```\n\nОтвет:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1502,\n    \"uuidMap\": []\n  }\n}\n```\n\n---\n\n## Полный пример: Echo-бот\n\n```javascript\nconst VIBE_KEY = process.env.VIBE_KEY\nconst BASE = 'https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1'\n\n\u002F\u002F ── 1. Регистрация бота ─────────────────────────────────────────\nconst regRes = await fetch(`${BASE}\u002Fbots`, {\n  method: 'POST',\n  headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n  body: JSON.stringify({\n    code: 'echo_bot',\n    name: 'Echo Bot',\n    type: 'bot',\n    color: 'AQUA',\n    eventMode: 'fetch',\n    workPosition: 'Повторяет ваши сообщения'\n  })\n})\nconst { data } = await regRes.json()\nconst BOT_ID = data.bot.id\n\nconsole.log(`Bot registered with ID: ${BOT_ID}`)\n\n\u002F\u002F ── 2. Регистрация slash-команд ─────────────────────────────────\nawait fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fcommands`, {\n  method: 'POST',\n  headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n  body: JSON.stringify({\n    command: 'ping',\n    title: 'Ping',\n    description: 'Проверить, жив ли бот'\n  })\n})\n\nawait fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fcommands`, {\n  method: 'POST',\n  headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n  body: JSON.stringify({\n    command: 'help',\n    title: 'Помощь',\n    description: 'Показать список команд'\n  })\n})\n\n\u002F\u002F ── 3. Цикл опроса событий (polling) ───────────────────────────\nlet offset = undefined\n\nasync function poll() {\n  while (true) {\n    try {\n      const url = new URL(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fevents`)\n      if (offset !== undefined) url.searchParams.set('offset', String(offset))\n\n      const res = await fetch(url, {\n        headers: { 'X-Api-Key': VIBE_KEY }\n      })\n      const { data } = await res.json()\n\n      for (const event of data.events || []) {\n        await handleEvent(event)\n      }\n\n      if (data.nextOffset !== undefined) {\n        offset = data.nextOffset\n      }\n    } catch (err) {\n      console.error('Poll error:', err.message)\n    }\n\n    await new Promise(r => setTimeout(r, 3000))\n  }\n}\n\nasync function handleEvent(event) {\n  const { data } = event\n\n  \u002F\u002F ── Обработка сообщений ────────────────────────────────────\n  if (event.type === 'ONIMBOTV2MESSAGEADD') {\n    const dialogId = data.chat.dialogId\n    const text = data.message?.text || ''\n    const userName = data.user?.firstName || 'друг'\n\n    \u002F\u002F Пропускаем системные сообщения и свои собственные\n    if (data.message?.isSystem) return\n    if (data.message?.authorId === BOT_ID) return\n\n    \u002F\u002F Показываем \"думает...\"\n    await fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Ftyping`, {\n      method: 'POST',\n      headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify({\n        dialogId,\n        statusMessageCode: 'IMBOT_AGENT_ACTION_THINKING'\n      })\n    })\n\n    \u002F\u002F Ставим реакцию на сообщение\n    await fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fmessages\u002F${data.message.id}\u002Freactions`, {\n      method: 'POST',\n      headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify({ reaction: 'like' })\n    })\n\n    \u002F\u002F Отправляем эхо-ответ с клавиатурой\n    await fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fmessages`, {\n      method: 'POST',\n      headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify({\n        dialogId,\n        fields: {\n          message: `${userName}, вы написали: [I]${text}[\u002FI]`,\n          keyboard: [\n            {\n              TEXT: 'Повторить',\n              BG_COLOR_TOKEN: 'primary',\n              ACTION: 'SEND',\n              ACTION_VALUE: text || 'ping',\n              BLOCK: 'Y'\n            },\n            {\n              TEXT: 'Помощь',\n              BG_COLOR_TOKEN: 'secondary',\n              ACTION: 'SEND',\n              ACTION_VALUE: '\u002Fhelp',\n              DISPLAY: 'LINE'\n            }\n          ]\n        }\n      })\n    })\n  }\n\n  \u002F\u002F ── Обработка команд ───────────────────────────────────────\n  if (event.type === 'ONIMBOTV2COMMANDADD') {\n    const dialogId = data.chat.dialogId\n    const command = data.command\n\n    if (command.command === 'ping') {\n      await fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fcommands\u002F${command.id}\u002Fanswer`, {\n        method: 'POST',\n        headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n        body: JSON.stringify({\n          dialogId,\n          messageId: data.message.id,\n          fields: { message: '[B]Pong![\u002FB] Бот работает нормально.' }\n        })\n      })\n    }\n\n    if (command.command === 'help') {\n      await fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fcommands\u002F${command.id}\u002Fanswer`, {\n        method: 'POST',\n        headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n        body: JSON.stringify({\n          dialogId,\n          messageId: data.message.id,\n          fields: { message: '[B]Echo Bot — Команды[\u002FB]\\n\\n\u002Fping — проверить, жив ли бот\\n\u002Fhelp — показать этот список\\n\\nПросто напишите мне — я повторю ваше сообщение.' }\n        })\n      })\n    }\n  }\n\n  \u002F\u002F ── Обработка реакций ──────────────────────────────────────\n  if (event.type === 'ONIMBOTV2REACTIONCHANGE') {\n    const dialogId = data.chat.dialogId\n    const userName = data.user?.firstName || 'Кто-то'\n\n    if (data.action === 'add') {\n      await fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fmessages`, {\n        method: 'POST',\n        headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n        body: JSON.stringify({\n          dialogId,\n          fields: {\n            message: `${userName} поставил реакцию: ${data.reaction}`,\n            system: true\n          }\n        })\n      })\n    }\n  }\n\n  \u002F\u002F ── Вход в чат ─────────────────────────────────────────────\n  if (event.type === 'ONIMBOTV2JOINCHAT') {\n    await fetch(`${BASE}\u002Fbots\u002F${BOT_ID}\u002Fmessages`, {\n      method: 'POST',\n      headers: { 'X-Api-Key': VIBE_KEY, 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify({\n        dialogId: data.chat.dialogId,\n        fields: {\n          message: 'Привет! Я Echo Bot. Напишите мне что-нибудь, и я повторю.\\n\\nКоманды:\\n[SEND=\u002Fping]Ping[\u002FSEND] | [SEND=\u002Fhelp]Помощь[\u002FSEND]'\n        }\n      })\n    })\n  }\n}\n\npoll()\n```\n\n---\n\n## Полный пример: Standup-бот (личный опрос → отчёт в группу)\n\nЧастый сценарий, где не хватает явного примера: утром бот пишет каждому сотруднику **в личку**, собирает ответы и публикует сводку в **групповой чат**. Здесь важны два разных `dialogId` (см. [Отправить сообщение](\u002Fdocs\u002Fbots\u002Fmessages\u002Fsend)):\n\n- **личное сообщение** — `dialogId` равен числовому ID пользователя (`\"42\"`)\n- **групповой чат** — `dialogId` имеет вид `chatXXX`.\n\n### Где взять `dialogId` группового чата\n\n- Создать чат: `POST \u002Fv1\u002Fbots\u002F:botId\u002Fchats` (`Chat.add`) — в ответе `data.chat.dialogId` = `chatXXX`. См. [Создать чат](\u002Fdocs\u002Fbots\u002Fchats\u002Fcreate).\n- Или взять из входящего события: каждое сообщение-событие из `GET \u002Fv1\u002Fbots\u002F:botId\u002Fevents` несёт `dialogId` (для группового чата это `chatXXX`). См. [События](\u002Fdocs\u002Fbots\u002Fevents).\n\n### Где взять ID участников\n\n`GET \u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fusers` возвращает список участников чата, либо берите сотрудников из `GET \u002Fv1\u002Fusers` (скоуп `user`). Числовой ID каждого пользователя и есть его личный `dialogId`.\n\n### Шаги\n\n```javascript\nconst BASE = 'https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1'\nconst headers = { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application\u002Fjson' }\n\n\u002F\u002F 1. Утром: личный вопрос каждому участнику (dialogId = числовой userId)\nasync function askTeam(botId, userIds) {\n  for (const userId of userIds) {\n    await fetch(`${BASE}\u002Fbots\u002F${botId}\u002Fmessages`, {\n      method: 'POST',\n      headers,\n      body: JSON.stringify({\n        dialogId: String(userId),\n        fields: { message: 'Доброе утро! Что сделал вчера, что планируешь сегодня, что мешает в работе?' },\n      }),\n    })\n  }\n}\n\n\u002F\u002F 2. В течение дня: собираем ответы через polling.\n\u002F\u002F    Поля события вложены в ev.data (см. «События»): chat.dialogId, message.text, user.id.\n\u002F\u002F    В личном диалоге ev.data.chat.dialogId равен числовому ID отправителя — тот же\n\u002F\u002F    путь, что использует echo-бот выше.\nconst answers = {}\nasync function collect(botId, expectedUserIds) {\n  const res = await fetch(`${BASE}\u002Fbots\u002F${botId}\u002Fevents`, { headers })\n  const { data } = await res.json()\n  for (const ev of data.events ?? []) {\n    if (ev.type !== 'ONIMBOTV2MESSAGEADD') continue\n    const fromUser = String(ev.data.user.id)\n    \u002F\u002F Личный диалог: dialogId берём из ev.data.chat.dialogId\n    if (ev.data.chat.dialogId === fromUser && expectedUserIds.includes(fromUser)) {\n      answers[fromUser] = ev.data.message.text\n    }\n  }\n}\n\n\u002F\u002F 3. Публикуем сводку в групповой чат (dialogId = chatXXX)\nasync function publishReport(botId, groupDialogId, userIds) {\n  const lines = userIds.map(id => `[b]${id}[\u002Fb]: ${answers[String(id)] ?? '— нет ответа'}`)\n  await fetch(`${BASE}\u002Fbots\u002F${botId}\u002Fmessages`, {\n    method: 'POST',\n    headers,\n    body: JSON.stringify({\n      dialogId: groupDialogId, \u002F\u002F 'chat123'\n      fields: { message: `[b]Standup за сегодня[\u002Fb]\\n${lines.join('\\n')}` },\n    }),\n  })\n}\n```\n\n**Расписание — на стороне вашего сервера.** Платформа не планирует запуски за вас: бот живёт на вашем Black Hole-сервере, поэтому утренний опрос и публикацию отчёта вызывайте по собственному cron (`crontab`, `node-cron` и т. п.). Polling событий держите запущенным постоянно — см. [Echo-бот](#полный-пример-echo-бот) выше.\n\n---\n\n## Windows \u002F PowerShell и UTF-8\n\nПри отправке запросов к API ботов из Windows PowerShell кириллица в `name` бота или в теле сообщения может превратиться в знаки вопроса (`?`). Это не проблема отображения на стороне сервера — кириллические байты теряются ещё до отправки HTTP-запроса, на стороне клиента.\n\n**Причина:** по умолчанию PowerShell использует кодировку `windows-1251` (или `iso-8859-1` — зависит от локали) для строк, передаваемых в параметр `-Body` у `Invoke-WebRequest` \u002F `Invoke-RestMethod`. Исходная строка теряет кириллицу ещё до того, как HTTP-клиент соберёт запрос. Заголовок `Content-Type: charset=utf-8` здесь не помогает — к моменту его применения исходные байты уже потеряны при перекодировании на стороне клиента.\n\n**Решение:** явно установите UTF-8 и передавайте тело массивом байтов.\n\n```powershell\n# 1. Включить UTF-8 для PowerShell (делается один раз в сессии)\n[Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n\n# 2. Собрать JSON и преобразовать его в массив UTF-8 байтов\n$body = @{\n  code = 'my_bot'\n  name = 'Мой бот'\n  color = 'AZURE'\n} | ConvertTo-Json -Compress\n\n$bytes = [System.Text.Encoding]::UTF8.GetBytes($body)\n\n# 3. Передать в -Body массив байтов (не строку!) и явно указать кодировку в Content-Type\nInvoke-WebRequest `\n  -Uri 'https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fbots' `\n  -Method POST `\n  -Headers @{\n    'X-Api-Key'    = $env:VIBE_KEY\n    'Content-Type' = 'application\u002Fjson; charset=utf-8'\n  } `\n  -Body $bytes\n```\n\n**Распространённые ошибки:**\n\n- ❌ Сохранять `.ps1` файл **с UTF-8 BOM** — старые версии PowerShell могут не разобрать сам скрипт.\n- ❌ Передавать **строку** в `-Body` (`-Body $body`) вместо массива байтов (`-Body $bytes`) — строка повторно перекодируется через системную кодировку.\n- ❌ Полагаться только на `Content-Type: application\u002Fjson; charset=utf-8` без `UTF8.GetBytes` — этот заголовок не восстанавливает байты, потерянные при перекодировании на стороне клиента, а лишь объявляет серверу заявленную кодировку тела.\n\n**Node.js и Python работают по умолчанию** — `fetch` с JSON в теле запроса и библиотека `requests` сами кодируют тело в UTF-8, дополнительных шагов не требуется. Проблема специфична для PowerShell.\n\n---\n\n## Коды ошибок\n\n### Ошибки бот-платформы\n\n| Код | HTTP | Описание |\n|-----|------|---------|\n| `SCOPE_DENIED` | 403 | API-ключ не имеет скоупа `imbot` |\n| `TOKEN_MISSING` | 401 | API-ключ не имеет настроенных токенов |\n| `CODE_REQUIRED` | 400 | Не передан параметр `code` при регистрации |\n| `NAME_REQUIRED` | 400 | Не передан параметр `name` при регистрации |\n| `INVALID_BOT_ID` | 400 | `botId` должен быть числом |\n| `BOT_NOT_FOUND` | 404 | Бот с таким ID не найден — зарегистрируйте через `POST \u002Fv1\u002Fbots` |\n| `BOT_ACCESS_DENIED` | 403 | Бот принадлежит другому API-ключу |\n| `BOT_ALREADY_EXISTS` | 409 | Бот с таким `code` уже зарегистрирован. Ответ содержит `data.botId` существующего бота (на этом пути — плоская форма, в отличие от вложенного `data.bot.id` в успешном 201) |\n| `REGISTRATION_FAILED` | 502 | Битрикс24 не вернул ID бота при регистрации |\n\n### Системные ошибки\n\n| Код | HTTP | Описание |\n|-----|------|---------|\n| `AUTH_REQUIRED` | 401 | Отсутствует заголовок `X-Api-Key` |\n| `INVALID_API_KEY` | 401 | Неверный API-ключ |\n| `KEY_REVOKED` | 403 | API-ключ отозван |\n| `RATE_LIMIT` | 429 | Превышен лимит запросов |\n| `BITRIX_ERROR` | 502 | Ошибка в ответе Битрикс24 API |\n| `BITRIX_UNAVAILABLE` | 502 | Портал Битрикс24 недоступен |\n| `INTERNAL_ERROR` | 500 | Внутренняя ошибка сервера |\n\n---\n\n## Справочник эндпоинтов\n\nВсе 36 эндпоинтов бот-платформы:\n\n| Метод | Путь | Битрикс24 метод | Описание |\n|-------|------|---------------|---------|\n| POST | [\u002Fv1\u002Fbots](\u002Fdocs\u002Fbots\u002Fmanagement\u002Fcreate) | imbot.v2.Bot.register | Регистрация бота |\n| GET | [\u002Fv1\u002Fbots](\u002Fdocs\u002Fbots\u002Fmanagement\u002Flist) | — | Список ботов |\n| GET | [\u002Fv1\u002Fbots\u002F:botId](\u002Fdocs\u002Fbots\u002Fmanagement\u002Fget) | imbot.v2.Bot.get | Данные бота |\n| PATCH | [\u002Fv1\u002Fbots\u002F:botId](\u002Fdocs\u002Fbots\u002Fmanagement\u002Fupdate) | imbot.v2.Bot.update | Обновление бота |\n| DELETE | [\u002Fv1\u002Fbots\u002F:botId](\u002Fdocs\u002Fbots\u002Fmanagement\u002Fdelete) | imbot.v2.Bot.unregister | Удаление бота |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Freauth](\u002Fdocs\u002Fbots\u002Fmanagement\u002Freauth) | — | Повторная авторизация бота |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fresubscribe](\u002Fdocs\u002Fbots\u002Fmanagement\u002Fresubscribe) | imbot.v2.Bot.update | Перепривязка подписки на события |\n| GET | [\u002Fv1\u002Fbots\u002Frevision](\u002Fdocs\u002Fbots\u002Fmanagement\u002Frevision) | imbot.v2.Revision.get | Ревизия бот-платформы |\n| GET | [\u002Fv1\u002Fbots\u002F:botId\u002Fevents](\u002Fdocs\u002Fbots\u002Fevents\u002Fpolling) | imbot.v2.Event.get | Получение событий |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fmessages](\u002Fdocs\u002Fbots\u002Fmessages\u002Fsend) | imbot.v2.Chat.Message.send | Отправка сообщения |\n| PATCH | [\u002Fv1\u002Fbots\u002F:botId\u002Fmessages\u002F:messageId](\u002Fdocs\u002Fbots\u002Fmessages\u002Fupdate) | imbot.v2.Chat.Message.update | Обновление сообщения |\n| DELETE | [\u002Fv1\u002Fbots\u002F:botId\u002Fmessages\u002F:messageId](\u002Fdocs\u002Fbots\u002Fmessages\u002Fdelete) | imbot.v2.Chat.Message.delete | Удаление сообщения |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fread](\u002Fdocs\u002Fbots\u002Fmessages\u002Fread) | imbot.v2.Chat.Message.read | Прочитать сообщения |\n| GET | [\u002Fv1\u002Fbots\u002F:botId\u002Fmessages\u002F:messageId](\u002Fdocs\u002Fbots\u002Fmessages\u002Fget) | imbot.v2.Chat.Message.get | Получить сообщение |\n| GET | [\u002Fv1\u002Fbots\u002F:botId\u002Fmessages\u002F:messageId\u002Fcontext](\u002Fdocs\u002Fbots\u002Fmessages\u002Fcontext) | imbot.v2.Chat.Message.getContext | Контекст сообщения |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fmessages\u002F:messageId\u002Freactions](\u002Fdocs\u002Fbots\u002Fui\u002Freaction-add) | imbot.v2.Chat.Message.Reaction.add | Добавить реакцию |\n| DELETE | [\u002Fv1\u002Fbots\u002F:botId\u002Fmessages\u002F:messageId\u002Freactions](\u002Fdocs\u002Fbots\u002Fui\u002Freaction-delete) | imbot.v2.Chat.Message.Reaction.delete | Удалить реакцию |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Ftyping](\u002Fdocs\u002Fbots\u002Fui\u002Ftyping) | imbot.v2.Chat.InputAction.notify | Индикатор набора |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Ftext-field](\u002Fdocs\u002Fbots\u002Fui\u002Ftext-field) | imbot.v2.Chat.TextField.enabled | Управление полем ввода |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats](\u002Fdocs\u002Fbots\u002Fchats\u002Fcreate) | imbot.v2.Chat.add | Создание чата |\n| GET | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId](\u002Fdocs\u002Fbots\u002Fchats\u002Fget) | imbot.v2.Chat.get | Информация о чате |\n| PATCH | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId](\u002Fdocs\u002Fbots\u002Fchats\u002Fupdate) | imbot.v2.Chat.update | Обновление чата |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fleave](\u002Fdocs\u002Fbots\u002Fchats\u002Fleave) | imbot.v2.Chat.leave | Покинуть чат |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fowner](\u002Fdocs\u002Fbots\u002Fchats\u002Fset-owner) | imbot.v2.Chat.setOwner | Назначить владельца |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fusers](\u002Fdocs\u002Fbots\u002Fchats\u002Fuser-add) | imbot.v2.Chat.User.add | Добавить участников |\n| DELETE | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fusers](\u002Fdocs\u002Fbots\u002Fchats\u002Fuser-delete) | imbot.v2.Chat.User.delete | Удалить участника |\n| GET | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fusers](\u002Fdocs\u002Fbots\u002Fchats\u002Fuser-list) | imbot.v2.Chat.User.list | Список участников |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fmanagers](\u002Fdocs\u002Fbots\u002Fchats\u002Fmanager-add) | imbot.v2.Chat.Manager.add | Добавить менеджеров |\n| DELETE | [\u002Fv1\u002Fbots\u002F:botId\u002Fchats\u002F:dialogId\u002Fmanagers](\u002Fdocs\u002Fbots\u002Fchats\u002Fmanager-delete) | imbot.v2.Chat.Manager.delete | Удалить менеджеров |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fcommands](\u002Fdocs\u002Fbots\u002Fcommands\u002Fregister) | imbot.v2.Command.register | Регистрация команды |\n| GET | [\u002Fv1\u002Fbots\u002F:botId\u002Fcommands](\u002Fdocs\u002Fbots\u002Fcommands\u002Flist) | imbot.v2.Command.list | Список команд |\n| PATCH | [\u002Fv1\u002Fbots\u002F:botId\u002Fcommands\u002F:commandId](\u002Fdocs\u002Fbots\u002Fcommands\u002Fupdate) | imbot.v2.Command.update | Обновление команды |\n| DELETE | [\u002Fv1\u002Fbots\u002F:botId\u002Fcommands\u002F:commandId](\u002Fdocs\u002Fbots\u002Fcommands\u002Fdelete) | imbot.v2.Command.unregister | Удаление команды |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Fcommands\u002F:commandId\u002Fanswer](\u002Fdocs\u002Fbots\u002Fcommands\u002Fanswer) | imbot.v2.Command.answer | Ответ на команду |\n| POST | [\u002Fv1\u002Fbots\u002F:botId\u002Ffiles](\u002Fdocs\u002Fbots\u002Ffiles\u002Fupload) | imbot.v2.File.upload | Загрузка файла |\n| GET | [\u002Fv1\u002Fbots\u002F:botId\u002Ffiles\u002F:fileId](\u002Fdocs\u002Fbots\u002Ffiles\u002Fdownload) | imbot.v2.File.download | Скачивание файла |\n","2026-07-07",{}]