## List of sticker packs

`GET /v1/chats/stickers/packs`

Returns the current user's sticker packs page by page: user packs (`custom`) first, then built-in ones (`vendor`). To get the next page, pass the `id` and `type` of the last pack of the previous page.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|----------|
| `limit` | number | no | Packs per page: 10 by default, from 1 to 200. An out-of-range value is clamped to the nearest bound; the requested and applied values are returned in `meta` |
| `lastId` | number | no | Cursor: `id` of the last pack of the previous page. Passed only together with `lastType` |
| `lastType` | string | no | Cursor: `type` of the last pack of the previous page — `vendor` or `custom`. Passed only together with `lastId` |

Without a cursor, the first page is returned. Other parameters, a repeated parameter or only one half of the cursor are rejected with `400 INVALID_PARAMS` before any Bitrix24 call.

## Examples

### curl — personal key

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

### curl — OAuth application

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

const { data } = await res.json()
console.log('Packs:', data.packs.length, 'more:', data.hasNextPage)
```

### JavaScript — OAuth application

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

const { data } = await res.json()
console.log('Packs:', data.packs.length, 'more:', data.hasNextPage)
```

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data.packs` | array | Packs on the page |
| `data.packs[].id` | number | Pack ID. Unique only together with `type`. Pass it as `packId` to [get a pack](/docs/chats/stickers/pack-get) |
| `data.packs[].type` | string | `custom` — a user pack, `vendor` — a built-in pack |
| `data.packs[].name` | string | Pack name |
| `data.packs[].authorId` | number \| null | ID of the author of a user pack; `null` for a built-in pack. Profile — by [user ID](/docs/entities/users/get) |
| `data.packs[].isAdded` | boolean | The pack is in the user's list |
| `data.stickers` | array | Stickers of the page's packs and, on the first page, also the recent stickers |
| `data.stickers[].id` | number | Sticker ID — for [deleting stickers from a pack](/docs/chats/stickers/pack-stickers) |
| `data.stickers[].packId` | number | ID of the sticker's pack — matches `data.packs[].id` |
| `data.stickers[].packType` | string | Kind of the sticker's pack |
| `data.stickers[].uri` | string | Path to the image in the Bitrix24 account — relative, without the domain |
| `data.stickers[].type` | string | Sticker type (`image`) |
| `data.stickers[].width` | number | Image width in pixels |
| `data.stickers[].height` | number | Image height in pixels |
| `data.stickers[].sort` | number | Sticker order in the pack |
| `data.recentStickers` | array | First page only: stickers the user sent recently, at most 12, newest first — `{ id, packId, packType }` |
| `data.hasNextPage` | boolean | There is a next page |
| `meta.requestedLimit` | number | The `limit` passed — only if it was clamped to a bound |
| `meta.appliedLimit` | number | The `limit` applied — only if it was clamped to a bound |

## Response example

```json
{
  "success": true,
  "data": {
    "stickers": [
      { "id": 1, "uri": "/upload/im/stickers/3/1.png", "type": "image", "width": 512, "height": 512, "packId": 3, "packType": "custom", "sort": 1 },
      { "id": 2, "uri": "/bitrix/images/im/stickers/aiHelp/2.png?v1", "type": "image", "width": 512, "height": 512, "packId": 14, "packType": "vendor", "sort": 2 }
    ],
    "packs": [
      { "id": 3, "name": "Work stickers", "type": "custom", "authorId": 7, "isAdded": true },
      { "id": 14, "name": "AI, help", "type": "vendor", "authorId": null, "isAdded": true }
    ],
    "recentStickers": [
      { "id": 2, "packId": 14, "packType": "vendor" }
    ],
    "hasNextPage": true
  }
}
```

## Error response example

400 — only one half of the cursor was passed:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "`lastId` needs `lastType`: pass the `id` and the `type` of the last pack of the previous page together."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | An unknown query parameter was passed |
| 400 | `INVALID_PARAMS` | A parameter was passed more than once |
| 400 | `INVALID_PARAMS` | `limit` is not an integer |
| 400 | `INVALID_PARAMS` | `lastId` was passed without `lastType` |
| 400 | `INVALID_PARAMS` | `lastType` was passed without `lastId` |
| 400 | `INVALID_PARAMS` | `lastId` is not a positive integer |
| 400 | `INVALID_PARAMS` | `lastType` is neither `vendor` nor `custom` |
| 401 | `TOKEN_MISSING` | The key has no configured Bitrix24 tokens |
| 403 | `SCOPE_DENIED` | The key lacks the `im` scope |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | A read-only key requested the first page — without `lastId` and `lastType`. Cursor pages work with a read-only key too |
| 404 | `ENTITY_NOT_FOUND` | Bitrix24 did not find the object. The portal code is in `error.b24Code` if supplied |
| 422 | `BITRIX_ERROR` | Bitrix24 returned an error. The portal code is in `error.b24Code` |
| 502 | `BITRIX_UNAVAILABLE` | Bitrix24 is unavailable or returned a server error |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

- The last page may be empty, with `hasNextPage: false`.
- If the cursor pack was deleted or removed from the user's list between requests, the list of user packs starts over from the beginning. Deduplicate packs by the `type` and `id` pair.
- `recentStickers` arrives on the first page only. The first request deletes recent-sticker rows beyond 12, so it is classified as a write: a read-only key receives `403 WRITE_BLOCKED_READONLY_KEY` before any Bitrix24 call. Cursor pages remain reads.
- `uri` is a path in the Bitrix24 account. The full image address is the Bitrix24 account domain plus `uri`.

## See also

- [Get a pack](/docs/chats/stickers/pack-get)
- [Recent stickers](/docs/chats/stickers/recent)
- [Stickers](/docs/chats/stickers)
