Обзор API
MARV предоставляет V2 как основную клиентскую API; V1 поддерживается для обратной совместимости. ACP - административный профиль; EXT - внешние вебхуки мерчантов.
Авторизация (V2)
V2 использует session-based авторизацию через JWT.
1. Login — клиент отправляет POST /v2/login с платформенными данными в JSON body:
{
"api_type": 30,
"api_uid": "12345",
"api_token": "platform-signed-token",
"client_version": "1.5.0",
"client_language_code": "ru"
}Сервер проверяет платформенный токен, создаёт/получает пользователя и возвращает JWT вместе с профилем:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_at": 1709136000,
"user": { "id": 1, "api_uid": "12345", "data": { ... } }
}Объект user содержит полный профиль (с data), что избавляет от отдельного запроса к /v2/users/me при старте сессии.
2. Запросы — все остальные V2 эндпоинты требуют JWT в заголовке:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...Платформенные заголовки (X-Auth-Token, X-Auth-Type, X-Auth-Uid) для V2 не нужны. Без валидного Bearer-токена запрос будет отклонён с 401.
3. Single session — каждый вызов /v2/login выдаёт новый токен с уникальным jti (JWT ID) и сохраняет его на сервере. Предыдущий токен того же пользователя автоматически инвалидируется: запросы со старым jti получат 401. Один пользователь = одна активная сессия.
4. Истечение — токен действует 24ч (настраивается через app.security.jwt.ttl). При истечении сервер вернёт 401; клиент должен повторить login.
JWT подписан HMAC-SHA256 ключом app.security.jwt.secret. Этот ключ можно использовать в других сервисах для верификации токена. Payload содержит: uid (user_id), atp (api_type), aui (api_uid), jti (session id), exp, iat.
Авторизация (V1)
V1 использует per-request платформенную авторизацию через заголовки:
| Заголовок | Обязателен | Описание |
|---|---|---|
X-Auth-Token | да | Токен авторизации: по умолчанию MD5(secret_apiType_apiUID) |
X-Auth-Type | да | Тип платформы (целое), выбирает конфигурацию платформы |
X-Auth-Uid | да | UID пользователя на платформе |
X-Session-Token | нет | Сессионный токен (только при single_mode.enabled) |
X-Client-Version | нет | Версия клиента; валидируется согласно конфигу |
X-Client-Language-Code | нет | Код языка клиента; сохраняется в профиле пользователя |
X-Session | нет | Сессия платформы (используется некоторыми платформами для верификации) |
X-Access-Token | нет | Access-токен платформы |
X-Inviter-Uid | нет | UID пригласившего пользователя (для реферальной системы) |
Single session mode (deprecated): при app.session.single_mode.enabled: true и немобильной платформе, при первом вызове /v1/users/fetch без X-Session-Token сервер генерирует токен, сохраняет его в БД и возвращает в заголовке X-Set-Session-Token. Клиент должен передавать этот токен в последующих запросах через X-Session-Token. При blocking: true запросы с устаревшим или отсутствующим токеном отклоняются (код 8 или 11).
Request ID и страна клиента
- Клиент может (но не обязан) передавать
X-Request-Id. Если заголовок не задан, MARV сгенерирует UUID самостоятельно. - Каждый ответ содержит
X-Request-Id— его можно использовать для сопоставления с логами (trace_idдобавляется вzerologконтекст). - При работе через Cloudflare заголовок
CF-IPCountryпроксируется в ответ какX-Client-Country-Code, поэтому страна клиента доступна даже без отдельного API. - В ответ также добавляется
X-Server-Id: это идентификатор узла (app.server.idиз конфига либо автогенерированное значение), что упрощает отладку и мониторинг лидерства.
Верификация IAP
ApiType/ApiUidвсегда берутся из аутентифицированного пользователя; значения в теле запроса игнорируются.- Поле
user_idопционально. Если его нет, MARV подставляет ApiUid текущего пользователя. Указывайтеuser_idявно только на платформах, где IAP использует другой идентификатор (например, Discord).
Форматы ответов
- Успех (V2):
{ "time": <unix>, "data": <payload> } - Ошибка (V2/ACP):
{ "time": <unix>, "error": { "code": "...", "http_status": N, "message": "...", "details": { ... }}}
Подробно про ошибки и соответствия доменных ошибок см. в V2 Errors.
Конфигурация и таймауты
- HTTP‑таймауты и бакеты метрик настраиваются в config/main.md, секциях
app.http.timeouts.*иobservability.metrics.http_buckets_ms.
EXT (мерчанты)
- Общие принципы и требования описаны в EXT Guide. Для каждого мерчанта используется собственная авторизация/подпись.
ACP: инициализация и мониторинг
POST /acp/me— основная точка входа ACP. Возвращает текущего ACP-пользователя, привязанные аккаунты, информацию о сервере (версия, аптайм, ОС), список включённых модулей, сконфигурированных платформ и активных маршрутов. Заменяет устаревший/acp/acp_users/me.POST /acp/system/overview— сводная аналитика для дашборда: статистика пользователей (total, today, week, month, DAU, MAU), количество онлайн, сессий за сегодня, состояние кластера (leader), память, Redis и статусы задач.POST /acp/system/metrics— Prometheus-совместимые метрики (HTTP, DB, cache, controllers, tasks). Описание полей и настройки — в Observability.
Реклама (ACP → Ads)
/acp/ads/listвозвращает все объявления иruntime‑снимок контроллерных метрик (количество вызовов, ошибки, p95) по префиксу/acp/ads/*. Эндпоинт read-only, отдельная роль не требуется./acp/ads/create|update|delete|toggleтребуют рольAccessAds(1024). После модификаций ответы всегда содержатcommit: ["ads"]и актуальный списокads, чтобы UI мог обновить состояние без повторного запроса.- DTO и поля объявлений описаны в openapi.yaml (
AcpAd,AcpCreateAdDTO, ...). Поляtitle/description/data— произвольные JSON‑структуры,weightзадаёт приоритет показа.
Alert Center (ACP)
/acp/alerts/list— фильтрует критические уведомления (type, severity, status, tags, диапазон дат). Требует рольAccessAlerts(2048)./acp/alerts/detail— возвращает карточку уведомления и историю доставок (Slack/Telegram webhooks)./acp/alerts/ack— подтверждает обработку, сохраняет комментарий (виден всем операторам).- Конфигурация каналов и шаблонов описана в config/main.md; подробный контракт — в openapi.yaml.
Реклама (V1 → Ads)
POST /v1/ads/fetchвозвращает доступные объявления (только включённые и отфильтрованные по весу). Дополнительно формируетсяvideo_urlпоdomain.stream.subdomainиз конфигурации.POST /v1/ads/impressionиPOST /v1/ads/clickинкрементируют счётчики просмотров/кликов поsid. Эти вызовы не возвращают payload.- Все V1 Ads маршруты используют стандартную платформенную авторизацию (
X-Auth-*). См. структурыV1Ad,V1AdImpressionDTO,V1AdClickDTOв openapi.yaml.
Реклама (V2 → Ads)
POST /v2/adsвозвращает массив объявлений (V2Ad) с теми же полями, что и V1 (включая вычисленныйvideo_url).POST /v2/ads/impressionиPOST /v2/ads/clickпринимают DTO (V2AdImpressionDTO,V2AdClickDTO) и увеличивают счётчики поsid.- Все вызовы требуют V2 авторизацию (
Authorization: Bearer JWT). Ответы следуют формату{ "time": ..., "data": ... }. Схемы перечислены в openapi.yaml.
