For AI agents: markdown of this page — /docs-content-en/chats/messages/load-in-context.md documentation index — /llms.txt
Load around a message
GET /v1/chats/messages/:messageId/load
Opens a chat at the given message in one request — like loading a chat, but the page is built around the given message instead of the last read one. The chat is found by the message, so dialogId is not needed.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
messageId (path) |
number | yes | — | Message ID, a positive integer — the id field of a message from the message history, message search or chat loading |
messageLimit (query) |
number | no | 50 | How many messages to take on each side of the given one. From 1 to 200: a value outside the range is clamped; the passed and applied values are in meta.requestedMessageLimit and meta.appliedMessageLimit |
pinLimit (query) |
number | no | 50 | How many pinned messages to return. From 1 to 200; the passed and applied values are in meta.requestedPinLimit and meta.appliedPinLimit |
Other or repeated parameters are rejected with 400 INVALID_PARAMS.
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/chats/messages/1002/load?messageLimit=20" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/chats/messages/1002/load?messageLimit=20" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/messages/1002/load?messageLimit=20', {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data } = await res.json()
console.log('Chat:', data.chat.dialogId)
console.log('Has older:', data.hasPrevPage, 'has newer:', data.hasNextPage)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/messages/1002/load?messageLimit=20', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.chat |
object | The card of the message's chat: id, dialogId, name, type, owner, role, permissions and other fields |
data.messages |
array | The given message and its neighbours |
data.messages[].id |
number | Message ID |
data.messages[].chatId |
number | Chat ID — equals data.chat.id |
data.messages[].authorId |
number | Author ID — the profile can be fetched by user ID. 0 — a system message |
data.messages[].date |
string | Date sent (ISO 8601) |
data.messages[].text |
string | Message text |
data.pins |
array | Pinned messages |
data.users |
array | Members mentioned on the page |
data.files |
array | Files of the page's messages |
data.reactions |
array | Reactions to the page's messages |
data.hasPrevPage |
boolean | Whether there are messages older than the page |
data.hasNextPage |
boolean | Whether there are messages newer than the page |
data.callInfo |
object | Chat context: chatId and token — the current user's call token. The endpoint passes it through unchanged. Do not write it to logs |
meta.requestedMessageLimit |
number | The messageLimit passed, when it was outside the range from 1 to 200 |
meta.appliedMessageLimit |
number | The applied messageLimit value — only when it was clamped to a bound |
meta.requestedPinLimit |
number | The pinLimit passed, when it was outside the range from 1 to 200 |
meta.appliedPinLimit |
number | The applied pinLimit value — only when it was clamped to a bound |
Response example
{
"success": true,
"data": {
"chat": {
"id": 42,
"dialogId": "chat42",
"name": "Project",
"type": "chat",
"owner": 5,
"role": "member"
},
"messages": [
{
"id": 1001,
"chatId": 42,
"authorId": 5,
"date": "2026-09-20T10:00:00+00:00",
"text": "Please check the mockup",
"params": {}
},
{
"id": 1002,
"chatId": 42,
"authorId": 7,
"date": "2026-09-20T10:01:00+00:00",
"text": "All done",
"params": {}
}
],
"pins": [],
"users": [],
"files": [],
"reactions": [],
"hasPrevPage": true,
"hasNextPage": true
}
}
Error response example
422 — the message does not exist in the Bitrix24 account:
{
"success": false,
"error": {
"code": "BITRIX_ERROR",
"message": "MESSAGE_NOT_FOUND",
"b24Code": "MESSAGE_NOT_FOUND"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
messageId is not a positive integer, or the request has a parameter other than messageLimit and pinLimit, a repeated parameter or an invalid value. Checked before any call to Bitrix24 |
| 404 | ENTITY_NOT_FOUND |
Bitrix24 returned "not found". The portal code is in error.b24Code |
| 422 | BITRIX_ERROR |
Bitrix24 returned an error. The portal code is in error.b24Code. A missing message lands here too (MESSAGE_NOT_FOUND), as does a message older than the start of the chat history open to the user (MESSAGE_ACCESS_DENIED) |
| 403 | BITRIX_ACCESS_DENIED |
The user has no access to the message's chat — Bitrix24 refused with the ACCESS_DENIED code |
| 403 | SCOPE_DENIED |
The API key does not have the im scope |
| 401 | TOKEN_MISSING |
The API key has no Bitrix24 tokens configured |
The full list of common API errors — Errors.
Known specifics
Opening the chat may make you a member. When the message's chat allows auto-join, the call adds the current user as a member, as loading a chat does. This targeted read operation is available to a READONLY key, subject to the im scope and the user's Bitrix24 permissions. It does not mark messages as read by itself.
How it differs from messages around a message. Messages around a message returns only a page of messages with their authors and files. Loading around a message also returns the chat card, pinned messages and the chat context — everything needed to open the chat from scratch, for example from a link to a message.
Continue in the message history. Read older messages from the message history in the v2 mode, passing lastId equal to the smallest id on the page, and newer ones with order=asc and lastId equal to the largest.