
## Notification feed

`GET /v1/notifications`

Returns a page of the token owner's notifications together with the unread counter. Pages are traversed with a cursor, and the page size is set by the limit parameter.

## Parameters

| Parameter | Type | Required | Default | Description |
|----------|-----|:-----:|-----------|---------|
| `limit` (query) | number | no | `50` | Page size, from `1` to `50`. Values `0` and above `50` are clamped to the nearest bound, and the original value is returned in `meta.requestedLimit`. A negative, fractional or non-numeric value returns `400 INVALID_LIMIT` |
| `lastId` (query) | number | no | — | The `id` of the last notification on the previous page. Sent only together with `lastType` |
| `lastType` (query) | number | no | — | Traversal stage of the feed: `1` — confirmations, `3` — regular notifications. Sent only together with `lastId` |
| `convertText` (query) | string | no | off | Conversion of the notification text. The values `true`, `1`, `y` turn it on and `false`, `0`, `n` turn it off. The value is case-insensitive |

Send the first request without a cursor — the page starts at the beginning of the feed. For the next page, send the `id` of the last notification in `lastId` together with `lastType`. The traversal order and the end-of-feed indicator are described in the "Known specifics" section.

## Examples

### curl — personal key

```bash
curl "https://vibecode.bitrix24.com/v1/notifications?limit=20" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth application

```bash
curl "https://vibecode.bitrix24.com/v1/notifications?limit=20" \
  -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/notifications?limit=20', {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})

const { data } = await res.json()
console.log('Unread:', data.totalUnreadCount)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/notifications?limit=20', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { data } = await res.json()
console.log('Unread:', data.totalUnreadCount)
```

## Response fields

For all keys, including personal keys, strings containing secret webhook URLs in response fields, including nested fields, are replaced entirely with `[REDACTED]`.

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data.notifications` | array | Notifications on the page |
| `data.notifications[].id` | number, null | Notification identifier. Pass it in `lastId` for the next page and to [`DELETE /v1/notifications/:id`](./delete.md) |
| `data.notifications[].chatId` | number, null | Identifier of the chat this notification belongs to |
| `data.notifications[].authorId` | number, null | Author identifier. The author's card is in the `data.users` array |
| `data.notifications[].date` | string | Notification date in ISO 8601 format |
| `data.notifications[].notifyType` | number, null | Notification type |
| `data.notifications[].notifyModule` | string | Source module of the notification, for example `rest` |
| `data.notifications[].notifyEvent` | string | Source event of the notification |
| `data.notifications[].notifyTag` | string | The `tag` the notification was sent with |
| `data.notifications[].notifySubTag` | string | Additional `subTag` |
| `data.notifications[].notifyTitle` | string | Notification title |
| `data.notifications[].settingName` | string | Name of the delivery setting under which the notification reached the recipient |
| `data.notifications[].text` | string | Notification text |
| `data.notifications[].notifyRead` | boolean | Whether the notification has been read |
| `data.notifications[].notifyButtons` | string | Notification buttons — a JSON string with the array of buttons, as the Bitrix24 account sent it. The value for [pressing a button](./confirm.md) is the part of the button's `COMMAND_PARAMS` after the `\|` character. If the `notifyButtons` string contains a secret webhook URL, it is replaced entirely with `[REDACTED]`; this value is not JSON. The field is absent on a notification without buttons |
| `data.notifications[].params` | object, null | Extra data from the sender. The keys inside are the ones the sending application wrote |
| `data.users` | array | Cards of the authors of the notifications on this page |
| `data.users[].id` | number, null | User identifier. Full card — [Employees](/docs/entities/users) |
| `data.users[].active` | boolean | Whether the user is active in the Bitrix24 account |
| `data.users[].name` | string | Display name |
| `data.users[].firstName` | string | First name |
| `data.users[].lastName` | string | Last name |
| `data.users[].workPosition` | string | Job position |
| `data.users[].color` | string | Color of the user card in the Bitrix24 interface |
| `data.users[].avatar` | string | Avatar link |
| `data.users[].bot` | boolean | Whether the author is a bot |
| `data.users[].type` | string | Author type, for example `user` |
| `data.totalCount` | number | Feed notification counter |
| `data.totalUnreadCount` | number | Unread notification counter |
| `data.chatId` | number, null | Identifier of the system notification chat |
| `data.hasMore` | boolean | `true` when the page is filled up to `meta.appliedLimit` |
| `meta.appliedLimit` | number | Page size the request ran with. Present in every response, including one without `limit` |
| `meta.requestedLimit` | number | The original `limit` value before clamping. Present only when the value was changed |

## Response example

HTTP 200:

