## Чаты папки

`GET /v1/chats/folders/:folderId/recent`

Возвращает список последних диалогов одной папки. Папки и их ID — в [`GET /v1/chats/folders`](/docs/chats/discovery/folders). Ответ и постраничный обход устроены так же, как у [списка последних диалогов в режиме v2](/docs/chats/discovery/recent): в `data` приходит объект v2 — `recentItems` и коллекции `chats`, `users`, `messages`, `files` — с ключами в формате `camelCase`.

## Параметры

| Параметр | Тип | Обяз. | По умолч. | Описание |
|----------|-----|:-----:|-----------|---------|
| `folderId` (path) | number | да | — | ID папки, положительное целое |
| `limit` (query) | number | нет | 50 | Строк на странице, от 50 до 200: меньшее значение поднимается до 50, большее срезается до 200, оба раза с эхом в `meta.requestedLimit` и `meta.appliedLimit` |
| `lastMessageDate` (query) | string | нет | — | Курсор следующей страницы, формат `YYYY-MM-DDTHH:MM:SS` со смещением или `Z`, без долей секунды. На первой странице не передаётся |
| `unreadOnly` (query) | boolean | нет | `false` | `true` — только чаты с непрочитанным. Личная папка этот фильтр не применяет |

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

**Обход.** Курсор следующей страницы — наименьшая непустая `dateLastActivity` среди **незакреплённых** строк текущей страницы. Сравнивайте моменты времени, а не строки. Граница включительная. Конец списка — только `hasNextPage: false`. Если при `hasNextPage: true` курсора нет или он равен прежнему, повторите запрос с бо́льшим `limit`, вплоть до 200. `true` без продвижения и при 200 — отказ, а не конец списка. Строки в ответе повторяются: закреплённые открывают страницы — у системной папки первую, у личной и следующие, — а папка всех чатов подмешивает коллег, с которыми ещё нет переписки. Повторы снимайте по `dialogId`.

## Примеры

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

```bash
curl "https://vibecode.bitrix24.tech/v1/chats/folders/1/recent?limit=200" \
  -H "X-Api-Key: YOUR_API_KEY"
```

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

```bash
curl "https://vibecode.bitrix24.tech/v1/chats/folders/1/recent?limit=200" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

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

```javascript
// Полный обход папки страницами по 200 строк
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.tech/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]
  // При limit=200 курсор без продвижения — отказ, а не конец списка
  if (!next || (cursor && Date.parse(next) === Date.parse(cursor))) throw new Error('Курсор не продвинулся')
  cursor = next
}
console.log('Чатов в папке:', seen.size)
```

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

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/chats/folders/1/recent?limit=200', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { data } = await res.json()
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|---------|
| `success` | boolean | Всегда `true` при успехе |
| `data.recentItems` | array | Строки списка: закреплённые первыми, далее по активности |
| `data.recentItems[].dialogId` | string | ID диалога (`chatXXX` или ID пользователя) — ключ для снятия повторов |
| `data.recentItems[].chatId` | number | ID чата |
| `data.recentItems[].messageId` | number | ID последнего сообщения |
| `data.recentItems[].pinned` | boolean | Чат закреплён в папке |
| `data.recentItems[].unread` | boolean | Метка «непрочитано», см. [Поставить метку «непрочитано»](/docs/chats/management/unread-create) |
| `data.recentItems[].dateLastActivity` | string \| null | Момент последней активности. Наименьшее значение среди незакреплённых строк — курсор следующей страницы |
| `data.chats` | array | Чаты строк |
| `data.users` | array | Пользователи строк |
| `data.messages` | array | Последние сообщения строк |
| `data.files` | array | Файлы последних сообщений |
| `data.hasNextPage` | boolean | `false` — конец списка |
| `meta.requestedLimit` | number | Переданный `limit`. Приходит вместе с `appliedLimit`, только когда значение меньше 50 или больше 200 |
| `meta.appliedLimit` | number | Применённое значение `limit` — только если он был приведён к границе |

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

```json
{
  "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+03:00",
        "dateLastActivity": "2026-09-20T10:01:00+03:00",
        "ownMessageId": 1001
      }
    ],
    "chats": [
      { "id": 42, "dialogId": "chat42", "name": "Проект", "type": "chat", "owner": 5, "role": "member" }
    ],
    "users": [
      { "id": 7, "active": true, "name": "Иван Петров", "firstName": "Иван", "lastName": "Петров", "type": "user" }
    ],
    "messages": [
      { "id": 1002, "chatId": 42, "authorId": 7, "date": "2026-09-20T10:01:00+03:00", "text": "Макет готов" }
    ],
    "files": [],
    "hasNextPage": false
  }
}
```

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

422 — папки нет:

```json
{
  "success": false,
  "error": {
    "code": "BITRIX_ERROR",
    "message": "FOLDER_NOT_FOUND",
    "b24Code": "FOLDER_NOT_FOUND"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | `folderId` не является положительным целым, параметр вне `limit`, `lastMessageDate` и `unreadOnly`, повтор параметра, нечисловой `limit`, `unreadOnly` не `true` и не `false` или `lastMessageDate` не в формате `YYYY-MM-DDTHH:MM:SS` со смещением или `Z` либо с несуществующей датой или временем. Проверяется до обращения к Битрикс24 |
| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `im` |
| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов Битрикс24 |
| 404 | `ENTITY_NOT_FOUND` | Битрикс24 вернул «не найдено». Код портала — в `error.b24Code` |
| 422 | `BITRIX_ERROR` | Битрикс24 вернул `FOLDER_NOT_FOUND` — папки нет. Код портала — в `error.b24Code` |
| 422 | `BITRIX_ERROR` | Битрикс24 вернул `FOLDER_ACCESS_DENIED` — папка другого пользователя. Код портала — в `error.b24Code` |
| 422 | `BITRIX_ERROR` | Битрикс24 вернул `FOLDER_OPERATION_NOT_SUPPORTED` — у папки нет списка чатов, как у витрины открытых каналов, или раздел недоступен пользователю. Код портала — в `error.b24Code` |
| 502 | `BITRIX_UNAVAILABLE` | Битрикс24 недоступен или вернул ошибку сервера |

Полный список общих ошибок API — [Ошибки](/docs/errors).

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

- **Личная папка не применяет `unreadOnly`.** Это поведение Битрикс24: список личной папки строится из выбранных в неё чатов без фильтра непрочитанного, поэтому с `unreadOnly=true` приходят все её чаты. Непрочитанное в личной папке отбирайте по [счётчикам](/docs/chats/discovery/counters): у них число непрочитанных и метка «непрочитано» по каждому чату.
- Код портала `FOLDER_NOT_FOUND` у этого эндпоинта приходит как `422 BITRIX_ERROR` с `error.b24Code` и не совпадает с кодом API Вайбкод `404 FOLDER_NOT_FOUND` — тот описан на странице [Загрузить файл в чат](/docs/chats/files/upload).
- Вызов только читает: аргумент — папка, а не чат, поэтому участником чата он не делает и ключ только для чтения его выполняет.
- Обход — не снимок: чат, поднятый новой активностью из-под курсора во время обхода, в нём не появится, поэтому после обхода перечитайте первую страницу.

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

- [Папки чатов](/docs/chats/discovery/folders)
- [Последние диалоги](/docs/chats/discovery/recent)
- [Счётчики непрочитанного](/docs/chats/discovery/counters)
- [Поиск чатов](/docs/chats/discovery)
