For AI agents: markdown of this page — /docs-content-en/chats/copilot.md documentation index — /llms.txt
Documentation articles are currently available in English.
CoPilot
Work with the Bitrix24 AI assistant in chats: open the CoPilot draft chat, switch the assistant's model and role, ask it to regenerate an answer, and rate the answer.
Scope: im | Base URL: https://vibecode.bitrix24.com/v1 | Authorization: X-Api-Key
CoPilot draft chat
POST /v1/chats/copilot/draft
Opens the current user's CoPilot draft chat — the v2 messenger method im.v2.Copilot.DraftChat.get. The response has the same structure as in Load a chat: the chat card, the first page of messages, pinned messages, participants, files and the copilot block. When there is no draft chat yet, the first call creates it.
Parameters
There are no path or query parameters. Any query parameter is rejected with 400 INVALID_PARAMS.
Request fields (body)
The body is optional.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
messageLimit |
number | no | 50 | How many messages to return on the first page. From 1 to 200: a value outside the range is clamped, echoed as meta.requestedMessageLimit and meta.appliedMessageLimit |
pinLimit |
number | no | 50 | How many pinned messages to return. From 1 to 200, echoed as meta.requestedPinLimit and meta.appliedPinLimit |
Other body fields are rejected with 400 INVALID_PARAMS.
Examples
curl — personal key
curl -X POST https://vibecode.bitrix24.com/v1/chats/copilot/draft \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messageLimit": 20}'
curl — OAuth application
curl -X POST https://vibecode.bitrix24.com/v1/chats/copilot/draft \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"messageLimit": 20}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/copilot/draft', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ messageLimit: 20 }),
})
const { data } = await res.json()
console.log('Draft chat:', data.chat.dialogId)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/copilot/draft', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ messageLimit: 20 }),
})
const { data } = await res.json()
console.log('Draft chat:', data.chat.dialogId)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.chat |
object | The draft chat card: id, dialogId, name, type, owner, role and other fields |
data.messages |
array | The first page of messages |
data.pins |
array | Pinned messages |
data.users |
array | Participants mentioned on the page |
data.files |
array | Files of the messages on the page |
data.reactions |
array | Reactions to the messages on the page |
data.copilot |
object | The CoPilot block |
data.copilot.chats |
array | CoPilot chats on the page: dialogId, role — the role code, engine — the model code, titleIsCustom |
data.copilot.engines |
array|null | Models of the chats on the page: code, name, supportsReasoning |
data.copilot.roles |
object|null | Roles keyed by role code: code, name, desc, avatar, default, prompts |
data.copilot.aiProvider |
string | Name of the default model |
data.hasPrevPage |
boolean | Whether there are messages older than the first page |
data.hasNextPage |
boolean | Whether there are messages newer than the first page |
meta.requestedMessageLimit |
number | The messageLimit sent, when it fell outside the range from 1 to 200 |
meta.appliedMessageLimit |
number | The applied messageLimit |
meta.requestedPinLimit |
number | The pinLimit sent, when it fell outside the range from 1 to 200 |
meta.appliedPinLimit |
number | The applied pinLimit |
Response example
{
"success": true,
"data": {
"chat": {
"id": 2001,
"dialogId": "chat2001",
"name": "CoPilot",
"type": "copilot",
"owner": 5,
"role": "owner"
},
"messages": [
{
"id": 9001,
"chatId": 2001,
"authorId": 0,
"date": "2026-09-25T10:00:00+00:00",
"text": "Hi! How can I help?",
"params": {}
}
],
"pins": [],
"users": [],
"files": [],
"reactions": [],
"copilot": {
"chats": [
{ "dialogId": "chat2001", "role": "copilot_assistant", "engine": "engine_code", "titleIsCustom": false }
],
"messages": null,
"engines": [
{ "code": "engine_code", "name": "Engine name", "supportsReasoning": false }
],
"roles": {
"copilot_assistant": {
"code": "copilot_assistant",
"name": "CoPilot",
"desc": "Universal assistant",
"avatar": { "small": "", "medium": "", "large": "" },
"default": true,
"prompts": []
}
},
"aiProvider": "Engine name"
},
"hasPrevPage": false,
"hasNextPage": false
}
}
Error response example
422 — the CoPilot draft chat is not available in the Bitrix24 account:
{
"success": false,
"error": {
"code": "BITRIX_ERROR",
"message": "DRAFT_CHAT_NOT_AVAILABLE",
"b24Code": "DRAFT_CHAT_NOT_AVAILABLE"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
messageLimit or pinLimit is not an integer, or another body field or a query parameter was sent. Checked before any call to Bitrix24 |
| 422 | BITRIX_ERROR |
Bitrix24 refused; the portal code is in error.b24Code. DRAFT_CHAT_NOT_AVAILABLE — the draft chat is turned off on the portal |
| 403 | BITRIX_ACCESS_DENIED |
The user is not allowed to create CoPilot chats — Bitrix24 refused with the ACCESS_DENIED code |
| 403 | SCOPE_DENIED |
The API key does not have the im scope |
| 403 | WRITE_BLOCKED_READONLY_KEY |
The key is read-only — the first call creates a chat |
| 401 | TOKEN_MISSING |
The API key has no Bitrix24 tokens configured |
The full list of general API errors — Errors.
Known specifics
Why POST. The first call creates the draft chat, so the operation is a write, even though repeated calls only read it. A read-only key gets 403 WRITE_BLOCKED_READONLY_KEY.
Response keys. Keys that name fields are converted to camelCase. Keys that are data stay as they are: the data.copilot.roles dictionary is keyed by the role code, and copilot_assistant arrives as copilot_assistant — the same value that role carries in data.copilot.chats, so a role is found directly as roles[role].
Continue in the message history. Load older messages with the message history in the v2 mode using data.chat.dialogId.