```json
{
  "success": true,
  "data": {
    "notifications": [
      {
        "id": 38963,
        "chatId": 3113,
        "authorId": 1297,
        "date": "2026-08-13T09:00:00+00:00",
        "notifyType": 2,
        "notifyModule": "rest",
        "notifyEvent": "rest_notify",
        "notifyTag": "MP|12345|DEAL_1024",
        "notifySubTag": "MP|12345|DEAL|1024",
        "notifyTitle": "",
        "settingName": "rest|rest_notify",
        "text": "Deal #1024 moved to the Paid stage",
        "params": null,
        "notifyRead": false
      },
      {
        "id": 38959,
        "chatId": 3113,
        "authorId": 1,
        "date": "2026-08-13T08:41:12+00:00",
        "notifyType": 1,
        "notifyModule": "calendar",
        "notifyEvent": "invite",
        "notifyTag": "CALENDAR|INVITE|8217|1297",
        "notifySubTag": "CALENDAR|INVITE|8217",
        "notifyTitle": "Invitation to event \"Stand-up\" from John Carter",
        "settingName": "calendar|invite",
        "text": "I would like to invite you to the event \"[B]Stand-up[/B]\". The said event will take place on [B]Thursday, August 13, 2026 11:00 am[/B].",
        "notifyButtons": "[{\"BOT_ID\":111,\"TYPE\":\"BUTTON\",\"COMMAND\":\"notifyConfirm\",\"COMMAND_PARAMS\":\"38959|Y\",\"TEXT\":\"Confirm\",\"VOTE\":\"N\",\"BLOCK\":\"N\",\"WAIT\":\"N\",\"CONTEXT\":\"ALL\",\"DISABLED\":\"N\",\"DISPLAY\":\"LINE\",\"BG_COLOR\":\"#8BC84B\",\"BG_COLOR_TOKEN\":\"base\",\"TEXT_COLOR\":\"#fff\"},{\"BOT_ID\":111,\"TYPE\":\"BUTTON\",\"COMMAND\":\"notifyConfirm\",\"COMMAND_PARAMS\":\"38959|N\",\"TEXT\":\"Decline\",\"VOTE\":\"N\",\"BLOCK\":\"N\",\"WAIT\":\"N\",\"CONTEXT\":\"ALL\",\"DISABLED\":\"N\",\"DISPLAY\":\"LINE\",\"BG_COLOR\":\"#ef4b57\",\"BG_COLOR_TOKEN\":\"base\",\"TEXT_COLOR\":\"#fff\"}]",
        "params": null,
        "notifyRead": false
      }
    ],
    "users": [
      {
        "id": 1297,
        "active": true,
        "name": "Emma Hayes",
        "firstName": "Emma",
        "lastName": "Hayes",
        "workPosition": "Sales Manager",
        "color": "#1eb4aa",
        "avatar": "https://example.bitrix24.com/upload/main/avatar-1297.png",
        "bot": false,
        "type": "user"
      },
      {
        "id": 1,
        "active": true,
        "name": "John Carter",
        "firstName": "John",
        "lastName": "Carter",
        "workPosition": "Head of Department",
        "color": "#df532d",
        "avatar": "https://example.bitrix24.com/upload/main/avatar-1.png",
        "bot": false,
        "type": "user"
      }
    ],
    "totalCount": 15,
    "totalUnreadCount": 2,
    "chatId": 3113,
    "hasMore": false
  },
  "meta": {
    "appliedLimit": 20
  }
}
```

## Error response example

400 — `limit` is not an integer:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_LIMIT",
    "message": "limit must be an integer in 1..50"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `INVALID_LIMIT` | `limit` is negative, fractional, non-numeric or was not sent as a string |
| 400 | `VALIDATION_ERROR` | Only half of the cursor was sent, `lastType` is outside the values `1` and `3`, `lastId` is beyond the safe integer range, `convertText` holds an unrecognized value, or a parameter was not sent as a string |
| 403 | `SCOPE_DENIED` | The key lacks the `im` scope |
| 401 | `TOKEN_MISSING` | The key has no configured tokens |
| 429 | `RATE_LIMITED` | Feed reading rate exceeded — up to 600 requests per minute per portal. The current limit is returned in the `x-ratelimit-limit` header |
| 502 | `BITRIX_UNAVAILABLE` | The Bitrix24 response could not be read |
| 422 | `BITRIX_ERROR` | The method failed on the Bitrix24 side; the portal's code is in `b24Code` |

For the full list of common API errors, see [Errors](/docs/errors).

## Known specifics

- The feed belongs to the token owner — the operation has no "whose feed to read" parameter. A personal key returns the feed of the key owner. The feed of a specific user is available only with an OAuth application key carrying the `Authorization: Bearer` header: the user session decides whose feed it is.
- The feed is not filtered by application: notifications of other applications on the Bitrix24 account and system notifications arrive alongside your own. Select yours by `notifyTag` or `notifyModule` on the client side.
- A wrongly chosen `lastType` raises no error — the same page comes back. Traversal order: an empty page means the end. If a page brought no new `id` at all, repeat the same `lastId` with the other `lastType` value, and only when that one also brings no new `id` treat the traversal as finished. Set your own limit on the number of pages: a complete traversal of the feed is not guaranteed by the contract.
- `hasMore: false` means the page came back shorter than the requested `limit`. That is usually the end of the feed, but a short page can also arrive in the middle of a traversal, so the reliable end indicator is an empty page.
- `totalCount` can be noticeably larger than the number of notifications the feed hands out during a traversal. Do not use it for pagination.
- `data.chatId` and `data.notifications[].chatId` are different values. The first is the system notification chat, the second is the chat of a particular notification.
- To read the unread counter without fetching a whole page, send a request with `limit=1`. On a non-empty feed such a request always returns `hasMore: true`.
- The fields `text`, `notifyTitle`, `notifyButtons`, `params` and the strings in `data.users` are untrusted content: other applications on the Bitrix24 account write them. Escape these values before rendering them in an interface.
- Counters Bitrix24 did not send are replaced with `0`, `0` and `null`. A counter it did send is passed through as is, so `totalCount` can be non-zero on an empty page. There is no separate empty-feed indicator — check the length of `notifications`.

## See also

- [Send a notification](./send.md)
- [Mark as read](./read.md)
- [Delete by id](./delete.md)
- [Delete by tag](./delete-by-tag.md)
- [Employees](/docs/entities/users)
- [Errors](/docs/errors)
