Для AI-агентов: markdown этой страницы — /docs-content/chats/discovery/sync.md индекс документации — /llms.txt

Изменения чатов с момента

GET /v1/chats/sync

Возвращает, что изменилось в чатах текущего пользователя начиная с указанного момента: новые и удалённые чаты, новые, изменённые и удалённые сообщения, закрепы. Подходит, чтобы догнать локальную копию чатов после перерыва, не перечитывая весь список.

Параметры

Параметр Тип Обяз. По умолч. Описание
lastDate (query) string да — С какого момента читать изменения. Формат YYYY-MM-DDTHH:MM:SS со смещением или Z, без долей секунды. Для следующей страницы — navigationData.lastServerDate предыдущей
lastId (query) integer нет — navigationData.lastId предыдущей страницы, не меньше 0. На первой странице не передаётся
limit (query) integer нет 50 Записей журнала изменений на странице, от 1 до 200. Меньшее значение поднимается до 1, большее срезается до 200, оба раза с эхом в meta

Другие параметры и повторы отклоняются с 400 INVALID_PARAMS.

Обход. Первую страницу запрашивайте с lastDate — моментом, до которого копия актуальна. Пока navigationData.hasMore равен true, запрашивайте следующую с lastDate, равным navigationData.lastServerDate, и lastId, равным navigationData.lastId. Пару lastServerDate и lastId последней страницы сохраните — с неё начнётся следующая синхронизация.

Примеры

curl — личный ключ

Terminal
curl "https://vibecode.bitrix24.tech/v1/chats/sync?lastDate=2026-09-24T10:00:00Z&limit=200" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth-приложение

Terminal
curl "https://vibecode.bitrix24.tech/v1/chats/sync?lastDate=2026-09-24T10:00:00Z&limit=200" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"

JavaScript — личный ключ

javascript
let lastDate = '2026-09-24T10:00:00Z'
let lastId
const added = new Set()
for (;;) {
  const url = new URL('https://vibecode.bitrix24.tech/v1/chats/sync')
  url.searchParams.set('lastDate', lastDate)
  url.searchParams.set('limit', '200')
  if (lastId !== undefined) url.searchParams.set('lastId', String(lastId))
  const res = await fetch(url, { headers: { 'X-Api-Key': 'YOUR_API_KEY' } })
  const { data } = await res.json()
  if (Array.isArray(data)) throw new Error('Incremental sync is unavailable; refresh the full recent-chat list')
  for (const id of Object.values(data.messageSync.addedMessages)) added.add(id)
  lastDate = data.navigationData.lastServerDate
  lastId = data.navigationData.lastId
  if (!data.navigationData.hasMore) break
}

JavaScript — OAuth-приложение

javascript
let lastDate = '2026-09-24T10:00:00Z'
let lastId
const added = new Set()
for (;;) {
  const url = new URL('https://vibecode.bitrix24.tech/v1/chats/sync')
  url.searchParams.set('lastDate', lastDate)
  url.searchParams.set('limit', '200')
  if (lastId !== undefined) url.searchParams.set('lastId', String(lastId))
  const res = await fetch(url, {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  })
  const { data } = await res.json()
  if (Array.isArray(data)) throw new Error('Incremental sync is unavailable; refresh the full recent-chat list')
  for (const id of Object.values(data.messageSync.addedMessages)) added.add(id)
  lastDate = data.navigationData.lastServerDate
  lastId = data.navigationData.lastId
  if (!data.navigationData.hasMore) break
}

Поля ответа

