Интеграция
Соглашения
Запросы и ответы#
- Серверные вызовы —
POSTсContent-Type: application/jsonи телом-JSON-объектом. Телаapplication/x-www-form-urlencodedтоже разбираются, но контракт — JSON. Всегда передавайте один из этих двух типов содержимого: при любом другом, напримерtext/plain, тело не разбирается как JSON и вызов завершается ошибкой (обычноUNAUTHORIZED, так какpartnerне найден). - Тело ограничено 128 КиБ (131072 байта). Слишком большое тело отклоняет веб-сервер: HTTP 413 и HTML-страница, до API запрос не доходит, поэтому JSON-конверта ошибки нет. Некорректный JSON, а также отсутствующий или неподдерживаемый тип содержимого (например,
application/xml) дают HTTP 400REQUEST_FAILED, а неINVALID_REQUEST. - Успешные ответы содержат
"status": "ok"и поля результата. - Ошибки имеют вид
{"status":"error","message":"<CODE>"}, HTTP-статус зависит от кода.message— всегда код в верхнем регистре; см. справочник ошибок. Сбой без публичного кода —REQUEST_FAILED. - Ответы отправляются с
Cache-Control: no-store: кэшируйте публичный каталог у себя. - Публичные GET endpoints тоже возвращают JSON (Каталог). На запрос с неверным HTTP-методом или неизвестным путём API отвечает HTTP 404 и JSON другого вида,
{"message":"Route GET:/nope not found","error":"Not Found","statusCode":404}, а не конвертом ошибки.
| HTTP | Типичный смысл |
|---|---|
| 200 | Успех |
| 400 | Ошибка валидации или бизнес-правило (INVALID_REQUEST, PROJECT_BET_LIMIT, …); также большинство сбоев без более точного статуса и IDEMPOTENCY_CONFLICT в /playGame.do |
| 401 | UNAUTHORIZED |
| 403 | IP_NOT_ALLOWED (или FORBIDDEN) |
| 404 | Неизвестная игра или запись (UNSUPPORTED_GAME, GAME_NOT_FOUND, GRANT_NOT_FOUND, OUTCOME_NOT_FOUND) |
| 409 | Только /gameActions.do: IDEMPOTENCY_CONFLICT, DUPLICATE_EXTERNAL_ID, ROUND_NOT_CANCELLABLE, ROUND_BUSY |
| 429 | RATE_LIMITED |
| 503 | DEMO_UNAVAILABLE при запуске; DATABASE_UNAVAILABLE в GET /health |
Идемпотентность#
POST /playGame.do и POST /gameActions.do принимают необязательный заголовок Idempotency-Key: от 1 до 128 печатных ASCII-символов (без пробелов). Некорректный ключ даёт HTTP 400 INVALID_IDEMPOTENCY_KEY.
- Область действия. Ключ действует в пределах вашего проекта и endpoint (
/playGame.doи/gameActions.doхранят ключи раздельно). В/gameActions.doодин и тот же ключ для двух разных значенийmethod— конфликт./playerRtp.doзаголовок не использует. - Повтор запроса с тем же ключом и тем же телом возвращает первый ответ, не выполняя работу заново. Поле
api_keyв сравнении не участвует. - Тот же ключ с другим телом даёт
IDEMPOTENCY_CONFLICT: HTTP 400 в/playGame.do, HTTP 409 в/gameActions.do. - Методы
report_*заголовок игнорируют (они только читают).freespins_createиoutcome_scheduleдополнительно защищеныexternal_id(DUPLICATE_EXTERNAL_ID). - Без заголовка вызов выполняется каждый раз (запуск без ключа считается новым запуском).
Лимиты запросов#
Операторские endpoints ограничены на проект и в минуту, чтобы одна интеграция не вытесняла остальные. Есть три независимые квоты:
| Класс | Endpoint | Квота по умолчанию |
|---|---|---|
| launch | POST /playGame.do | 1200 в минуту |
| actions | POST /gameActions.do (фриспины, целевые исходы, round_cancel) | 600 в минуту |
| reports | POST /gameActions.do с report_* | 120 в минуту |
- Квота — «ведро токенов»: целую минуту вызовов можно отправить пачкой, токены возвращаются непрерывно.
POST /playerRtp.doи публичные GET endpoints не ограничиваются. - Ведро выбирается по полю
partnerтела до проверки ключа: вызовы с известнымpartnerи неверным ключом тоже расходуют квоту, а429может прийти раньше401. Счётчики хранятся в памяти процесса сервера и обнуляются при его перезапуске. - При превышении квоты ответ — HTTP 429
RATE_LIMITED, ничего не выполняется. Учтённые ответы содержатX-RateLimit-Limit(например,600/min); разрешённые — ещё иX-RateLimit-Remaining; отказ содержитRetry-Afterв целых секундах (не менее 1). - Значения окружения — в
rateLimitsвGET /capabilities; более высокие можно согласовать с менеджером.
HTTP/1.1 429 Too Many Requests
Retry-After: 7
X-RateLimit-Limit: 600/min
content-type: application/json
{"status":"error","message":"RATE_LIMITED"}При 429 подождите Retry-After секунд и повторите с тем же Idempotency-Key. Не опрашивайте отчёты: листайте report_rounds через cursor, а report_ggr и report_reconciliation вызывайте раз за период. Колбэки платформы к вам в эти квоты не входят.
Суммы#
У всех валют два знака после запятой (Валюты). Суммы точные: разбирайте их десятичным типом, а не числом с плавающей точкой.
| Контекст | Формат | Пример |
|---|---|---|
Колбэки кошелька: amount, bet_amount, win_amount | JSON-число, платформа записывает его с двумя знаками | 1.50, 12.75 |
Ответ кошелька: balance | JSON-число, неотрицательное, не более 2 знаков, без экспоненты | 998.50 |
bet, total_win фриспинов и freespins_finished; отчёты; demo_balance | Десятичная строка, не более 2 знаков | "1.00" |
min_minor, max_minor | Строка из цифр, минорные единицы | "1250" |
Допускается не более двух знаков после запятой и не более 13 цифр до точки; ведущие нули запрещены. Платформа отправляет суммы колбэков JSON-числами ровно с двумя знаками (1.50, а не 1.5). Некоторые информационные поля meta (nominal_bet, total_win внутри meta.freespins, multiplier) — обычные числа без дополнения нулями. Подпись считайте и проверяйте по исходным байтам тела, а не по пересериализованному JSON (Подпись колбэков).
Даты и время#
expires_at,created_at,finished_atи подобные поля — ISO 8601. Когда вы отправляетеexpires_at, в нём должна быть зона (Zили+02:00), например2027-02-01T12:00:00Z.- Колбэки кошелька содержат Unix-время в секундах (
meta.time,timestamp).
Идентификаторы#
| Id | Откуда берётся |
|---|---|
player_id | Выбираете вы (1–128 печатных ASCII-символов) |
session_id | Возвращается методом запуска |
round_id | Генерируется платформой; встречается в колбэках кошелька и в Game History админ-панели |
meta.transaction | Уникальный id каждой операции кошелька (bet, win, refund) |
grant_id, outcome_id | UUID, генерируются платформой |
external_id | Необязательный ваш id выдачи или исхода, уникальный в проекте (1–128 печатных символов без пробелов) |
Неизвестные поля#
Метод запуска отклоняет неизвестные поля с INVALID_REQUEST. Отправляйте только документированные поля.
Таймауты и повторы с вашей стороны#
Используйте клиентский таймаут около 10 секунд; при таймауте или 5xx повторите вызов с тем же Idempotency-Key. 4xx — окончательный ответ: сначала исправьте запрос.