For AI agents: markdown of this page — /docs-content-en/bots/management.md documentation index — /llms.txt
Bot management
Register a bot on your Bitrix24 account, fetch and update its data, restore access after authorization failures, and delete the bot when it's no longer needed.
Scope: imbot | Base URL: https://vibecode.bitrix24.com/v1 | Authorization: X-Api-Key
Register a bot
POST /v1/bots
Registers a new bot in a Bitrix24 account. The operation is idempotent on code — a repeated call with the same code returns 409 BOT_ALREADY_EXISTS with the data of the existing bot.
Request fields (body)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
code |
string | yes | — | Unique bot code (Latin letters, digits, underscore) |
name |
string | yes | — | Bot display name |
type |
string | no | bot |
Bot type: bot, personal, supervisor, openline. Cannot be changed after registration |
eventMode |
string | no | fetch |
Event mode: fetch (polling) or webhook (push) |
webhookUrl |
string | no | — | URL for push notifications (only with eventMode: "webhook") |
lastName |
string | no | — | Bot last name |
workPosition |
string | no | — | Bot job title (shown under the name) |
color |
string | no | — | Avatar color: RED, GREEN, MINT, LIGHT_BLUE, DARK_BLUE, PURPLE, AQUA, PINK, LIME, BROWN, AZURE, KHAKI, SAND, MARENGO, GRAY, GRAPHITE |
gender |
string | no | — | Gender: M or F |
avatar |
string | no | — | Bot avatar: PNG or JPEG as a base64 string without the data:image/...;base64, prefix, up to ~50 KB. See "Avatar format" in "Known specifics" |
isHidden |
boolean | no | false |
Hide the bot from the contact list |
isReactionsEnabled |
boolean | no | true |
Allow reactions to the bot's messages |
backgroundId |
string | no | — | Chat background: azure, mint, steel, slate, teal, cornflower, sky, peach, frost |
isSupportOpenline |
boolean | no | false |
Open-channel support (only for type: "openline") |
Bot types
| Type | Description |
|---|---|
bot |
Standard bot — reacts to @mention and direct messages |
personal |
AI assistant — receives all messages without an @mention. Message.get and Message.getContext are available |
supervisor |
System observer — receives all messages in the chats it belongs to |
openline |
Open-channel bot. Requires isSupportOpenline: true |
⚠
personalandsupervisorare privileged types: they receive all messages in the chats they belong to, even without an @mention of the bot. Use them deliberately. Registration viaPOST /v1/botsis allowed and does not require an admin role on the Bitrix24 side — the restriction is set by the permissions of your webhook/OAuth token.
Available colors
Used in the color parameter when creating and updating a bot:
RED, GREEN, MINT, LIGHT_BLUE, DARK_BLUE, PURPLE, AQUA, PINK,
LIME, BROWN, AZURE, KHAKI, SAND, MARENGO, GRAY, GRAPHITE
Examples
curl — personal key
curl -X POST https://vibecode.bitrix24.com/v1/bots \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "support_bot",
"name": "Support",
"type": "bot",
"eventMode": "fetch",
"color": "AZURE",
"workPosition": "Technical support assistant"
}'
curl — OAuth application
curl -X POST https://vibecode.bitrix24.com/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": "Support",
"type": "bot",
"eventMode": "fetch",
"color": "AZURE",
"workPosition": "Technical support assistant"
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/bots', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
code: 'support_bot',
name: 'Support',
type: 'bot',
eventMode: 'fetch',
color: 'AZURE',
workPosition: 'Technical support assistant',
}),
})
const { success, data } = await res.json()
// `data.botId` mirrors the 409 BOT_ALREADY_EXISTS response — the same path for
// success and conflict. `data.bot.id` is kept for backward compatibility.
console.log('Bot ID:', data.botId)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/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: 'Support',
type: 'bot',
eventMode: 'fetch',
color: 'AZURE',
workPosition: 'Technical support assistant',
}),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
botId |
number | Bot ID in the Bitrix24 account. Mirrors data.botId from the 409 response — the same path for success and conflict |
bot.id |
number | Duplicate of botId for backward compatibility. Bot ID in the Bitrix24 account |
bot.code |
string | Unique bot code |
bot.type |
string | Bot type |
bot.eventMode |
string | Event mode: fetch or webhook |
bot.isHidden |
boolean | Hidden from the contact list |
bot.isReactionsEnabled |
boolean | Reactions allowed |
users |
array | Array of Bitrix24 users created for the bot |
Response example
{
"success": true,
"data": {
"botId": 42,
"bot": {
"id": 42,
"code": "support_bot",
"type": "bot",
"eventMode": "fetch",
"isHidden": false,
"isReactionsEnabled": true
},
"users": [
{
"id": 42,
"name": "Support",
"active": true,
"bot": true
}
]
}
}
Error response example
409 — a bot with this code already exists:
{
"success": false,
"error": {
"code": "BOT_ALREADY_EXISTS",
"message": "Bot with this code already exists"
},
"data": {
"botId": 42,
"code": "support_bot",
"name": "Support"
}
}
The data field returns the botId, code, and name of the already-registered bot — this is the idempotent path for recovering the record in the Vibecode database after a desync.
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | CODE_REQUIRED |
The code parameter was not provided |
| 400 | NAME_REQUIRED |
The name parameter was not provided |
| 409 | BOT_ALREADY_EXISTS |
A bot with this code is already registered. The response contains data with botId |
| 422 | BITRIX_ERROR |
Bitrix24 returned an error during registration (error text in message) |
| 502 | REGISTRATION_FAILED |
Bitrix24 did not return a bot ID |
| 403 | SCOPE_DENIED |
The API key does not have the imbot scope |
| 401 | TOKEN_MISSING |
The API key has no configured tokens |
Full list of common API errors — Errors.
Known specifics
Type cannot be changed: after registration, type is fixed. PATCH /v1/bots/:botId does not accept this field.
Recovery after a desync: if the bot exists in the Bitrix24 account but is missing from the Vibecode database (after a failure), a repeated POST with the same code restores the database record.
Body format differs from PATCH: on creation, fields are passed flat (code, name, color). On update — a nested structure { fields: { properties: { name, color } } }.
Avatar format. The avatar field accepts a PNG or JPEG image as a base64 string without the data:image/...;base64, prefix — pass only the base64 data itself. An image URL or a string with the data: prefix results in a 422 BITRIX_ERROR response. Size is up to ~50 KB: above that the request succeeds, but the avatar is not saved and stays empty.
Idempotency on code: if a bot with this code already exists both in the Vibecode database and in the Bitrix24 account, 409 BOT_ALREADY_EXISTS is returned with data: { botId, code, name } of the existing bot. Suitable for re-running scripts and verifying registration without handling 200/400 separately.
Bot lifecycle. A bot exists exactly as long as the local application through which it was registered exists. Removing the application from the Bitrix24 account also removes the bot.
Bot operations use the same key. A bot is bound to the API key it was registered with. Polling events, sending messages, and updating run with that same key — a request from a different key returns 403 BOT_ACCESS_DENIED. To move a bot to another active key of the same user — or by an account admin — use POST /v1/bots/:botId/transfer.
webhook mode requires a public webhookUrl. With eventMode: "webhook", Bitrix24 sends events directly to webhookUrl, so the address must be publicly reachable. A Black Hole server with the OWNER_ONLY policy does not accept such a request — details and the solution are in the Troubleshooting section.