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
curl "https://vibecode.bitrix24.com/v1/chats/recent/channels?limit=50" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
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
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
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:
{
"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:
{
"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.