Стикеры
Библиотека стикеров компании: паки со статичными стикерами (WebP 512×512), которые оператор отправляет в чат так же, как вложение. Эта группа управляет паками и отдельными стикерами — создание, загрузка файлов, добавление стикера прямо из входящего сообщения, импорт публичного набора Telegram, и отдаёт байты стикера по публичной подписанной ссылке (для рендера в интерфейсе-пикере).
Права доступа
Гейтится правами sticker.view / sticker.create / sticker.update / sticker.delete. Роль Agent по умолчанию имеет sticker.view и sticker.create (может листать библиотеку и добавлять стикеры, в т.ч. кнопкой «В библиотеку» из чата), но не sticker.update/sticker.delete — переименование, перемещение между паками и удаление доступны только Manager/Admin.
Тенантность: 404, а не 403
Как и в группе «Быстрые ответы», обращение к паку или стикеру другой компании возвращает 404 Sticker pack not found. / 404 Sticker not found., а не 403 — вызывающая сторона не может отличить «не существует» от «принадлежит другой компании».
Загрузка файлов
POST /v1/sticker-packs/{pack}/stickers — multipart/form-data, поле files[] (1–120 файлов за раз, PNG/JPG/JPEG/WebP, до 5 МБ каждый). Каждый файл конвертируется на сервере в статичный WebP 512×512. Один плохой файл не откатывает весь батч: успешно обработанные попадают в created[], остальные — в skipped[] с человекочитаемой reason (например, превышение 25-мегапиксельного лимита на декодирование или неподдерживаемый формат).
«В библиотеку» из сообщения
Есть два эндпоинта для добавления стикера, полученного во входящем сообщении: POST /v1/sticker-packs/{pack}/stickers/from-message — в указанный пак, и POST /v1/sticker-packs/stickers/from-message (без {pack}) — в служебный пак «Из чатов», который создаётся лениво при первом обращении. Оба принимают {message_id, attachment_id}; вложение должно быть настоящим WebP-стикером (проверяется по сигнатуре RIFF/WEBP байт, а не по заявленному mime_type), а сообщение и вложение — принадлежать текущей компании и диалогу, доступному вызывающему пользователю (иначе 422 для чужих/несуществующих message_id/attachment_id, 403 при отсутствии доступа к диалогу).
Импорт публичного набора Telegram
POST /v1/sticker-packs/import/telegram принимает {link} — ссылку вида https://t.me/addstickers/<name> (или голое имя набора). С 2026-08-23 импорт асинхронный: запрос синхронно выполняет только дешёвую проверку (один вызов getStickerSet — разбор ссылки, резолв токена, существование набора, непустой, не полностью анимированный) и, если она проходит, сразу отвечает 202 Accepted с {status: "queued", name, title}, поставив в очередь photos фактическую загрузку. Все «заведомо не может получиться» случаи (битая ссылка, нет доступного Telegram-бота, набор не найден/пуст/полностью анимированный) по-прежнему возвращают 422 немедленно, без постановки в очередь. Результат импорта (успех или ошибка, счётчики imported/skipped_animated, флаг truncated) приходит отдельным событием sticker.pack.import.finished (WS-канал компании + вебхук) — в ответе на POST его больше нет. Импортируемые стикеры пропускают только анимированные форматы Telegram (TGS/WebM); у остальных сохраняется собственный emoji-тег Telegram как emoji_tags. Лимит набора — 120 статичных стикеров на пак (truncated: true в событии, если набор был длиннее и часть отброшена).
Публичная ссылка на файл стикера
Каждый стикер в ответе несёт url — подписанную ссылку на GET /v1/stickers/{sticker}/file. Этот роут публичный (без Authorization, авторизация — сама подпись) и БЕССРОЧНЫЙ, а не временный: пикер стикеров рендерит десятки <img> разом и полагается на агрессивное кеширование браузера. Отозвать одну утёкшую ссылку можно только удалением стикера (мягкое удаление скрывает файл — 404 по старой ссылке); отозвать все ссылки разом можно только ротацией APP_KEY платформы.
Эндпоинты
| Метод | Путь | Описание |
|---|---|---|
| GET | /v1/sticker-packsСписок паков стикеров компании со вложенными стикерами. | Список паков стикеров компании со вложенными стикерами. |
| POST | /v1/sticker-packsСоздать пак стикеров (name, tray_emoji). | Создать пак стикеров (name, tray_emoji). |
| POST | /v1/sticker-packs/{pack}Обновить пак — название, tray_emoji, позицию (сортировка). | Обновить пак — название, tray_emoji, позицию (сортировка). |
| DELETE | /v1/sticker-packs/{pack}Удалить пак вместе со всеми его стикерами. | Удалить пак вместе со всеми его стикерами. |
| POST | /v1/sticker-packs/{pack}/stickersЗагрузить один или несколько стикеров в пак (multipart/form-data, files[], до 120 файлов, до 5 МБ каждый). | Загрузить один или несколько стикеров в пак (multipart/form-data, files[], до 120 файлов, до 5 МБ каждый). |
| POST | /v1/sticker-packs/stickers/from-messageДобавить стикер из входящего сообщения в служебный пак «Из чатов» (создаётся лениво). | Добавить стикер из входящего сообщения в служебный пак «Из чатов» (создаётся лениво). |
| POST | /v1/sticker-packs/{pack}/stickers/from-messageДобавить стикер из входящего сообщения в указанный пак. | Добавить стикер из входящего сообщения в указанный пак. |
| POST | /v1/sticker-packs/import/telegramПоставить в очередь импорт публичного набора стикеров Telegram по ссылке (t.me/addstickers/…) — 202, результат приходит событием sticker.pack.import.finished. | Поставить в очередь импорт публичного набора стикеров Telegram по ссылке (t.me/addstickers/…) — 202, результат приходит событием sticker.pack.import.finished. |
| PATCH | /v1/stickers/{sticker}Обновить стикер — emoji_tags, position, или переместить в другой пак (sticker_pack_id). | Обновить стикер — emoji_tags, position, или переместить в другой пак (sticker_pack_id). |
| DELETE | /v1/stickers/{sticker}Удалить стикер из пака. | Удалить стикер из пака. |
| GET | /v1/stickers/{sticker}/fileПубличная бессрочная подписанная ссылка на файл стикера (WebP) — без Authorization. | Публичная бессрочная подписанная ссылка на файл стикера (WebP) — без Authorization. |
Примеры
Создание пака стикеров
Запрос
curl -X POST "https://api.aisar.app/v1/sticker-packs" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Reactions",
"tray_emoji": "😀"
}'Ответ
{
"data": {
"message": "Sticker pack created.",
"pack": {
"id": 14,
"name": "Reactions",
"is_system": false,
"source": "manual",
"tray_emoji": "😀",
"position": 0,
"stickers_count": 0,
"stickers": []
}
}
}Список паков стикеров
Запрос
curl -X GET "https://api.aisar.app/v1/sticker-packs" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": [
{
"id": 14,
"name": "Reactions",
"is_system": false,
"source": "manual",
"tray_emoji": "😀",
"position": 0,
"stickers_count": 1,
"stickers": [
{
"id": 87,
"pack_id": 14,
"url": "https://api.aisar.app/v1/stickers/87/file?signature=...",
"width": 512,
"height": 512,
"size": 41230,
"is_animated": false,
"emoji_tags": ["😀"],
"position": 0
}
]
}
]
}Загрузка стикеров в пак
Запрос
curl -X POST "https://api.aisar.app/v1/sticker-packs/14/stickers" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "files[]=@/path/to/sticker1.png" \
-F "files[]=@/path/to/sticker2.png"Ответ
{
"data": {
"created": [
{
"id": 88,
"pack_id": 14,
"url": "https://api.aisar.app/v1/stickers/88/file?signature=...",
"width": 512,
"height": 512,
"size": 38940,
"is_animated": false,
"emoji_tags": [],
"position": 1
}
],
"skipped": [
{ "filename": "sticker2.png", "reason": "Image exceeds the maximum decodable pixel count." }
]
}
}«В библиотеку» из входящего сообщения
Запрос
curl -X POST "https://api.aisar.app/v1/sticker-packs/stickers/from-message" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message_id": 1001,
"attachment_id": 55
}'Ответ
{
"data": {
"message": "Sticker added to library.",
"pack_id": 15,
"item": {
"id": 89,
"pack_id": 15,
"url": "https://api.aisar.app/v1/stickers/89/file?signature=...",
"width": 512,
"height": 512,
"size": 27510,
"is_animated": false,
"emoji_tags": [],
"position": 0
}
}
}Импорт набора стикеров Telegram (202 — ставится в очередь)
Запрос
curl -X POST "https://api.aisar.app/v1/sticker-packs/import/telegram" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"link": "https://t.me/addstickers/CoolPack"
}'Ответ
{
"data": {
"status": "queued",
"name": "CoolPack",
"title": "Cool Pack"
}
}Перемещение стикера в другой пак
Запрос
curl -X PATCH "https://api.aisar.app/v1/stickers/87" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sticker_pack_id": 14,
"emoji_tags": ["😀", "👍"]
}'Ответ
{
"data": {
"message": "Sticker updated.",
"sticker": {
"id": 87,
"pack_id": 14,
"url": "https://api.aisar.app/v1/stickers/87/file?signature=...",
"width": 512,
"height": 512,
"size": 41230,
"is_animated": false,
"emoji_tags": ["😀", "👍"],
"position": 0
}
}
}