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

Channel list

GET /v1/chats/recent/channels

Returns the public channels of the Bitrix24 account page by page, from the channel with the newest message to older ones. Use it to build a directory of channels the user can subscribe to.

Parameters

Parameter Type Required Default Description
limit (query) integer no 50 Rows per page, 1 to 200. A smaller value is raised to 1 and a larger one is clamped to 200, and both adjustments are echoed in meta
lastMessageId (query) integer no — Cursor for the next page: the smallest positive messageId among the rows of the previous page. Not passed on the first page

Other parameters and repeated parameters are rejected with 400 INVALID_PARAMS.

Walk. Rows are ordered by the ID of the channel's last message, from largest to smallest. Request the next page with lastMessageId equal to the smallest positive messageId of the current page. The bound is exclusive: the channel with that messageId is not repeated on the next page. The list ends only at hasNextPage: false. If hasNextPage is true but the page has no row with a positive messageId, repeat the request with a larger limit, up to 200.

Examples

curl — personal key

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

curl — OAuth application

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

JavaScript — personal key

javascript
const channels = []
const seen = new Set()
let limit = 50
let cursor
for (;;) {
  const url = new URL('https://vibecode.bitrix24.com/v1/chats/recent/channels')
  url.searchParams.set('limit', String(limit))
  if (cursor) url.searchParams.set('lastMessageId', String(cursor))
  const res = await fetch(url, { headers: { 'X-Api-Key': 'YOUR_API_KEY' } })
  const { data } = await res.json()
  for (const item of data.recentItems) {
    if (!seen.has(item.chatId)) { seen.add(item.chatId); channels.push(item) }
  }
  if (!data.hasNextPage) break
  const ids = data.recentItems.map((i) => i.messageId).filter((id) => id > 0)
  const next = ids.length ? Math.min(...ids) : undefined
  if (next === undefined || (cursor !== undefined && next >= cursor)) {
    if (limit === 200) throw new Error('Channel 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 channels = []
const seen = new Set()
let limit = 50
let cursor
for (;;) {
  const url = new URL('https://vibecode.bitrix24.com/v1/chats/recent/channels')
  url.searchParams.set('limit', String(limit))
  if (cursor) url.searchParams.set('lastMessageId', String(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) {
    if (!seen.has(item.chatId)) { seen.add(item.chatId); channels.push(item) }
  }
  if (!data.hasNextPage) break
  const ids = data.recentItems.map((i) => i.messageId).filter((id) => id > 0)
  const next = ids.length ? Math.min(...ids) : undefined
  if (next === undefined || (cursor !== undefined && next >= cursor)) {
    if (limit === 200) throw new Error('Channel 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, one per channel
data.recentItems[].dialogId string Dialog ID of the channel, chatXXX
data.recentItems[].chatId number Chat ID of the channel, the deduplication key
data.recentItems[].messageId number ID of the channel's last message, 0 for a channel without messages. The smallest positive value on the page is the cursor for the next one
data.recentItems[].pinned boolean Whether the channel is pinned for the current user. It does not affect the row order
data.recentItems[].dateLastActivity null Always null in this list: channels are ordered by message ID, not by date
data.chats array Channel cards: id, dialogId, name, type, owner, the current user's role and other chat fields
data.messages array The channels' last messages
data.users array Authors of the last messages
data.recentConfigs array The list sections each channel is counted in: chatId and sections
data.hasNextPage boolean false — the end of the list
meta.requestedLimit number The limit passed. Returned together with appliedLimit, and only when the value was outside the range of 1 to 200
meta.appliedLimit number The limit applied

Response example

The main fields are shown:

JSON
{
  "success": true,
  "data": {
    "recentItems": [
      {
        "dialogId": "chat206",
        "chatId": 206,
        "messageId": 329393,
        "type": "chat",
        "pinned": false,
        "unread": false,
        "dateUpdate": null,
        "dateLastActivity": null
      },
      {
        "dialogId": "chat2",
        "chatId": 2,
        "messageId": 0,
        "type": "chat",
        "pinned": false,
        "unread": false,
        "dateUpdate": null,
        "dateLastActivity": null
      }
    ],
    "chats": [
      {
        "id": 206,
        "dialogId": "chat206",
        "name": "Company news",
        "type": "openChannel",
        "owner": 4,
        "role": "guest"
      }
    ],
    "messages": [
      {
        "id": 329393,
        "chatId": 206,
        "authorId": 4,
        "date": "2026-09-10T09:15:00+00:00",
        "text": "Quarterly results are published"
      }
    ],
    "recentConfigs": [
      { "chatId": 206, "sections": ["default", "openChannel", "channel"] }
    ],
    "hasNextPage": false
  }
}

Error response example

400 — the cursor is not a positive number:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "`lastMessageId` must be an integer, 1 or more — the smallest positive `messageId` among the rows of the previous page."
  }
}

Errors

HTTP Code Description
400 INVALID_PARAMS A parameter other than limit and lastMessageId, a repeated parameter, a non-numeric limit, or lastMessageId less than 1. 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 list holds all public channels of the Bitrix24 account, not only yours. Channels the user is not a member of are returned too, with the guest role in data.chats[].role.

Channels without messages come last. Their messageId is 0, and they do not serve as a cursor. If such channels do not fit on one page of 200 rows, the walk cannot continue past them: the next page would have no cursor.

See also