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

External chats of a section

GET /v1/chats/recent/external

Returns one section of the current user's chat list: the chats that other Bitrix24 modules create, such as task chats or calendar event chats. Ordering and paging work as in recent dialogs: pinned ones first, then by the time of the last activity.

Parameters

Parameter Type Required Default Description
Parametertype (query) Typestring Requiredyes Default— DescriptionSection code: a Latin letter, then letters, digits or _, up to 64 characters. tasksTask — task chats, calendar — calendar event chats. The sections a chat is counted in are listed in the recentSections field of the unread counters
Parameterlimit (query) Typeinteger Requiredno Default50 DescriptionRows per page, 50 to 200. A smaller value is raised to 50 and a larger one is clamped to 200, and both adjustments are echoed in meta
ParameterlastMessageDate (query) Typestring Requiredno Default— DescriptionCursor 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. The default and collab sections are not read here, as they have their own endpoints: the common list — recent dialogs in the v2 mode, collabs — collab list.

Pagination — 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/external?type=tasksTask&limit=50" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth application

Terminal
curl "https://vibecode.bitrix24.com/v1/chats/recent/external?type=tasksTask&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/external')
  url.searchParams.set('type', 'tasksTask')
  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/external')
  url.searchParams.set('type', 'tasksTask')
  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
Fieldsuccess Typeboolean DescriptionAlways true on success
Fielddata.recentItems Typearray DescriptionSection rows in the order Bitrix24 returns them: pinned ones first, then by activity
Fielddata.recentItems[].dialogId Typestring DescriptionDialog ID, chatXXX
Fielddata.recentItems[].chatId Typenumber DescriptionChat ID, the deduplication key
Fielddata.recentItems[].messageId Typenumber DescriptionID of the last message
Fielddata.recentItems[].pinned Typeboolean DescriptionThe chat is pinned for the current user
Fielddata.recentItems[].unread Typeboolean DescriptionThe chat is manually marked as unread
Fielddata.recentItems[].dateLastActivity Typestring|null DescriptionInstant of the last activity. The smallest value among the unpinned rows is the cursor of the next page
Fielddata.chats Typearray DescriptionChat cards: id, dialogId, name, type — the same section code, entityType and entityId — the linked entity, entityLink.url — its address in Bitrix24, the current user's role and other chat fields
Fielddata.messages Typearray DescriptionThe chats' last messages
Fielddata.users Typearray DescriptionAuthors of the last messages
Fielddata.recentConfigs Typearray DescriptionThe list sections each chat is counted in: chatId and sections
Fielddata.hasNextPage Typeboolean Descriptionfalse — the end of the section
Fieldmeta.requestedLimit Typenumber DescriptionThe limit passed. Present together with appliedLimit only when the value was outside the range of 50 to 200
Fieldmeta.appliedLimit Typenumber DescriptionThe limit applied — only when it was clamped to a bound

Response example

The tasksTask section, with the main fields shown:

JSON
{
  "success": true,
  "data": {
    "recentItems": [
      {
        "dialogId": "chat264388",
        "chatId": 264388,
        "messageId": 608251,
        "type": "chat",
        "pinned": false,
        "unread": false,
        "dateUpdate": "2026-09-11T12:53:10+00:00",
        "dateLastActivity": "2026-09-11T12:53:10+00:00"
      }
    ],
    "chats": [
      {
        "id": 264388,
        "dialogId": "chat264388",
        "name": "Prepare the release",
        "type": "tasksTask",
        "entityType": "TASKS_TASK",
        "entityId": "27",
        "owner": 1,
        "role": "owner"
      }
    ],
    "recentConfigs": [
      { "chatId": 264388, "sections": ["tasksTask"] }
    ],
    "hasNextPage": false
  }
}

Error response example

400 — the common list is requested:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "`type` default is not an external-chat section — read it through GET /v1/chats/recent?format=v2."
  }
}

Errors

HTTP Code Description
HTTP400 CodeINVALID_PARAMS DescriptionNo type, type is not a section code, or type is default or collab — the message names the right endpoint. Also a parameter other than type, limit, 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. Checked before the Bitrix24 call
HTTP422 CodeBITRIX_ERROR DescriptionBitrix24 returned an error; the Bitrix24 code is in error.b24Code
HTTP403 CodeBITRIX_ACCESS_DENIED DescriptionBitrix24 denied access
HTTP403 CodeSCOPE_DENIED DescriptionThe API key does not have the im scope
HTTP401 CodeTOKEN_MISSING DescriptionThe API key has no Bitrix24 tokens configured
HTTP502 CodeBITRIX_UNAVAILABLE DescriptionBitrix24 is unavailable or returned a server error

Full list of common API errors — Errors.

Known specifics

An unknown section is an empty list, not an error. A code that does not exist in the Bitrix24 account returns 200 with an empty recentItems and hasNextPage: false. The response does not reveal a typo in type: check the code against the recentSections field of the unread counters.

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

Pagination does not give a snapshot. A chat lifted above the cursor by new activity during pagination does not appear in the results. Re-read the first page after pagination.

See also