SportAPI Documentation
EN
C Product documentationCoupon API
v1
Service & pricing ↗ Get access ↗
Coupon API / API response format

API Response Format

The new Client API methods use a common JSON envelope.

Key rule:

HTTP 200 confirms that the HTTP request was processed, but does not always mean that the business operation succeeded. Always check the code field.

Successful Response

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

Business Error

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

A business error usually also returns HTTP 200.

Envelope Fields

FieldTypeDescription
codeintegerBusiness operation result: 1 — success, 0 — error.
bodyany/nullOperation result or additional details. Its structure depends on the endpoint.
error_codeinteger/nullMachine-readable business error code. Usually null on success.
error_messagestring/nullText error description. Usually null on success.
dateintegerResponse generation time as Unix milliseconds.
time_msintegerServer-side request processing time in milliseconds.
pathstringPath of the method that processed the request.

code and error_code

These fields serve different purposes:

code       → whether the business operation succeeded
error_code → why the operation failed

Example:

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

Here:

  • the HTTP API is available;
  • the request was processed;
  • the coupon was not created;
  • the reason is a blocked outcome.

Use error_code in program logic. error_message is intended for diagnostics and may be refined, so do not compare it as a stable error identifier.

The body Shape Depends on the Method

body does not have one type across the whole API.

Methodbody typeData location
GET /api/partner/healthstringDirectly in body.
POST /api/partner/loginobjectToken in body.token.
POST /api/partner/coupons/placeobjectCoupons in body.coupons[].
GET /api/partner/coupons/getobjectOne coupon directly in body.
POST /api/partner/coupons/resultsobjectbody.query_type and body.coupons[].
GET /api/partner/coupons/calculatedarrayCoupons directly in body[].
GET /api/partner/coupons/activearrayCoupons directly in body[].
GET /api/partner/balanceobjectBalance in body.balance.

Do not use one universal path such as body.coupons[0] for every endpoint.

Coupon Creation

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

Retrieving One Coupon

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

Active or Settled Coupons

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

Empty Successful Result

An empty array is not an error:

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

This response is possible, for example, when:

  • there are no active coupons;
  • there are no settled coupons in the selected window;
  • none of the supplied codes were found in the available data.

For /coupons/results, the empty array is inside an object:

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

body in a Business Error

For an error, body may be:

  • null;
  • an object with additional details;
  • an array in the compatible legacy contract.

For example, when odds change, the new API returns the reasons in 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"
}

Therefore, with code = 0, first read error_code, then process the body structure documented for that error.

HTTP Status and Business Result

HTTP resultMeaningClient action
2xx, code = 1Operation completed.Process the data from body.
2xx, code = 0Business error.Read error_code, error_message, and additional data.
400Invalid JSON or parameter format.Correct the request.
401JWT is missing, invalid, expired, or revoked.Log in again and use a new JWT.
403The token lacks the required role or access is denied.Check the token type and account state.
5xxServer or temporary error.Record the error and use a safe retry strategy.

Checking only the HTTP status gives an incorrect result for a business error:

HTTP 200 + code 0 ≠ success
1. Send the HTTP request.
2. Check the transport result.
3. With HTTP 401, obtain a new JWT.
4. With HTTP 403, check access.
5. With HTTP 5xx, use the temporary-error strategy.
6. For a JSON response, check code.
7. With code = 0, process error_code.
8. With code = 1, parse body according to the specific endpoint contract.

Pseudocode:

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)

Retrying Requests

The retry strategy depends on the operation.

Read methods can be safely retried after a temporary network or server error:

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

Do not automatically retry POST /api/partner/coupons/place after an indeterminate network or server error until you have ruled out the possibility that the first request was processed. Otherwise, one user selection may create multiple coupons.

Coupon creation business errors 501–504 are outcome-validation results, not transport errors. Do not treat them as a normal automatic retry of the unchanged request.

Diagnostic Fields

date

Top-level date is the response generation time:

{
  "date": 1784970000000
}

It is a Unix timestamp in milliseconds.

Do not confuse it with:

  • body.date — coupon creation time;
  • event_date — event start time;
  • calculate_date — settlement time.

time_ms

{
  "time_ms": 12
}

This is the server-side request processing time in milliseconds. The field is useful for monitoring, but does not include the partner’s total network latency.

path

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

This helps identify which route formed the response. Do not use path as a business identifier for a coupon or operation.

Dates and null

API dates use Unix milliseconds:

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

Before settlement, calculate_date is always null. The value 0 is not used for an unsettled coupon or bet.

Do not replace null with the number 0: they have different meanings.

Decimal Numbers

Amounts, odds, and payouts are JSON numbers without a fixed number of decimal places:

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

The integration must not depend on the textual number of decimal places:

10 = 10.0 = 10.00

The partner defines its own display and rounding rules. A decimal data type is recommended for storing money.

Optional and Absent Fields

Depending on the endpoint and result, individual optional envelope fields may be null or absent.

The client must:

  • check whether an optional field is present;
  • handle null correctly;
  • not replace an absent field with an arbitrary value;
  • not treat an empty array as an error;
  • not depend on JSON field order.

Legacy API Format

Legacy routes use the previous five-field envelope:

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

It does not contain:

  • time_ms;
  • path.

For a protected legacy route, an invalid JWT may be returned as a business error with HTTP 200:

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

Do not apply a legacy-structure handler to the new API without accounting for the additional fields and new HTTP 401/403 behavior.

More information:

Callback Uses a Different Contract

An incoming callback is not wrapped in code, body, error_code, or other Client API fields.

The callback payload begins with:

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

The partner response to a callback also has a separate contract:

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

Do not use the common Client API envelope to process callbacks.

See Result Callbacks for details.

Checklist

  • The HTTP status is checked first.
  • Then code is checked.
  • With code = 0, error_code is read.
  • error_message is not used as a programmatic identifier.
  • The body shape is determined by the endpoint.
  • An empty array with code = 1 is treated as success.
  • date is read as Unix milliseconds.
  • time_ms is used only for diagnostics.
  • Before settlement, calculate_date is null, not 0.
  • Decimal values do not depend on the number of displayed digits.
  • Coupon creation is not retried blindly.
  • Callbacks are processed according to their separate contract.

Next section: Error Codes.