For AI agents: markdown of this page — /docs-content-en/chats/discovery/recent-collabs.md documentation index — /llms.txt

Collab list

GET /v1/chats/recent/collabs

Returns the current user's collab chats page by page: pinned ones first, then by last activity time. Use it for a separate collab tab in the dialog list.

Parameters

Parameter Type Required Default Description
limit (query) integer no 50 Rows per page, 50 to 200. A smaller value is raised to 50 and a larger one is clamped to 200, both echoed in meta
lastMessageDate (query) string no — Cursor of the next page: the smallest dateLastActivity among the unpinned rows of the previous page. Format YYYY-MM-DDTHH:MM:SS with an offset or Z, without fractional seconds. Not passed on the first page

Other parameters and repeated parameters are rejected with 400 INVALID_PARAMS.

Walk — as in recent dialogs in the v2 mode. The cursor of the next page is the smallest non-empty dateLastActivity among the unpinned rows; compare instants, not strings. The bound is inclusive, and pinned chats appear at the top of every page, so deduplicate by chatId. The list ends only at hasNextPage: false. If hasNextPage is true but there is no cursor or it equals the previous one, repeat the request with a larger limit, up to 200. Do not discard response rows: the cursor is computed over the whole response.

Examples

curl — personal key

Terminal
curl "https://vibecode.bitrix24.com/v1/chats/recent/collabs?limit=50" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth application

Terminal
curl "https://vibecode.bitrix24.com/v1/chats/recent/collabs?limit=50" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"

JavaScript — personal key

javascript
const rows = new Map()
let limit = 50
let cursor
for (;;) {
  const url = new URL('https://vibecode.bitrix24.com/v1/chats/recent/collabs')
  url.searchParams.set('limit', String(limit))
  if (cursor) url.searchParams.set('lastMessageDate', cursor)
  const res = await fetch(url, { headers: { 'X-Api-Key': 'YOUR_API_KEY' } })
  const { data } = await res.json()
  for (const item of data.recentItems) rows.set(item.chatId, item)
  if (!data.hasNextPage) break
  const dates = data.recentItems.filter((i) => !i.pinned && i.dateLastActivity).map((i) => i.dateLastActivity)
  const next = dates.length ? dates.reduce((a, b) => (Date.parse(a) <= Date.parse(b) ? a : b)) : undefined
  if (!next || (cursor && Date.parse(next) >= Date.parse(cursor))) {
    if (limit === 200) throw new Error('Recent-list cursor did not advance; restart with a full refresh')
    limit = Math.min(limit * 2, 200)
    continue
  }
  cursor = next
  limit = 50
}

JavaScript — OAuth application

javascript
const rows = new Map()
let limit = 50
let cursor
for (;;) {
  const url = new URL('https://vibecode.bitrix24.com/v1/chats/recent/collabs')
  url.searchParams.set('limit', String(limit))
  if (cursor) url.searchParams.set('lastMessageDate', cursor)
  const res = await fetch(url, {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  })
  const { data } = await res.json()
  for (const item of data.recentItems) rows.set(item.chatId, item)
  if (!data.hasNextPage) break
  const dates = data.recentItems.filter((i) => !i.pinned && i.dateLastActivity).map((i) => i.dateLastActivity)
  const next = dates.length ? dates.reduce((a, b) => (Date.parse(a) <= Date.parse(b) ? a : b)) : undefined
  if (!next || (cursor && Date.parse(next) >= Date.parse(cursor))) {
    if (limit === 200) throw new Error('Recent-list cursor did not advance; restart with a full refresh')
    limit = Math.min(limit * 2, 200)
    continue
  }
  cursor = next
  limit = 50
}

Response fields

Field Type Description
success boolean Always true on success
data.recentItems array List rows in the order Bitrix24 returns them: pinned first, then by activity
data.recentItems[].dialogId string Dialog ID of the collab, chatXXX
data.recentItems[].chatId number Chat ID, the deduplication key
data.recentItems[].messageId number ID of the last message
data.recentItems[].pinned boolean The chat is pinned for the current user
data.recentItems[].unread boolean The chat is manually marked as unread
data.recentItems[].dateLastActivity string|null Instant of the last activity. The smallest value among the unpinned rows is the cursor of the next page
data.chats array Collab chat cards: id, dialogId, name, type with the value collab, entityType with the value SONET_GROUP, entityId — the group ID, the current user's role and other chat fields
data.messages array The chats' last messages
data.users array Authors of the last messages
data.recentConfigs array The list sections each chat counts in: chatId and sections
data.hasNextPage boolean false — the end of the list
meta.requestedLimit number The limit passed. It arrives together with appliedLimit, only when the value was outside the range of 50 to 200
meta.appliedLimit number The limit applied

Response example

The main fields are shown; limit=10 is raised to 50:

JSON
{
  "success": true,
  "data": {
    "recentItems": [
      {
        "dialogId": "chat53",
        "chatId": 53,
        "messageId": 413,
        "type": "chat",
        "pinned": false,
        "unread": false,
        "dateUpdate": "2026-06-15T12:31:26+00:00",
        "dateLastActivity": "2026-04-21T10:55:53+00:00"
      }
    ],
    "chats": [
      {
        "id": 53,
        "dialogId": "chat53",
        "name": "Partner program launch",
        "type": "collab",
        "entityType": "SONET_GROUP",
        "entityId": "3",
        "owner": 1,
        "role": "owner"
      }
    ],
    "recentConfigs": [
      { "chatId": 53, "sections": ["default", "collab"] }
    ],
    "hasNextPage": false
  },
  "meta": {
    "requestedLimit": 10,
    "appliedLimit": 50
  }
}

Error response example

400 — the cursor has no offset:

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

Errors

HTTP Code Description
400 INVALID_PARAMS A parameter other than limit and lastMessageDate, a repeated parameter, a non-numeric limit, or lastMessageDate not in the YYYY-MM-DDTHH:MM:SS format with an offset or Z, or with a nonexistent date or time (2026-02-30, 24:00). Checked before the Bitrix24 call
422 BITRIX_ERROR Bitrix24 returned an error; the Bitrix24 code is in error.b24Code
403 BITRIX_ACCESS_DENIED Bitrix24 denied access
403 SCOPE_DENIED The API key does not have the im scope
401 TOKEN_MISSING The API key has no Bitrix24 tokens configured
502 BITRIX_UNAVAILABLE Bitrix24 is unavailable or returned a server error

Full list of common API errors — Errors.

Known specifics

The limit floor is 50. A user can have up to 45 pinned chats, and they repeat on every page. A page smaller than 50 rows could consist of repeats only and give no cursor.

A walk is not a snapshot. A collab lifted above the cursor by new activity during the walk does not appear in it. Re-read the first page after the walk.

See also