For AI agents: markdown of this page — /docs-content-en/chats/discovery/folder-recent.md documentation index — /llms.txt
Folder chats
GET /v1/chats/folders/:folderId/recent
Returns the recent dialog list of one folder — the v2 messenger method im.v2.Folder.Recent.tail. Folders and their IDs come from GET /v1/chats/folders. The response and paging work the same way as in the recent dialog list in the v2 mode: data holds the v2 object — recentItems and the chats, users, messages, files collections — with keys in camelCase.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
folderId (path) |
number | yes | — | Folder ID, a positive integer |
limit (query) |
number | no | 50 | Rows per page, from 50 to 200: a smaller value is raised to 50, a larger one is clamped to 200, both echoed in meta.requestedLimit and meta.appliedLimit |
lastMessageDate (query) |
string | no | — | Cursor of the next page, format YYYY-MM-DDTHH:MM:SS with an offset or Z, no fractional seconds. Not sent on the first page |
unreadOnly (query) |
boolean | no | false |
true — only chats with unread messages. Personal folders ignore this filter |
Other parameters and repeated parameters are rejected with 400 INVALID_PARAMS.
Paging. The cursor of the next page is the smallest non-empty dateLastActivity among the unpinned rows of the current page; compare moments in time, not strings. The bound is inclusive. Only hasNextPage: false marks the end of the list. 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; true without progress even at 200 is a failure, not the end of the list. The response contains repeated rows: pinned rows come first on a page — on the first page in a system folder, and on the following pages as well in a personal folder — and the all-chats folder mixes in colleagues the user has not chatted with yet. Deduplicate by dialogId.
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/chats/folders/1/recent?limit=200" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/chats/folders/1/recent?limit=200" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
// Full walk of a folder in pages of 200 rows
const seen = new Map()
let cursor = null
for (;;) {
const qs = new URLSearchParams({ limit: '200' })
if (cursor) qs.set('lastMessageDate', cursor)
const res = await fetch(`https://vibecode.bitrix24.com/v1/chats/folders/1/recent?${qs}`, {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data } = await res.json()
for (const row of data.recentItems) seen.set(row.dialogId, row)
if (!data.hasNextPage) break
const dates = data.recentItems
.filter((r) => !r.pinned && r.dateLastActivity)
.map((r) => r.dateLastActivity)
const next = dates.sort((a, b) => Date.parse(a) - Date.parse(b))[0]
// At limit=200 a cursor without progress is a failure, not the end of the list
if (!next || (cursor && Date.parse(next) === Date.parse(cursor))) throw new Error('The cursor did not advance')
cursor = next
}
console.log('Chats in the folder:', seen.size)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/folders/1/recent?limit=200', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.recentItems |
array | List rows: pinned first, then by activity |
data.recentItems[].dialogId |
string | Dialog ID (chatXXX or a user ID) — the deduplication key |
data.recentItems[].chatId |
number | Chat ID |
data.recentItems[].messageId |
number | ID of the last message |
data.recentItems[].pinned |
boolean | Whether the chat is pinned in the folder |
data.recentItems[].unread |
boolean | The "unread" mark — see unread mark |
data.recentItems[].dateLastActivity |
string | null | Moment of the last activity; the smallest value among unpinned rows is the cursor of the next page |
data.chats |
array | Chats referenced by the rows |
data.users |
array | Users referenced by the rows |
data.messages |
array | Last messages of the rows |
data.files |
array | Files of the last messages |
data.hasNextPage |
boolean | false — the end of the list |
meta.requestedLimit |
number | The limit that was sent. Arrives together with appliedLimit, only when the value is below 50 or above 200 |
meta.appliedLimit |
number | The applied limit value |
Response example
{
"success": true,
"data": {
"recentItems": [
{
"dialogId": "chat42",
"chatId": 42,
"messageId": 1002,
"type": "chat",
"pinned": false,
"unread": false,
"options": [],
"invited": false,
"lastReadMessageId": 1002,
"dateUpdate": "2026-09-20T10:01:00+00:00",
"dateLastActivity": "2026-09-20T10:01:00+00:00",
"ownMessageId": 1001
}
],
"chats": [
{ "id": 42, "dialogId": "chat42", "name": "Project", "type": "chat", "owner": 5, "role": "member" }
],
"users": [
{ "id": 7, "active": true, "name": "John Brown", "firstName": "John", "lastName": "Brown", "type": "user" }
],
"messages": [
{ "id": 1002, "chatId": 42, "authorId": 7, "date": "2026-09-20T10:01:00+00:00", "text": "The mockup is ready" }
],
"files": [],
"hasNextPage": false
}
}
Error response example
422 — the folder does not exist:
{
"success": false,
"error": {
"code": "BITRIX_ERROR",
"message": "FOLDER_NOT_FOUND",
"b24Code": "FOLDER_NOT_FOUND"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
folderId is not a positive integer; a parameter other than limit, lastMessageDate or unreadOnly; a repeated parameter; a non-numeric limit; an unreadOnly that is neither true nor false; or a lastMessageDate that is not in the YYYY-MM-DDTHH:MM:SS format with an offset or Z, or that names a date or time that does not exist. Checked before any call to Bitrix24 |
| 403 | SCOPE_DENIED |
The API key does not have the im scope |
| 401 | TOKEN_MISSING |
The API key has no Bitrix24 tokens configured |
| 404 | ENTITY_NOT_FOUND |
Bitrix24 answered "not found"; the portal code is in error.b24Code |
| 422 | BITRIX_ERROR |
Bitrix24 returned an error; the portal code is in error.b24Code: FOLDER_NOT_FOUND — no such folder, FOLDER_ACCESS_DENIED — the folder belongs to another user, FOLDER_OPERATION_NOT_SUPPORTED — the folder has no chat list (the public channel showcase) or the section is not available to the user |
| 502 | BITRIX_UNAVAILABLE |
Bitrix24 is unavailable or returned a server error |
Full list of common API errors — Errors.
Known specifics
- Personal folders ignore
unreadOnly. This is Bitrix24 behaviour: a personal folder's list is built from the chats added to it, without the unread filter, sounreadOnly=truereturns all of its chats. To find the unread chats of a personal folder, use the counters: they carry the unread count and the "unread" mark for every chat. - The Bitrix24 code
FOLDER_NOT_FOUNDreturned by this endpoint arrives as422 BITRIX_ERRORwitherror.b24Codeand is not the same as the Vibecode code404 FOLDER_NOT_FOUND, which refers to the chat folder on Drive. - The call only reads: its argument is a folder, not a chat, so it does not make anyone a chat member, and a read-only key can run it.
- A walk is not a snapshot: a chat that new activity lifts above the cursor during the walk does not appear in it, so re-read the first page after the walk.