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

List pinned messages

GET /v1/chats/:dialogId/pins

Returns a paginated list of messages pinned in a group chat or a personal dialog.

Parameters

Parameter Type Required Default Description
dialogId (path) string yes — Dialog ID: numeric user ID for personal messages, chatXXX for group chats — the dialogId field of a recent dialogs row; a user ID comes from the user list. The special me alias is the current user's personal dialog — see the Chats overview
lastId (query) number no — Cursor: the id of the last pin of the previous page — a pin ID, not a message ID. The boundary itself is not included
order (query) string no desc desc — latest pins first, asc — earliest first
limit (query) number no 50 Pins per page, from 1 to 200: a value outside the range is clamped and echoed in meta.requestedLimit and meta.appliedLimit

Any other parameter or a repeated parameter is rejected with 400 INVALID_PARAMS.

Examples

curl — personal key

Terminal
curl -X GET "https://vibecode.bitrix24.com/v1/chats/chat42/pins" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth application

Terminal
curl -X GET "https://vibecode.bitrix24.com/v1/chats/chat42/pins" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/chat42/pins', {
  method: 'GET',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})

const { data } = await res.json()
const byId = new Map((data.additionalMessages ?? []).map((m) => [m.id, m]))
console.log('Pinned:', data.pins.map((p) => byId.get(p.messageId)?.text))

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/chats/chat42/pins', {
  method: 'GET',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { data } = await res.json()
const byId = new Map((data.additionalMessages ?? []).map((m) => [m.id, m]))
console.log('Pinned:', data.pins.map((p) => byId.get(p.messageId)?.text))

Response fields

Field Type Description
success boolean Always true on success
data.pins array Pins on the page
data.pins[].id number Pin ID — the lastId cursor for the next page
data.pins[].messageId number ID of the pinned message
data.pins[].chatId number Chat ID
data.pins[].authorId number ID of the user who pinned the message
data.pins[].dateCreate string When the message was pinned (ISO 8601)
data.additionalMessages array The pinned messages: id, chatId, authorId, date, text, params and other v2 message fields
data.users array Users referenced by the pins and messages
data.files array Files of the pinned messages
data.reactions array Reactions to the pinned messages
data.tariffRestrictions object Plan restrictions on history: isHistoryLimitExceeded
meta.requestedLimit number The limit you passed, when it fell outside the 1 to 200 range
meta.appliedLimit number The limit value applied — only when it was clamped to a bound

Also returned are stickers, forwardSource and copilot — v2 feed collections shared by responses that carry messages.

Response example

The main user fields are shown.

JSON
{
  "success": true,
  "data": {
    "users": [
      {
        "id": 5,
        "active": true,
        "name": "Anna Smith",
        "firstName": "Anna",
        "lastName": "Smith",
        "avatar": "",
        "bot": false,
        "type": "user"
      }
    ],
    "additionalMessages": [
      {
        "id": 1001,
        "chatId": 42,
        "authorId": 5,
        "date": "2026-10-06T09:18:11+00:00",
        "text": "Please review the home page mockup",
        "isSystem": false,
        "uuid": null,
        "forward": null,
        "params": { "isPinned": "Y" },
        "viewedByOthers": false,
        "block": null,
        "unread": false,
        "viewed": true,
        "viewedCount": 0
      }
    ],
    "tariffRestrictions": { "isHistoryLimitExceeded": false },
    "forwardSource": null,
    "files": [],
    "copilot": null,
    "stickers": [],
    "reactions": [],
    "pins": [
      {
        "id": 1,
        "messageId": 1001,
        "chatId": 42,
        "authorId": 5,
        "dateCreate": "2026-10-06T09:18:20+00:00"
      }
    ]
  }
}

Error response example

422 — there is no such chat:

JSON
{
  "success": false,
  "error": {
    "code": "BITRIX_ERROR",
    "message": "CHAT_NOT_FOUND",
    "hint": "dialogId must be a userId (number as string) for DMs or \"chat{N}\" for group chats. Examples: \"1\" for user 1, \"chat123\" for group chat 123. Create a group chat first via POST /v1/bots/:botId/chats if needed.",
    "b24Code": "CHAT_NOT_FOUND"
  }
}

Errors

HTTP Code Description
400 INVALID_PARAMS A parameter other than lastId, order, limit, a repeated parameter or an invalid value. Checked before any call to Bitrix24
404 ENTITY_NOT_FOUND Bitrix24 reported "not found"; the portal code is in error.b24Code
422 BITRIX_ERROR Bitrix24 returned an error; the code is in error.b24Code, for example CHAT_NOT_FOUND — there is no such chat
403 SCOPE_DENIED The API key does not have the im scope
403 WRITE_BLOCKED_READONLY_KEY Read-only mode: the existing chat was not confirmed within the bounded window of recent dialogs, or a creating or ambiguous alias was passed. The method that would create a chat is not sent to the Bitrix24 account
403 WRITE_BLOCKED_READONLY_KEY In READONLY mode, this read is not available to an application key, a management key or a key whose owner type is unconfirmed
401 TOKEN_MISSING The API key has no Bitrix24 tokens configured
502 ME_ALIAS_RESOLUTION_FAILED The me alias could not be resolved: Bitrix24 returned no ID of the current user

Full list of common API errors — Errors.

Known specifics

The pins list may make you a member. When the chat allows auto-join, reading the list may add the current user as a member, as loading a chat does. This read is available to an ordinary employee's personal key in READONLY mode. It does not mark messages as read.

There is no next-page flag. The response has no hasNextPage. A page shorter than limit is the last one.

A response without pins is shorter. For a chat without pins, only pins, users and tariffRestrictions are returned. The other collections appear with the first pin, so read them with a fallback value.

See also