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

Polling Fallback

Polling is the periodic retrieval of coupon states through the SportAPI Coupon Settlement System Client API.

It can be used:

  • as the primary way to receive results when callbacks are not enabled;
  • as fallback reconciliation while callbacks are operating;
  • to recover after the callback endpoint was temporarily unavailable;
  • to check a specific coupon at the request of a user or support team.

Callbacks and polling are not mutually exclusive. The most reliable approach is to use callbacks for fast updates and additionally reconcile settled coupons through the API at regular intervals.

Every request in this section requires a valid Bearer JWT:

Authorization: Bearer <token>

Available verification methods

TaskMethod
Find coupons finally settled during the last N minutesGET /api/partner/coupons/calculated
Retrieve the current state of known coupons as a listPOST /api/partner/coupons/results with coupon_ids
Find coupons by their placement timePOST /api/partner/coupons/results with start_date and end_date
Check one couponGET /api/partner/coupons/get
Retrieve all active couponsGET /api/partner/coupons/active

Use /api/partner/** endpoints for new integrations.

For example, the partner may send a request every 5 minutes:

GET /api/partner/coupons/calculated?time=10 HTTP/1.1
Host: coupon-api.example.com
Authorization: Bearer <token>
Accept: application/json

In this example:

  • polling runs every 5 minutes;
  • every request checks the last 10 minutes again;
  • adjacent time windows overlap.

The overlap prevents a result from being missed if one run does not occur because of an application restart, network error, or temporary API outage.

Receiving an already processed coupon again is normal. The partner system must update the existing record rather than create a new coupon or repeat a financial operation.

The partner chooses the polling interval according to the required update speed and its own load. We recommend requesting a period at least twice as long as the normal polling interval.

Recently settled coupons

Use:

GET /api/partner/coupons/calculated?time={minutes}

Example:

BASE_URL="https://coupon-api.example.com"
TOKEN="<jwt-token>"

curl "$BASE_URL/api/partner/coupons/calculated?time=10" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

The time parameter defines how many recent minutes of finally settled coupons should be returned.

Parameter rules:

ConditionBehavior
time is omittedThe last 5 minutes are used.
time <= 0The value is replaced with 5 minutes.
time > 120The last 120 minutes are used.
Supported working range1 to 120 minutes.

Coupons are selected by final settlement time, not placement time.

The method does not return:

  • active coupons;
  • coupons belonging to other partners.

This endpoint is convenient for regular polling, but one call is not sufficient to recover after an interruption longer than 120 minutes.

Checking a list of known coupons

If the partner system contains coupons for which a current final result has not yet been recorded, request them by code:

POST /api/partner/coupons/results HTTP/1.1
Host: coupon-api.example.com
Authorization: Bearer <token>
Content-Type: application/json

{
  "coupon_ids": [
    "000000000272",
    "000000000273"
  ]
}

One request may contain no more than 100 codes.

Behavior:

  • duplicate codes in the input array are removed;
  • unknown coupons and coupons belonging to other partners are omitted from the response;
  • the coupon order in the response may differ from the order of coupon_ids;
  • the response may contain fewer entries than the number of submitted codes.

Match results by coupon_code, not by array position.

The response uses the common format:

{
  "code": 1,
  "body": {
    "query_type": "ids",
    "coupons": []
  },
  "error_code": null,
  "error_message": null,
  "date": 1784970000000,
  "time_ms": 8,
  "path": "/api/partner/coupons/results"
}

The body.coupons array contains the complete current models of the coupons that were found.

This request is especially useful:

  • after a polling interruption longer than 120 minutes;
  • to periodically check coupons that are locally considered incomplete;
  • after receiving status 15, while waiting for a new result;
  • for batch reconciliation of partner data with the API.

Searching by placement period

The second POST /api/partner/coupons/results mode finds coupons by placement time:

POST /api/partner/coupons/results HTTP/1.1
Host: coupon-api.example.com
Authorization: Bearer <token>
Content-Type: application/json

{
  "start_date": 1784880000000,
  "end_date": 1784966400000
}

start_date and end_date are Unix timestamps in milliseconds.

Restrictions:

  • both values are required;
  • end_date must be greater than start_date;
  • one interval cannot exceed 24 hours;
  • dates and coupon_ids cannot be submitted together;
  • a parameter error returns error_code = 1002.

In the response, body.query_type is time.

Important. This mode selects coupons by placement time, not settlement time. It is suitable for restoring the list of coupons placed during a particular period, but it does not replace /calculated when searching for results that appeared later.

For example, if a coupon was placed one week ago and received a new result today, a request for today’s placement period will not find it. Use /calculated or a request with its known coupon_code.

Checking one coupon

For a targeted check, use:

GET /api/partner/coupons/get?coupon_code=000000000272 HTTP/1.1
Host: coupon-api.example.com
Authorization: Bearer <token>
Accept: application/json

Always submit the complete coupon_code as a string, including leading zeros.

If the coupon is not found or belongs to another partner, the API returns:

{
  "code": 0,
  "error_code": 471,
  "error_message": "Coupon not found"
}

This method is suitable for:

  • opening a coupon detail page;
  • checking a result in response to a user request;
  • resolving a discrepancy between a callback and local data;
  • retrieving the full model when a callback does not contain the required fields.

Active coupons

Retrieve all active partner coupons with:

GET /api/partner/coupons/active HTTP/1.1
Host: coupon-api.example.com
Authorization: Bearer <token>
Accept: application/json

No parameters are required. The method returns active coupons in the full format.

Use it to restore the list of incomplete coupons, but not as a replacement for /calculated: a completed coupon disappears from the active list and must be retrieved through result methods.

Combined callback and polling processing

Callbacks contain batchId, while polling responses do not. Deduplication therefore occurs at two levels:

SourceLinking keyRule
CallbackbatchIdA repeated batch is not processed again.
Callback and pollingcoupon_codeBoth update the same local coupon record.
Bet within a couponcoupon_code + id or coupon_code + uuidThe existing bet is updated.

In the full polling model, a bet has the field events_data[].id. In a callback, the same bet is provided as events_data[].uuid in string form.

Do not create separate local coupons for callback and polling data. Both sources describe the state of the same coupon.

Do not credit funds only because a final coupon appears in polling again. The financial operation must be protected by a unique key and performed once for the specific settlement state.

If callback and polling data arrive almost simultaneously and differ, request the current full model through GET /api/partner/coupons/get and synchronize the local record with it. Do not decide which state is newer only from the order in which the HTTP requests arrived.

Recovery after an outage

Interruption of no more than 120 minutes

  1. Resume regular polling.
  2. Call /calculated with a window that fully covers the interruption.
  3. Update the returned coupons by coupon_code.
  4. Resume the schedule with overlapping windows.

Example after a 40-minute interruption:

GET /api/partner/coupons/calculated?time=50

The small margin prevents results at the interval boundary from being missed.

Interruption longer than 120 minutes

  1. Retrieve from your database the codes of coupons whose current final result has not yet been confirmed.
  2. Split them into groups of no more than 100 codes.
  3. Request each group through POST /api/partner/coupons/results with coupon_ids.
  4. If necessary, restore coupons placed during the outage using placement periods of no more than 24 hours.
  5. Match every result by coupon_code.
  6. After reconciliation, return to regular /calculated polling with overlapping windows.

If only one problematic coupon is known locally, use /coupons/get.

Processing the response

HTTP 200 means that the server processed the HTTP request, but the business result must be checked separately:

  1. check the HTTP status;
  2. parse the JSON;
  3. verify that the top-level code equals 1;
  4. process the entire coupon array;
  5. update coupons and bets idempotently;
  6. perform financial operations only for settlement transitions not yet processed.

Do not treat an empty array as an error. It may mean that no matching coupons exist in the selected window.

After a transport error or temporary API outage, do not move the time window forward. Repeat the same request and, after recovery, use a window with a safety margin.

Checklist

  • Polling operates even when callbacks are enabled.
  • Regular request windows overlap.
  • The time value does not exceed 120 minutes.
  • Known coupon_code values are used after a long interruption.
  • Requests by code contain no more than 100 entries.
  • Date searches use placement time rather than settlement time.
  • coupon_code is stored as a string with leading zeros.
  • The entire response array is processed, not only the first coupon.
  • Callback and polling data update the same local record.
  • Receiving the same result again does not repeat a debit or credit.
  • Financial actions use real_win, not potential_win.
  • Status 15 is not treated as final.

Detailed descriptions of the methods begin in the next section: Retrieving a single coupon.