Для AI-агентов: markdown этой страницы — /docs-content/chats/discovery/recent.md индекс документации — /llms.txt
Последние диалоги
GET /v1/chats/recent
Возвращает список последних диалогов текущего пользователя: закреплённые диалоги первыми, далее по времени последнего сообщения.
Параметры
| Параметр | Тип | Обяз. | По умолч. | Описание |
|---|---|---|---|---|
format (query) |
string | нет | — | v2 включает режим v2 — см. «Режим v2» ниже. Любое другое значение игнорируется, ответ прежний. Повтор format не отклоняется: из format=v1&format=v2 берётся последнее значение, то есть режим v2, а format=v2&format=v1 даёт прежний ответ. Форма format[]=v2 включает режим v2, если все её значения — v2 |
skipOpenLines (query) |
string | нет | — | Исключить линии открытых каналов. Принимает true, Y или y |
skipChat (query) |
string | нет | — | Исключить групповые чаты. Принимает true, Y или y |
skipDialog (query) |
string | нет | — | Исключить личные диалоги. Принимает true, Y или y |
unreadOnly (query) |
string | нет | — | Только диалоги с непрочитанными сообщениями. Принимает true, Y или y |
onlyOpenLines (query) |
string | нет | — | Только линии открытых каналов. Принимает true, Y или y |
onlyCopilot (query) |
string | нет | — | Только чаты с AI-ассистентом. Принимает true, Y или y |
onlyChannel (query) |
string | нет | — | Только каналы. Принимает true, Y или y |
lastMessageDate (query) |
string | нет | — | Дата последнего сообщения для постраничной навигации (ISO 8601). В режиме v2 — курсор по правилу ниже, формат YYYY-MM-DDTHH:MM:SS со смещением или Z, без долей секунды |
updatedAfter (query) |
string | нет | — | Режим дельты: вернуть диалоги, изменённые начиная с указанного момента. Дата в ISO 8601 с явным смещением или Z. Несовместим с offset и lastMessageDate |
limit (query) |
number | нет | 50 | Количество элементов в ответе. Максимум 200. В режиме v2 — от 50 до 200: меньшее значение поднимается до 50, большее срезается до 200, в обоих случаях переданное и применённое значения возвращаются в meta |
offset (query) |
number | нет | 0 |
Смещение для постраничной навигации |
Режим дельты. Параметр updatedAfter переключает эндпоинт в режим «что изменилось с указанного момента»: GET /v1/chats/recent?updatedAfter=2026-06-28T00:00:00Z. В ответ приходит массив диалогов, у которых dateUpdate не раньше переданного момента. Граница включительна — диалог с dateUpdate, равным переданному моменту, попадает в ответ, поэтому при сдвиге курсора на максимальное увиденное значение пограничная запись придёт повторно.
Размером выборки в этом режиме управляет сервер: читается одна страница до 200 диалогов. Переданный limit на неё не влияет и возвращается в meta.requestedLimit вместе с применённым meta.appliedLimit.
Если в meta пришло truncated со значением true, дельта может быть неполной: за отданной страницей есть ещё диалоги, либо форму ответа не удалось разобрать. В этом случае не сдвигайте updatedAfter, а получите полный список постраничным режимом с курсором lastMessageDate. Число возвращённых строк признаком полноты не является — короткий ответ приходит и тогда, когда за ним есть ещё данные.
Дата без явного смещения — например 2026-06-29 10:00:00 — отклоняется с 400 INVALID_PARAMS: такое значение читается по-разному в зависимости от часового пояса сервера, поэтому момент требуется указать однозначно.
Режим v2. format=v2 переключает эндпоинт в режим v2: первая страница запрашивается без lastMessageDate, следующие — с ним. В data приходит объект v2 — recentItems и коллекции chats, users, messages, files — с ключами в camelCase. Режим принимает только format, limit, lastMessageDate и unreadOnly (true или false). Любой другой параметр, в том числе параметры прежнего режима и их формы в верхнем регистре (OFFSET, LIMIT, LAST_UPDATE), отклоняется с 400 INVALID_PARAMS и именем параметра. Список всегда общий, без вложенных разделов. У режима своя корзина лимита запросов, отдельная от прежнего режима.
Курсор следующей страницы — наименьшая непустая dateLastActivity среди незакреплённых строк текущей страницы. Сравнивайте моменты времени, а не строки: смещение у дат бывает разным. Граница включительная, а закреплённые чаты с датой не новее курсора открывают каждую страницу — повторы снимайте по chatId. Конец списка — только hasNextPage: false. Если при hasNextPage: true курсора нет или он равен прежнему, повторите запрос с бо́льшим limit, вплоть до 200. true без продвижения и при 200 — отказ, а не конец списка. Строк ответа не отбрасывайте, даже когда показываете меньше: курсор считается по всему ответу, и отброшенные строки больше не придут. Обход — не снимок: чат, поднятый новой активностью из-под курсора во время обхода, в нём не появится, поэтому после обхода перечитайте первую страницу. Для полного обхода берите limit=200: закреплённые строки повторяются на каждой странице, и маленькая страница тратит запросы на повторы.
Примеры
curl — личный ключ
curl "https://vibecode.bitrix24.tech/v1/chats/recent?limit=20" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth-приложение
curl "https://vibecode.bitrix24.tech/v1/chats/recent?limit=20" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — личный ключ
const res = await fetch('https://vibecode.bitrix24.tech/v1/chats/recent?limit=20', {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data } = await res.json()
console.log('Последние диалоги:', data.items)
JavaScript — OAuth-приложение
const res = await fetch('https://vibecode.bitrix24.tech/v1/chats/recent?limit=20', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data } = await res.json()
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | Всегда true при успехе |
data |
object|array | Объект результата. В режиме дельты — массив диалогов, см. абзац под таблицей |
data.items |
array | Массив последних диалогов |
data.items[].id |
string | Идентификатор диалога (chatXXX для группового чата или числовой ID для личного диалога) |
data.items[].chatId |
number | Числовой ID чата |
data.items[].type |
string | Тип диалога: chat, openlines, copilot, channel |
data.items[].title |
string | Название диалога |
data.items[].avatar |
object | Аватар диалога |
data.items[].avatar.url |
string | URL изображения аватара. Пустая строка, если аватар не задан |
data.items[].avatar.color |
string | Цвет аватара в шестнадцатеричном формате, например #4ba984 |
data.items[].message |
object | Последнее сообщение в диалоге |
data.items[].message.id |
number | ID сообщения |
data.items[].message.text |
string | Текст сообщения |
data.items[].message.authorId |
number | ID автора сообщения |
data.items[].message.date |
string | Дата сообщения (ISO 8601) |
data.items[].message.file |
boolean | Содержит ли сообщение файл |
data.items[].message.attach |
boolean | Содержит ли сообщение вложение |
data.items[].message.sticker |
string | null | Стикер сообщения или null |
data.items[].message.status |
string | Статус сообщения (например, received) |
data.items[].lastId |
number | ID последнего прочитанного сообщения |
data.items[].unread |
boolean | Есть ли непрочитанные сообщения |
data.items[].counter |
number | Количество непрочитанных сообщений |
data.items[].pinned |
boolean | Диалог закреплён |
data.items[].dateUpdate |
string | Дата последнего обновления диалога (ISO 8601) |
data.items[].dateLastActivity |
string | Дата последней активности (ISO 8601) |
data.items[].chat |
object | Расширенная информация о чате |
data.items[].chat.id |
number | Числовой ID чата |
data.items[].chat.name |
string | Системное название чата |
data.items[].chat.type |
string | Тип чата: chat, general, openlines, copilot, channel, mail, crm и другие |
data.items[].chat.owner |
number | ID владельца чата |
data.items[].chat.userCounter |
number | Количество участников |
data.items[].chat.role |
string | Роль текущего пользователя: OWNER, MANAGER, MEMBER |
data.items[].chat.entityType |
string | Тип связанной сущности (CRM, TASKS, MAIL, GENERAL и другие) |
data.items[].chat.entityId |
string | ID связанной сущности |
data.hasMorePages |
boolean | true, если есть следующая страница |
data.hasMore |
boolean | Дублирует hasMorePages. Сохранён для обратной совместимости |
meta.requestedLimit |
number | Переданный limit до срезания. Присутствует вместе с appliedLimit, только когда переданное значение вышло за диапазон от 1 до 200, когда limit передан в режиме дельты или когда в режиме v2 он меньше 50 или больше 200 |
meta.appliedLimit |
number | Применённое значение limit — только если он был приведён к границе. В режиме дельты приходит при любом переданном limit и равно размеру серверной страницы — 200 |
meta.mode |
string | Значение delta. Приходит только в режиме дельты |
meta.returned |
number | Число диалогов в ответе. Приходит только в режиме дельты |
meta.truncated |
boolean | Приходит со значением true, когда дельту не удалось подтвердить полной: за отданной страницей есть ещё диалоги либо форма ответа не разобрана |
data.recentItems |
array | Режим v2: строки списка в порядке портала — закреплённые первыми, далее по активности |
data.recentItems[].dialogId |
string | Режим v2: ID диалога (chatXXX или ID пользователя) — его принимают загрузка чата и лента сообщений |
data.recentItems[].chatId |
number | Режим v2: ID чата — ключ для снятия повторов. Совпадает с data.chat.id загрузки чата |
data.recentItems[].pinned |
boolean | Режим v2: чат закреплён |
data.recentItems[].dateLastActivity |
string|null | Режим v2: момент последней активности. Наименьшее значение среди незакреплённых строк — курсор следующей страницы |
data.hasNextPage |
boolean | Режим v2: false — конец списка |
В режиме дельты data — массив диалогов с теми же полями элемента, что перечислены выше для data.items. Поля hasMorePages и hasMore в этом режиме не возвращаются, их роль выполняет meta.truncated.
Пример ответа
Постраничный режим:
{
"success": true,
"data": {
"items": [
{
"id": "chat456",
"chatId": 456,
"type": "chat",
"title": "Команда разработки",
"avatar": {
"url": "",
"color": "#4ba984"
},
"message": {
"id": 1201,
"text": "Обновление задачи готово",
"authorId": 1,
"date": "2026-06-03T16:51:12+03:00",
"file": false,
"attach": false,
"sticker": null,
"status": "received"
},
"lastId": 1195,
"pinned": false,
"unread": false,
"counter": 0,
"dateUpdate": "2026-06-03T16:51:12+03:00",
"dateLastActivity": "2026-06-03T16:51:12+03:00",
"chat": {
"id": 456,
"name": "Команда разработки",
"type": "chat",
"owner": 1,
"userCounter": 5,
"role": "OWNER",
"entityType": "",
"entityId": ""
}
},
{
"id": "chat123",
"chatId": 123,
"type": "crm",
"title": "Чат по сделке",
"avatar": {
"url": "",
"color": "#f76187"
},
"message": {
"id": 980,
"text": "Договор согласован",
"authorId": 7,
"date": "2026-06-02T14:08:10+03:00",
"file": false,
"attach": false,
"sticker": null,
"status": "received"
},
"lastId": 0,
"pinned": false,
"unread": false,
"counter": 0,
"dateUpdate": "2026-06-02T14:08:10+03:00",
"dateLastActivity": "2026-06-02T14:08:10+03:00",
"chat": {
"id": 123,
"name": "Чат по сделке",
"type": "crm",
"owner": 1,
"userCounter": 2,
"role": "MEMBER",
"entityType": "CRM",
"entityId": "DEAL|42"
}
}
],
"hasMorePages": true,
"hasMore": true
}
}
Режим дельты. Показаны основные поля элемента, полный набор — в таблице выше:
{
"success": true,
"data": [
{
"id": "chat456",
"chatId": 456,
"type": "chat",
"title": "Команда разработки",
"pinned": false,
"unread": false,
"counter": 0,
"dateUpdate": "2026-06-29T10:12:44+03:00",
"dateLastActivity": "2026-06-29T10:12:44+03:00"
}
],
"meta": {
"mode": "delta",
"returned": 1
}
}
Пример ответа при ошибке
403 — нет скоупа im:
{
"success": false,
"error": {
"code": "SCOPE_DENIED",
"message": "This endpoint requires 'im' scope"
}
}
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_PARAMS |
updatedAfter передан без явного смещения или Z, либо не является датой |
| 400 | INVALID_PARAMS |
updatedAfter передан вместе с offset или lastMessageDate |
| 400 | INVALID_PARAMS |
Режим v2: параметр вне format, limit, lastMessageDate, unreadOnly, повтор параметра, кроме format, нечисловой limit, unreadOnly не true и не false или lastMessageDate не в формате YYYY-MM-DDTHH:MM:SS со смещением или Z либо с несуществующей датой или временем (2026-02-30, 24:00) |
| 403 | SCOPE_DENIED |
API-ключ не имеет скоупа im |
| 401 | TOKEN_MISSING |
API-ключ не имеет настроенных токенов Битрикс24 |
| 422 | BITRIX_ERROR |
Битрикс24 вернул ошибку (подробности в message) |
| 502 | BITRIX_UNAVAILABLE |
Битрикс24 недоступен или вернул ошибку сервера |
Полный список общих ошибок API — Ошибки.
Известные особенности
- Флаги
skipOpenLinesиonlyOpenLinesвзаимоисключающие: включение обоих приводит к результату, при котором ни один из чатов открытых линий не попадёт в список. - В обычном режиме глубокий
offsetпередаётся в Битрикс24. Небольшое окно читается из одной буферной страницы, неполная граничная строка может потребовать один дозапрос. Новая активность между запросами может менять порядок списка. В обычном режиме граница даты включительная: передайтеdateLastActivityпоследнего незакреплённого элемента, не передавайтеoffsetи удаляйте повторы поchatId. Закреплённые строки и строки с той же датой могут повторяться. Если курсор не продвинулся, увеличьтеlimitдо 200. - Ответ содержит поле
data.copilotс конфигурацией AI-ассистента портала. К списку диалогов оно не относится. - В режиме дельты диалог с нечитаемым значением
dateUpdateостаётся в ответе: лишняя запись безопаснее потерянного изменения. - Фильтры семейств
skip*,only*иunreadOnlyдействуют и в режиме дельты, сужая просматриваемую страницу. - В режиме v2 ключи-имена полей приводятся к
camelCase, а ключи-данные остаются как есть: ключи словаряdata.copilot.roles— коды ролей, иcopilot_assistantприходит какcopilot_assistant— тем же значением, чтоroleу чата, поэтому роль находится прямым обращениемroles[role]. - На портале без методов v2 режим отвечает
422 BITRIX_ERRORс кодом портала вerror.b24Codeи не откатывается на прежний ответ молча: форма ответа другая.