#Бот-платформа
33 REST-эндпоинта для создания чат-ботов Битрикс24. Не нужны вебхуки и публичный сервер — бот опрашивает события через polling и отвечает через HTTP.
Скоуп: imbot | Базовый URL: https://vibecode.bitrix24.tech/v1 | Авторизация: X-Api-Key
Быстрый старт | Echo-бот (пример) | Коды ошибок | Справочник эндпоинтов
#Разделы документации
- Управление ботами — регистрация, обновление, удаление
- События — polling входящих сообщений и команд
- Сообщения — отправка, редактирование, удаление, форматирование
- Чаты — создание чатов, управление участниками и менеджерами
- Команды — slash-команды бота
- Интерфейс — реакции, индикатор набора, поле ввода
- Файлы — загрузка и скачивание
#Быстрый старт
#1. Зарегистрируйте бота
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"
}'
Ответ:
{
"success": true,
"data": {
"botId": 42,
"code": "my_helper_bot",
"name": "Помощник",
"type": "bot",
"eventMode": "fetch"
}
}
#2. Получайте события (long-polling)
curl -H "X-Api-Key: $VIBE_KEY" \
"https://vibecode.bitrix24.tech/v1/bots/42/events"
Ответ содержит nextOffset — передайте его как offset в следующем запросе:
{
"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": 0
}
}
Следующий запрос:
curl -H "X-Api-Key: $VIBE_KEY" \
"https://vibecode.bitrix24.tech/v1/bots/42/events?offset=42"
#3. Отправьте ответ
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": "Привет! Чем могу помочь?" }
}'
Ответ:
{
"success": true,
"data": {
"id": 1502,
"uuidMap": []
}
}
#Полный пример: Echo-бот
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: bot } = await regRes.json()
const BOT_ID = bot.botId
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.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.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.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.dialogId,
fields: {
message: 'Привет! Я Echo Bot. Напишите мне что-нибудь, и я повторю.\n\nКоманды:\n[SEND=/ping]Ping[/SEND] | [SEND=/help]Помощь[/SEND]'
}
})
})
}
}
poll()
#Коды ошибок
#Ошибки бот-платформы
| Код | 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 |
REGISTRATION_FAILED |
502 | Битрикс24 не вернул ID бота при регистрации |
#Системные ошибки
| Код | HTTP | Описание |
|---|---|---|
AUTH_REQUIRED |
401 | Отсутствует заголовок X-Api-Key |
INVALID_KEY |
401 | Неверный API-ключ |
KEY_REVOKED |
403 | API-ключ отозван |
RATE_LIMIT |
429 | Превышен лимит запросов |
BITRIX_ERROR |
502 | Ошибка в ответе Bitrix24 API |
BITRIX_UNAVAILABLE |
502 | Портал Битрикс24 недоступен |
INTERNAL_ERROR |
500 | Внутренняя ошибка сервера |
#Справочник эндпоинтов
Все 33 эндпоинта бот-платформы:
| Метод | Путь | Bitrix24 метод | Описание |
|---|---|---|---|
| POST | /v1/bots | imbot.v2.Bot.register | Регистрация бота |
| GET | /v1/bots | — | Список ботов |
| GET | /v1/bots/:botId | imbot.v2.Bot.get | Данные бота |
| PATCH | /v1/bots/:botId | imbot.v2.Bot.update | Обновление бота |
| DELETE | /v1/bots/:botId | imbot.v2.Bot.unregister | Удаление бота |
| GET | /v1/bots/:botId/events | imbot.v2.Event.get | Получение событий (polling) |
| POST | /v1/bots/:botId/messages | imbot.v2.Chat.Message.send | Отправка сообщения |
| PATCH | /v1/bots/:botId/messages/:messageId | imbot.v2.Chat.Message.update | Обновление сообщения |
| DELETE | /v1/bots/:botId/messages/:messageId | imbot.v2.Chat.Message.delete | Удаление сообщения |
| POST | /v1/bots/:botId/chats/:dialogId/read | imbot.v2.Chat.Message.read | Прочитать сообщения |
| GET | /v1/bots/:botId/messages/:messageId | imbot.v2.Chat.Message.get | Получить сообщение |
| GET | /v1/bots/:botId/messages/:messageId/context | imbot.v2.Chat.Message.getContext | Контекст сообщения |
| POST | /v1/bots/:botId/messages/:messageId/reactions | imbot.v2.Chat.Message.Reaction.add | Добавить реакцию |
| DELETE | /v1/bots/:botId/messages/:messageId/reactions | imbot.v2.Chat.Message.Reaction.delete | Удалить реакцию |
| POST | /v1/bots/:botId/typing | imbot.v2.Chat.InputAction.notify | Индикатор набора |
| POST | /v1/bots/:botId/text-field | imbot.v2.Chat.TextField.enabled | Управление полем ввода |
| POST | /v1/bots/:botId/chats | imbot.v2.Chat.add | Создание чата |
| GET | /v1/bots/:botId/chats/:dialogId | imbot.v2.Chat.get | Информация о чате |
| PATCH | /v1/bots/:botId/chats/:dialogId | imbot.v2.Chat.update | Обновление чата |
| POST | /v1/bots/:botId/chats/:dialogId/leave | imbot.v2.Chat.leave | Покинуть чат |
| POST | /v1/bots/:botId/chats/:dialogId/owner | imbot.v2.Chat.setOwner | Назначить владельца |
| POST | /v1/bots/:botId/chats/:dialogId/users | imbot.v2.Chat.User.add | Добавить участников |
| DELETE | /v1/bots/:botId/chats/:dialogId/users | imbot.v2.Chat.User.delete | Удалить участника |
| GET | /v1/bots/:botId/chats/:dialogId/users | imbot.v2.Chat.User.list | Список участников |
| POST | /v1/bots/:botId/chats/:dialogId/managers | imbot.v2.Chat.Manager.add | Добавить менеджеров |
| DELETE | /v1/bots/:botId/chats/:dialogId/managers | imbot.v2.Chat.Manager.delete | Удалить менеджеров |
| POST | /v1/bots/:botId/commands | imbot.v2.Command.register | Регистрация команды |
| GET | /v1/bots/:botId/commands | imbot.v2.Command.list | Список команд |
| PATCH | /v1/bots/:botId/commands/:commandId | imbot.v2.Command.update | Обновление команды |
| DELETE | /v1/bots/:botId/commands/:commandId | imbot.v2.Command.unregister | Удаление команды |
| POST | /v1/bots/:botId/commands/:commandId/answer | imbot.v2.Command.answer | Ответ на команду |
| POST | /v1/bots/:botId/files | imbot.v2.File.upload | Загрузка файла |
| GET | /v1/bots/:botId/files/:fileId | imbot.v2.File.download | Скачивание файла |