SportAPI Документация
RU
C Документация продуктаCoupon API
v1
Услуга и цены ↗ Получить доступ ↗
Coupon API / Формат ответа API

Формат ответа API

Методы нового клиентского API используют общую JSON-оболочку.

Ключевое правило:

HTTP 200 подтверждает обработку HTTP-запроса, но не всегда означает успешную бизнес-операцию. Всегда проверяйте поле code.

Успешный ответ

{
  "code": 1,
  "body": {},
  "error_code": null,
  "error_message": null,
  "date": 1784970000000,
  "time_ms": 12,
  "path": "/api/partner/coupons/get"
}

Бизнес-ошибка

{
  "code": 0,
  "body": null,
  "error_code": 471,
  "error_message": "Coupon not found",
  "date": 1784970000000,
  "time_ms": 5,
  "path": "/api/partner/coupons/get"
}

Бизнес-ошибка обычно также возвращается с HTTP 200.

Поля оболочки

ПолеТипОписание
codeintegerРезультат бизнес-операции: 1 — успех, 0 — ошибка.
bodyany/nullРезультат операции либо дополнительные сведения. Структура зависит от endpoint.
error_codeinteger/nullМашиночитаемый код бизнес-ошибки. При успехе обычно null.
error_messagestring/nullТекстовое описание ошибки. При успехе обычно null.
dateintegerВремя формирования ответа, Unix-миллисекунды.
time_msintegerВремя обработки запроса сервером в миллисекундах.
pathstringПуть метода, который обработал запрос.

code и error_code

Эти поля имеют разное назначение:

code       → успешна ли бизнес-операция
error_code → почему операция завершилась ошибкой

Пример:

{
  "code": 0,
  "error_code": 503,
  "error_message": "Bet outcome is blocked"
}

Здесь:

  • HTTP API доступен;
  • запрос обработан;
  • купон не создан;
  • причина — заблокированный исход.

В программной логике используйте error_code. Текст error_message предназначен для диагностики и может уточняться, поэтому не сравнивайте его как стабильный идентификатор ошибки.

Форма body зависит от метода

body не имеет одного типа для всего API.

МетодТип bodyГде находятся данные
GET /api/partner/healthstringНепосредственно в body.
POST /api/partner/loginobjectТокен в body.token.
POST /api/partner/coupons/placeobjectКупоны в body.coupons[].
GET /api/partner/coupons/getobjectОдин купон непосредственно в body.
POST /api/partner/coupons/resultsobjectbody.query_type и body.coupons[].
GET /api/partner/coupons/calculatedarrayКупоны непосредственно в body[].
GET /api/partner/coupons/activearrayКупоны непосредственно в body[].
GET /api/partner/balanceobjectБаланс в body.balance.

Не используйте один универсальный путь вроде body.coupons[0] для всех endpoint.

Создание купона

{
  "code": 1,
  "body": {
    "coupons": [
      {
        "coupon_code": "000000000272"
      }
    ]
  }
}

Получение одного купона

{
  "code": 1,
  "body": {
    "coupon_code": "000000000272"
  }
}

Активные или рассчитанные купоны

{
  "code": 1,
  "body": [
    {
      "coupon_code": "000000000272"
    }
  ]
}

Пустой успешный результат

Пустой массив не является ошибкой:

{
  "code": 1,
  "body": [],
  "error_code": null,
  "error_message": null
}

Такой ответ возможен, например, если:

  • активных купонов нет;
  • в выбранном окне нет рассчитанных купонов;
  • ни один из переданных кодов не найден в доступных данных.

Для /coupons/results пустой массив находится внутри объекта:

{
  "code": 1,
  "body": {
    "query_type": "ids",
    "coupons": []
  }
}

body при бизнес-ошибке

При ошибке body может быть:

  • null;
  • объектом с дополнительными сведениями;
  • массивом в старом совместимом контракте.

Например, при изменении коэффициента новый API возвращает причины в body.changes:

{
  "code": 0,
  "body": {
    "changes": [
      {
        "game_id": 737779544,
        "bet_coefficient": 2.19,
        "actual_coefficient": 2.09,
        "change_type": 2,
        "status": "rejected"
      }
    ]
  },
  "error_code": 501,
  "error_message": "Coefficient is change",
  "date": 1784970000000,
  "time_ms": 20,
  "path": "/api/partner/coupons/place"
}

Поэтому при code = 0 сначала прочитайте error_code, затем обработайте структуру body, описанную для этой ошибки.

HTTP-статус и бизнес-результат

HTTP-результатЗначениеДействие клиента
2xx, code = 1Операция выполнена.Обработать данные из body.
2xx, code = 0Бизнес-ошибка.Прочитать error_code, error_message и дополнительные данные.
400Неверный JSON или формат параметров.Исправить запрос.
401JWT отсутствует, неверен, истек или отозван.Выполнить вход повторно и использовать новый JWT.
403Токен не имеет нужной роли или доступ запрещен.Проверить тип токена и состояние аккаунта.
5xxСерверная или временная ошибка.Зафиксировать ошибку и применить безопасную стратегию повтора.