Поле Тип Описание
success boolean Всегда true при успехе
data.chatSync.addedRecent object Чаты, появившиеся в списке диалогов: ключ и значение — ID чата
data.chatSync.addedChats object Чаты, которые появились или изменились у пользователя: ключ и значение — ID чата
data.chatSync.deletedChats object Чаты, убранные из списка диалогов пользователя: ключ и значение — ID чата
data.chatSync.completeDeletedChats object Чаты, удалённые с портала: ключ и значение — ID чата
data.chatSync.readAllChats boolean Приходит со значением true, если за это время пользователь прочитал все чаты: сбросьте счётчики непрочитанного в локальной копии
data.messageSync.addedMessages object Новые сообщения: ключ и значение — ID сообщения
data.messageSync.updatedMessages object Изменённые сообщения: ключ и значение — ID сообщения
data.messageSync.completeDeletedMessages object Удалённые сообщения: ключ и значение — ID сообщения
data.pinSync.addedPins object Новые закреплённые сообщения: ключ и значение — ID закрепа
data.pinSync.deletedPins object Снятые закрепы сообщений: ключ и значение — ID закрепа
data.userSync object Изменения пользователей: updatedUsers и deletedUsers
data.chats array Карточки чатов из chatSync
data.messages array Сообщения из messageSync
data.pins array Закрепы сообщений из pinSync: id, messageId, chatId, authorId, dateCreate
data.recentItems array Строки списка диалогов для чатов из chatSync
data.users array Пользователи, упомянутые в изменениях
data.dialogIds object Соответствие ID чата и ID диалога: ключ — ID чата, значение — dialogId
data.navigationData.lastServerDate string lastDate для следующей страницы — момент последней записи журнала на этой странице
data.navigationData.lastId number lastId для следующей страницы
data.navigationData.hasMore boolean true — есть следующая страница
meta.requestedLimit number Переданный limit. Приходит вместе с appliedLimit, только когда значение вышло за диапазон от 1 до 200
meta.appliedLimit number Применённый limit — только если он был приведён к границе

Пример ответа

Показаны основные поля:

JSON
{
  "success": true,
  "data": {
    "chatSync": {
      "addedRecent": { "264431": 264431 },
      "addedChats": { "264431": 264431 },
      "deletedChats": { "264418": 264418 },
      "completeDeletedChats": []
    },
    "messageSync": {
      "addedMessages": { "609001": 609001 },
      "updatedMessages": [],
      "completeDeletedMessages": []
    },
    "pinSync": {
      "addedPins": [],
      "deletedPins": []
    },
    "userSync": {
      "updatedUsers": [],
      "deletedUsers": []
    },
    "messages": [
      {
        "id": 609001,
        "chatId": 264431,
        "authorId": 1,
        "date": "2026-09-24T21:10:22+00:00",
        "text": "Черновик плана готов"
      }
    ],
    "chats": [
      {
        "id": 264431,
        "dialogId": "chat264431",
        "name": "Подготовка релиза",
        "type": "chat"
      }
    ],
    "dialogIds": { "264431": "chat264431" },
    "navigationData": {
      "lastServerDate": "2026-09-24T21:10:22+00:00",
      "hasMore": false,
      "lastId": 182091
    }
  }
}

Пример ответа при ошибке

400 — дата без смещения:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "`lastDate` must be a datetime YYYY-MM-DDTHH:MM:SS with a UTC offset (+03:00) or Z and no fractional seconds — `navigationData.lastServerDate` of the previous page."
  }
}

Ошибки

HTTP Код Описание
400 INVALID_PARAMS Нет lastDate, lastDate не в формате YYYY-MM-DDTHH:MM:SS со смещением или Z либо с несуществующей датой или временем (2026-02-30, 24:00), lastId меньше 0, нечисловой limit, параметр вне lastDate, lastId, limit или повтор параметра. Проверяется до обращения к Битрикс24
422 BITRIX_ERROR Битрикс24 вернул ошибку, код портала — в error.b24Code
403 BITRIX_ACCESS_DENIED Битрикс24 отказал в доступе
403 SCOPE_DENIED API-ключ не имеет скоупа im
401 TOKEN_MISSING API-ключ не имеет настроенных токенов Битрикс24
502 BITRIX_UNAVAILABLE Битрикс24 недоступен или вернул ошибку сервера

Полный список общих ошибок API — Ошибки.

Известные особенности

Пустая коллекция приходит массивом. Когда в группе изменений нет записей, вместо объекта приходит пустой массив: "updatedMessages": []. Читайте такие поля через Object.values, он одинаково работает с обоими видами.

Инкрементальный журнал не гарантирует четыре недели истории. Часть записей Битрикс24 хранится лишь около суток. После долгого перерыва, особенно близкого к суткам, перечитайте последние диалоги и нужную историю сообщений целиком, прежде чем доверять новой дельте.

Синхронизация может быть выключена на портале. Тогда data — пустой массив, а не объект с полями выше. В этом случае перечитывайте список целиком.

Это не события в реальном времени. Эндпоинт отвечает на вопрос «что изменилось с момента», а новые сообщения по мере появления приходят через опрос событий.

Смотрите также