SMeet Mini Apps
Справочник API автора
Справочник после первых разделов собран из машиночитаемого описания API, которое можно скачать как openapi.json. Имена методов, поля JSON и коды ошибок одинаковы на всех языках этой документации.
Запросы#
- Базовый адрес:
https://messenger.scrile.com/mini-app-api/v1. Метод вызывается какPOST https://messenger.scrile.com/mini-app-api/v1/<method>с телом в JSON в UTF-8 иContent-Type: application/json. - Тело не больше 64 КиБ; большее отклоняется с
413 PAYLOAD_TOO_LARGEиlimitв байтах ещё до чтения. - Путь, который не является методом, и любой HTTP-метод, кроме
POST, получают400 INVALID_REQUEST. - API не отвечает на запросы CORS и не ставит cookie: он только для серверов.
- Ответ, который даёт сам прокси SMeet,
429или413, приходит в той же обёртке с пустымrequest_id.
Аутентификация#
Каждый вызов несёт ключ одной среды мини-приложения:
Authorization: Bearer smac1_<key id>_<secret>Ключ определяет мини-приложение и среду. Код входа другого приложения или среды отклоняется (APP_MISMATCH, ENVIRONMENT_MISMATCH); сессия другого приложения или среды получает not_found. Ключи выпускаются и отзываются на экране мини-приложения в «Моих ботах» (Ключи).
Лимиты#
| Что | Лимит |
|---|---|
| Вызовы одним ключом | 50 в секунду |
| Вызовы одного мини-приложения, все ключи | 200 в секунду |
| Все мини-приложения вместе | 1000 в секунду |
| Тело | 64 КиБ |
При превышении ответ 429 RATE_LIMITED с retry_after; повторите тот же запрос с тем же ключом после этого срока.
Справочник собран из контракта SMeet Mini Apps author API 1.0.0 (OpenAPI 3.1.0). Базовый адрес: https://messenger.scrile.com/mini-app-api/v1. Машиночитаемый файл: openapi.json.
API, которым сервер мини-приложения обменивает код входа на сессию, проверяет и отзывает сессии.
Методы#
Каждый метод вызывается как POST https://messenger.scrile.com/mini-app-api/v1/<method> с телом в JSON; методов с GET нет. Аутентификация: Ключ одной среды мини-приложения; показывается один раз в «Моих ботах» при выпуске. Храните его только на сервере, никогда на странице, в ссылке или в журнале. У каждой среды до двух действующих ключей, поэтому ключ можно заменить без перерыва. Отозванный или неизвестный ключ получает 401 INVALID_CREDENTIALS.
| Метод | HTTP | Idempotency-Key | Описание |
|---|---|---|---|
| SessionsВход человека и проверка того, что он всё ещё может пользоваться мини-приложением. | |||
exchangeLaunchCode | POST | обязателен | Обменять код входа и его PKCE verifier на сессию мини-приложения. |
checkSession | POST | можно | Проверить сессию мини-приложения сейчас, перед защищённой операцией. |
revokeSession | POST | можно | Завершить сессию мини-приложения, например когда человек выходит из вашего приложения. |
exchangeLaunchCode#
POST /exchangeLaunchCodeSessions
Обменять код входа и его PKCE verifier на сессию мини-приложения.
Код приходит из authorize() на странице и живёт 60 секунд; verifier тот, что SDK создал для него. Обменивайте код один раз: тот же Idempotency-Key с тем же телом в течение 60 секунд после обмена повторяет ответ (если он потерялся), всё остальное с использованным кодом получает CODE_ALREADY_USED. Неверный verifier отзывает код. Если человек больше не может пользоваться мини-приложением, ответом будет ACCESS_DENIED с причиной. Сессия живёт не больше 15 минут; страница продлевает её новым authorize() и новым обменом.
Заголовки#
| Заголовок | Тип | Обязательно | Описание |
|---|---|---|---|
Idempotency-Key | IdempotencyKey | Да | Один ключ на вход, например привязанный к вашей попытке входа (login:<attempt id>). Повторяя запрос после тайм-аута, 429 или 503, передавайте тот же ключ с тем же телом. |
Тело запроса (JSON)#
| Поле | Тип | Обязательно |
|---|---|---|
code | LoginCode | Да |
code_verifier | CodeVerifier | Да |
Результат#
В поле result приходит Session. Сессия и тот, кто вошёл.
При ошибке приходит объект ошибки с кодом из таблицы кодов ошибок.
checkSession#
POST /checkSessionSessions
Проверить сессию мини-приложения сейчас, перед защищённой операцией.
Вызывайте без кеша перед каждой операцией от имени человека: создание или изменение его данных, загрузка или скачивание файла, чтение того, что ему принадлежит. Любое состояние сессии приходит ответом 200: active: true с текущими сведениями или active: false с причиной. Неизвестный токен, неверный секрет и сессия другого приложения или среды одинаково дают reason: not_found. Во время паузы платформы ответ active: false, reason: maintenance.
Заголовки#
| Заголовок | Тип | Обязательно | Описание |
|---|---|---|---|
Idempotency-Key | IdempotencyKey | Нет | Принимается, но не нужен: метод ничего не меняет или идемпотентен сам по себе. |
Тело запроса (JSON)#
| Поле | Тип | Обязательно |
|---|---|---|
session_token | SessionToken | Да |
Результат#
В поле result приходит SessionCheck. Состояние сессии.
При ошибке приходит объект ошибки с кодом из таблицы кодов ошибок.
revokeSession#
POST /revokeSessionSessions
Завершить сессию мини-приложения, например когда человек выходит из вашего приложения.
Отзывает только сессию приложения и среды ключа. Ответ одинаков для неизвестного токена, неверного секрета, сессии другого приложения или среды и уже отозванной сессии, и тогда ничего не меняется. Работает и во время паузы платформы.
Заголовки#
| Заголовок | Тип | Обязательно | Описание |
|---|---|---|---|
Idempotency-Key | IdempotencyKey | Нет | Принимается, но не нужен: метод ничего не меняет или идемпотентен сам по себе. |
Тело запроса (JSON)#
| Поле | Тип | Обязательно |
|---|---|---|
session_token | SessionToken | Да |
Результат#
Всегда один и тот же ответ. В поле result приходит объект с такими полями.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
revoked | boolean | Да | Всегда true. |
При ошибке приходит объект ошибки с кодом из таблицы кодов ошибок.
Типы#
Простые типы#
Строки с заданным форматом. Поля ссылаются на них по имени.
| Имя | Тип | Описание |
|---|---|---|
Id | string | Десятичный идентификатор, переданный строкой. Шаблон: ^[0-9]{1,20}$. Пример: 1000. |
LoginCode | string | Одноразовый код входа из authorize(); живёт 60 секунд. Шаблон: ^smlc_[A-Za-z0-9_-]{43}$. |
CodeVerifier | string | PKCE verifier (RFC 7636), который SDK создал для кода; SMeet проверяет его по S256. Шаблон: ^[A-Za-z0-9._~-]{43,128}$. |
SessionToken | string | Сессия мини-приложения. Её хранит ваш сервер; на страницу она не попадает. Шаблон: ^smas1_([0-9a-f]{16})_([A-Za-z0-9_-]{43})$. |
AuthorKey | string | Ключ одной среды мини-приложения, передаётся как Authorization: Bearer. Шаблон: ^smac1_([0-9a-f]{16})_([A-Za-z0-9_-]{43})$. |
IdempotencyKey | string | От 1 до 128 символов. Шаблон: ^[A-Za-z0-9._:-]{1,128}$. |
Timestamp | string (date-time) | RFC 3339, UTC. Пример: 2026-10-10T12:15:00Z. |
Revision | string | Ревизия разговора человека с ботом. Передавайте её в Bot API как expected_access_revision; сравнивайте только на равенство. От 1 до 64 символов. Пример: 1088. |
Environment | string | Одно из значений: production, test. |
SpaceKind | string | Публичное пространство SMeet или организация. Одно из значений: public, organization. |
LanguageCode | string | Язык интерфейса SMeet у человека. Одно из значений: en, ru. |
Scope | string | Что человек согласился передать сверх идентификатора и языка; profile означает отображаемое имя. Одно из значений: profile. |
SessionReason | string | Почему сессия не активна. Принимайте и незнакомые значения. Одно из значений: not_found, maintenance, expired, revoked, launch_closed, parent_session_revoked, operator_session, account_disabled, chat_stopped, membership_revoked, app_unavailable, space_disabled, bot_unavailable, test_access_removed, user_revoked, config_changed. |
AccessDeniedReason | string | Почему обмен отклонён с ACCESS_DENIED. Принимайте и незнакомые значения. Одно из значений: launch_closed, parent_session_revoked, operator_session, account_disabled, chat_stopped, membership_revoked, app_unavailable, space_disabled, bot_unavailable, test_access_removed, user_revoked, config_changed. |
App#
Мини-приложение, которому принадлежит ключ.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id | Id | Да | |
bot_id | string или null | Да | Идентификатор бота, тот же, что id в ответе getMe в Bot API. |
title | string или null | Да | Название конфигурации, которую открыл человек. |
Space#
Где человек открыл мини-приложение.
User#
Человек, который вошёл.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id | Id | Да | Тот же идентификатор, который бот видит как from.id в Bot API. |
display_name | string | Нет | Есть, только если мини-приложение запрашивает profile и человек согласился. |
language_code | LanguageCode | Да |
Chat#
Личный чат человека с ботом.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id | Id | Да | Используйте его как chat_id в Bot API. |
type | string | Да | Всегда private. |
access_revision | Revision | Да |
Session#
Новая сессия мини-приложения и для кого она.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
session_token | SessionToken | Да | |
expires_at | Timestamp | Да | Не позже чем через 15 минут после обмена и никогда не позже конца входа человека в SMeet. |
environment | Environment | Да | |
app | App | Да | |
space | Space | Да | |
user | User | Да | |
chat | Chat | Да | |
scopes | массив Scope | Да | Что человек согласился передать; пусто, если мини-приложение запрашивает только идентификатор и язык. |
start_param | string или null | Да | Параметр кнопки или ссылки, которой открыто мини-приложение; null, если его не было. Шаблон: ^[A-Za-z0-9_-]{0,64}$. |
SessionCheck#
Состояние сессии. При active: false приходит только reason; при active: true приходят сведения о сессии, прочитанные сейчас: chat.access_revision и есть ревизия для того, что вы отправите человеку после этой проверки.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
active | boolean | Да | |
reason | SessionReason | Нет | Есть, когда active равно false. |
expires_at | Timestamp | Нет | Есть, когда active равно true. |
environment | Environment | Нет | |
app | App | Нет | |
space | Space | Нет | |
user | User | Нет | |
chat | Chat | Нет |
Ошибки#
Любая ошибка. Значение каждого кода и HTTP-статус, с которым он приходит, указаны в ErrorCode. Заголовок Retry-After ставится всегда, когда в теле есть retry_after. Ответ 502, 503 или 504 без такого тела в JSON пришёл от прокси перед SMeet: считайте его TEMPORARILY_UNAVAILABLE.
Заголовки ответа с ошибкой: Retry-After, X-Request-Id, WWW-Authenticate.
Объект ошибки#
Любой неудачный вызов отвечает этой обёрткой и соответствующим HTTP-статусом.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
ok | boolean | Да | Всегда false. |
error | Error | Да | |
request_id | string | Да | Укажите его, когда пишете в поддержку. Пуст, если ответил прокси перед SMeet. |
Поле error:
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
code | ErrorCode | Да | |
message | string | Да | Человекочитаемый текст на английском, без секретов. Не разбирайте его. |
retry_after | integer | Нет | Сколько секунд подождать перед повтором. Есть, только когда повтор имеет смысл. Не меньше 1. |
reason | string | Нет | При ACCESS_DENIED значение из AccessDeniedReason; при CODE_ALREADY_USED значение replay_unavailable, когда на повтор обмена ответить уже нельзя. |
field | string | Нет | Есть при INVALID_REQUEST: поле с ошибкой (code, code_verifier, session_token, idempotency_key, body или method для пути, который не является методом). |
limit | integer | Нет | Есть при PAYLOAD_TOO_LARGE: наибольшее допустимое тело в байтах. |
Коды ошибок#
| Код | HTTP | Значение |
|---|---|---|
INVALID_CREDENTIALS | 401 | Ключа нет, он неизвестен или отозван. Не повторяйте |
INVALID_REQUEST | 400 | Поля нет или оно неверное; field его называет |
PAYLOAD_TOO_LARGE | 413 | Тело больше 64 КиБ; limit даёт размер в байтах |
RATE_LIMITED | 429 | Слишком много запросов; подождите retry_after и повторите с тем же ключом |
MINI_APPS_MAINTENANCE | 503 | Мини-приложения на паузе; только exchangeLaunchCode, retry_after 30 |
TEMPORARILY_UNAVAILABLE | 503 | Ничего не изменено; повторите тот же запрос с тем же ключом через retry_after |
IDEMPOTENCY_KEY_REQUIRED | 400 | exchangeLaunchCode нужен заголовок Idempotency-Key |
IDEMPOTENCY_CONFLICT | 409 | Ключ уже использован для этого кода с другим code_verifier |
APP_MISMATCH | 403 | Код принадлежит не тому мини-приложению, что ключ |
ENVIRONMENT_MISMATCH | 403 | Код принадлежит другой среде мини-приложения ключа |
CODE_NOT_FOUND | 400 | Такого кода нет. Страница входит заново |
CODE_EXPIRED | 400 | Код прожил свои 60 секунд. Страница входит заново |
CODE_REVOKED | 400 | Код отозван: окно закрыто, доступ закончился или прислан неверный verifier. Страница входит заново |
CODE_ALREADY_USED | 400 | Код уже обменян; с reason replay_unavailable на повтор ответить уже нельзя. Страница входит заново |
CODE_VERIFIER_MISMATCH | 400 | Verifier не подходит к коду, и теперь код отозван. Страница входит заново |
ACCESS_DENIED | 403 | Человек сейчас не может пользоваться мини-приложением; reason говорит почему |