Для бизнес-ошибки проверка только HTTP-статуса приведет к неверному результату:

HTTP 200 + code 0 ≠ успех

Рекомендуемый алгоритм клиента

1. Выполнить HTTP-запрос.
2. Проверить транспортный результат.
3. Если HTTP 401 — получить новый JWT.
4. Если HTTP 403 — проверить доступ.
5. Если HTTP 5xx — применить стратегию временной ошибки.
6. Для JSON-ответа проверить code.
7. Если code = 0 — обработать error_code.
8. Если code = 1 — разобрать body по контракту конкретного endpoint.

Псевдокод:

response = send_request()

if response.status == 401:
    refresh_login()
    stop

if response.status == 403:
    report_access_error()
    stop

if response.status >= 500:
    handle_server_error()
    stop

payload = parse_json(response.body)

if payload.code != 1:
    handle_business_error(payload.error_code, payload.body)
    stop

handle_success(payload.body)

Повтор запросов

Стратегия повтора зависит от операции.

Методы чтения можно безопасно повторять после временной сетевой или серверной ошибки:

  • /coupons/get;
  • /coupons/results;
  • /coupons/calculated;
  • /coupons/active;
  • /balance.

Не повторяйте автоматически POST /api/partner/coupons/place после неопределенной сетевой или серверной ошибки, пока не исключена возможность, что первый запрос был обработан. Иначе один выбор пользователя может создать несколько купонов.

Бизнес-ошибки создания 501–504 являются результатом проверки исхода, а не транспортной ошибкой. Их нельзя обрабатывать как обычный автоматический повтор неизмененного запроса.

Диагностические поля

date

date на верхнем уровне — время формирования ответа:

{
  "date": 1784970000000
}

Это Unix timestamp в миллисекундах.

Не путайте его с:

  • body.date — временем создания купона;
  • event_date — временем начала события;
  • calculate_date — временем расчета.

time_ms

{
  "time_ms": 12
}

Показывает время обработки запроса сервером в миллисекундах. Поле полезно для мониторинга, но не включает всю сетевую задержку на стороне партнера.

path

{
  "path": "/api/partner/coupons/get"
}

Помогает определить, какой маршрут сформировал ответ. Не используйте path как бизнес-идентификатор купона или операции.

Даты и null

Даты API передаются в Unix-миллисекундах:

{
  "date": 1784970000000,
  "calculate_date": null
}

До расчета calculate_date всегда равен null. Значение 0 для нерассчитанного купона или ставки не используется.

Не заменяйте null числом 0: эти значения имеют разный смысл.

Десятичные числа

Суммы, коэффициенты и выплаты передаются как JSON-числа без фиксированного количества знаков после запятой:

{
  "amount": 10,
  "coef": 1.5,
  "real_win": 15
}

Интеграция не должна зависеть от текстового количества знаков:

10 = 10.0 = 10.00

Партнер самостоятельно определяет правила отображения и округления. Для хранения денег рекомендуется десятичный тип данных.

Необязательные и отсутствующие поля

В зависимости от endpoint и результата отдельные необязательные поля оболочки могут быть null или отсутствовать.

Клиент должен:

  • проверять наличие необязательного поля;
  • корректно обрабатывать null;
  • не подменять отсутствующее поле произвольным значением;
  • не считать пустой массив ошибкой;
  • не зависеть от порядка JSON-полей.

Формат старого API

Старые маршруты используют прежнюю оболочку из пяти полей:

{
  "code": 1,
  "body": {},
  "error_code": null,
  "error_message": null,
  "date": 1784970000000
}

В ней отсутствуют:

  • time_ms;
  • path.

Для старого защищенного маршрута неверный JWT может возвращаться как бизнес-ошибка с HTTP 200:

{
  "code": 0,
  "body": false,
  "error_code": 1003,
  "error_message": "Wrong token",
  "date": 1784970000000
}

Не применяйте обработчик старой структуры к новому API без учета дополнительных полей и нового поведения HTTP 401/403.

Подробнее:

Callback использует другой контракт

Входящий callback не оборачивается в code, body, error_code и другие поля клиентского API.

Payload callback начинается с:

{
  "event": "coupons.settled",
  "batchId": "...",
  "couponCount": 1,
  "coupons": []
}

Ответ партнера на callback также имеет отдельный контракт:

{
  "success": true,
  "processed": 1
}

Не используйте общую оболочку клиентского API для обработки callback.

Подробнее: «Callback результатов».

Контрольный список

  • Сначала проверяется HTTP-статус.
  • Затем проверяется code.
  • При code = 0 читается error_code.
  • error_message не используется как программный идентификатор.
  • Форма body определяется по endpoint.
  • Пустой массив при code = 1 считается успехом.
  • date читается как Unix-миллисекунды.
  • time_ms используется только для диагностики.
  • calculate_date до расчета равен null, а не 0.
  • Десятичные значения не зависят от количества знаков.
  • Создание купона не повторяется вслепую.
  • Callback обрабатывается по отдельному контракту.

Следующий раздел: «Коды ошибок».