Coupon and Bet Model
The complete model contains:
- general coupon data;
- amounts and odds;
- status and settlement dates;
- the
events_dataarray with every coupon bet.
One events_data object describes one accepted bet within the coupon.
General structure
{
"coupon_code": "000000000272",
"amount": 10,
"status": 0,
"events_count": 1,
"events_data": [
{
"id": 84521,
"game_id": 737779544,
"bet_id": 1,
"status": 0
}
]
}
Coupon and bet statuses use different reference tables. Always consider the level at which the field appears.
Identifiers
| Field | Where it is provided | Purpose |
|---|---|---|
coupon_code | Full model and callback | Public coupon code. |
events_data[].id | Full model | Internal accepted-bet ID. |
events_data[].uuid | Callback | The same bet ID in string form. |
game_id | Full model and callback | Sporting event or sub-event ID. |
bet_id | Full model | Outcome ID within a bet group. |
batchId | Callback only | ID of a specific callback batch version. |
Do not confuse these values:
coupon_code → coupon
id / uuid → specific bet within the coupon
game_id → sporting event
bet_id → outcome in the sports line
batchId → callback batch
For local bet storage, use this composite key:
coupon_code + events_data[].id
When processing a callback, match the string uuid to the stored id.
game_id and bet_id may repeat across different coupons, so they do not replace the internal accepted-bet ID.
Coupon fields
General data
| Field | Type | Description |
|---|---|---|
coupon_code | string | Public coupon code, usually consisting of 12 digits. |
date | integer | Coupon placement date, as Unix milliseconds. |
status | integer | Current status of the entire coupon. |
coupon_type | integer | 1 — single; 2 — accumulator. |
events_count | integer | Number of bets in the coupon. |
events_data | array | Complete list of coupon bets. |
has_return | boolean | true when the coupon contains a returned bet. |
asian | boolean | true when the coupon contains an Asian market. |
events_count should describe the number of bet objects, but always iterate over the actual events_data array when processing a response.
Amounts
| Field | Type | Description |
|---|---|---|
amount | number | Stake amount. |
win | number | Current displayed payout: before settlement it normally equals the potential payout; after settlement it contains the actual value with returns accounted for. |
potential_win | number | Original potential payout when the coupon was placed. |
real_win | number/null | Actual payout after settlement. null before a final result. |
Use real_win for financial crediting after final settlement.
Do not use potential_win as the actual payout. It is only the potential result calculated when the coupon was placed.
In brief:
amount → amount staked
potential_win → amount that could be received at placement time
real_win → amount actually payable after settlement
The win field is retained for display and compatibility. When the partner needs to change the user balance, real_win should be the primary field.
Coupon odds
| Field | Type | Description |
|---|---|---|
coef | number | Working odds: original before settlement; may account for returns after settlement. |
original_coef | number | Original coupon odds fixed at placement time. |
calculate_coef | number/null | Final settlement multiplier. null before settlement. |
In brief:
original_coef → odds at placement time
coef → current displayed value
calculate_coef → final settlement multiplier
For a financial operation, do not independently recalculate the payout from the displayed coef. Use the provided real_win value.
Settlement date
| Field | Type | Description |
|---|---|---|
calculate_date | integer/null | Time of the latest settled coupon bet, as Unix milliseconds. |
Before settlement, the value is always null:
{
"calculate_date": null
}
The value 0 is not used for an unsettled coupon.
Coupon statuses
| Code | Name | Meaning | Final |
|---|---|---|---|
0 | NEW | The coupon is active or an accumulator is partially settled. | No |
2 | WIN | The coupon won. | Yes |
4 | LOSE | The coupon lost. | Yes |
8 | RETURN | The coupon was fully returned. | Yes |
15 | UPDATE | The coupon was returned for recalculation and awaits a new result. | No |
Status 15 does not mean a regular card update. The corresponding bet has status 4, and the partner waits for a new settlement result.
Financial actions for these statuses are described in Statuses and payout calculation.
Bet fields in events_data
Event and sub-event IDs
| Field | Type | Description |
|---|---|---|
id | integer/null | Internal accepted-bet ID. |
game_id | integer | ID of the event or sub-event on which the bet was placed. |
main_game_id | integer/null | Main game ID from the provider data. |
is_sub_game | boolean | true when the bet belongs to a sub-event or period. |
parent_game_id | integer/null | Parent event ID for a sub-event. |
sub_game_key | string/null | Stable internal sub-event key. |
sgame_id | string/null | Sub-event ID from the sports line provider. |
game_num | integer/null | Additional provider game number. |
stat_id | string/null | Provider statistics ID. |
dop_name | string/null | Name of the period, half, set, inning, or another sub-event. |
For a main game, some sub-event fields are null.
Main game example:
{
"game_id": 737779544,
"main_game_id": 737779544,
"is_sub_game": false,
"parent_game_id": null,
"sub_game_key": null,
"dop_name": null
}
For a sub-event, game_id identifies the selected sub-event, while main_game_id and parent_game_id associate it with the main match.
Original pointer and sports line type
| Field | Type | Description |
|---|---|---|
raw_pointer | string | Original bet pointer used when the coupon was placed. |
line_type | string | line for prematch or live for live betting. |
is_live | boolean | true when the bet was created from the live sports line. |
raw_pointer is stored without modification:
line#737779544#1#1#0#1.85
It is useful for technical reconciliation, but does not replace events_data[].id as the accepted-bet ID.
Sport, tournament, and participants
| Field | Type | Description |
|---|---|---|
sport_id | integer/null | Sport ID. |
sport_name | string/null | Full localized sport name. |
tournament_id | integer/null | Tournament ID. |
tournament | string/null | Full localized tournament name. |
event_date | integer/null | Scheduled event start, as Unix milliseconds. |
opp1 | string/null | Full name of the first team or participant. |
opp2 | string/null | Full name of the second team or participant. |
team1_id | integer/null | First team or participant ID. |
team2_id | integer/null | Second team or participant ID. |
opp_icon1 | integer/null | Compatible first-participant ID; equal to team1_id. |
opp_icon2 | integer/null | Compatible second-participant ID; equal to team2_id. |
opp_icon1 and opp_icon2 are legacy-compatible names. Despite the word icon, these fields contain participant IDs, not an image URL or file.
Use team1_id and team2_id in new code.
Bet group and outcome
| Field | Type | Description |
|---|---|---|
bet_group_id | integer | Bet group ID. |
bet_group_name | string/null | Full localized bet group name. |
bet_id | integer | Outcome ID within the group. |
bet_name | string/null | Full localized outcome name. |
rate | string | Outcome parameter: total, handicap, or 0 when no parameter is required. |
bet_name may already include the resolved outcome parameter and player name when applicable.
Example:
{
"bet_group_id": 17,
"bet_group_name": "Goal Totals",
"bet_id": 9,
"bet_name": "Total Over 2.5",
"rate": "2.5"
}
Bet odds and settlement
| Field | Type | Description |
|---|---|---|
status | integer | Current bet settlement status. |
coef | number | Bet odds fixed at placement time. |
calc_coef | number/null | Bet settlement multiplier. null before settlement. |
calculate_date | integer/null | Bet settlement time, as Unix milliseconds. null before settlement. |
settlement_reason_code | string/null | Stable machine-readable settlement or return reason code. null before settlement. |
settlement_reason | string/null | Settlement or return reason text. null before settlement. |
calc_coef depends on the bet result:
| Status | Result | calc_coef |
|---|---|---|
0 | Unsettled | null |
1 | Win | Original coef |
2 | Loss | 0 |
3 | Return | 1 |
4 | Awaiting recalculation | null |
21 | Half win | (coef + 1) / 2 |
22 | Half loss | 0.5 |
23 | Push | 1 |
calc_coef is the settlement multiplier of a specific bet, while coupon-level calculate_coef is the result for the entire coupon.
Settlement reason
The reason fields supplement the numeric bet status:
settlement_reason_codeis suitable for program processing and analytics;settlement_reasoncontains explanatory text and is not a stable program value.
Example codes:
| Code | Meaning |
|---|---|
MATCH_CANCELLED | The match was cancelled. |
MATCH_POSTPONED | The match was postponed. |
MARKET_PUSH | The market was settled as a push. |
REMOTE_WIN | The settlement source returned a win. |
REMOTE_LOSE | The settlement source returned a loss. |
REMOTE_RETURN | The settlement source returned the bet. |
REMOTE_HALF_WIN | The settlement source returned a half win. |
REMOTE_HALF_LOSE | The settlement source returned a half loss. |
REMOTE_PUSH | The settlement source returned a push. |
AUTOMATIC_MARKET_RETURN | The return was determined by market rules. |
AUTOMATIC_SETTLEMENT | Standard result settlement. |
The list of codes may grow. Do not reject a response because of an unknown settlement_reason_code: store the value and determine the financial result from status, calc_coef, and the final real_win.
End-user notification
For a clear interface message:
- read
settlement_reason_code; - map a known code to the partner’s localized text;
- if the code is unknown, use a non-empty
settlement_reasonas a fallback explanation; - store both original fields for subsequent reconciliation.
For example:
| Code | Example user message |
|---|---|
MATCH_POSTPONED | “The match was postponed. The bet was settled according to the return rules.” |
MATCH_CANCELLED | “The match was cancelled. The bet was settled according to the return rules.” |
MARKET_PUSH | “The selected market was settled as a return.” |
Do not assume that settlement_reason is translated into the coupon language: the field may contain the original text from the settlement source. The reason explains the result and does not replace status, calc_coef, or real_win.
These fields describe the reason for a completed settlement or return, not the current state of the sporting event. Both fields are null before settlement; the API does not guarantee a separate advance notification of a postponed or cancelled match through these fields.
Event score
| Field | Type | Description |
|---|---|---|
bet_score | string | Legacy API compatibility field containing the original bet pointer. |
calculate_score | string/null | Final full score used for settlement. |
placement_score_full | string/null | Full score when the bet was placed. |
placement_score_periods | string/null | Period-by-period score when the bet was placed. |
calculation_score_full | string/null | Full score at settlement time. |
calculation_score_periods | string/null | Period-by-period score at settlement time. |
timer | integer/null | Event timer, when available. |
Important. Despite its name,
bet_scoreis not the match score. It is a compatibility field containing the original bet pointer. Usecalculate_scoreand the extendedplacement_*/calculation_*fields for scores.
The score format depends on the sport and provider data. Store it as a string and do not independently determine the bet result from this field alone.
Complete active coupon example
{
"coupon_code": "000000000272",
"amount": 10,
"win": 18.5,
"potential_win": 18.5,
"real_win": null,
"coef": 1.85,
"original_coef": 1.85,
"calculate_coef": null,
"has_return": false,
"date": 1784970000000,
"status": 0,
"asian": false,
"calculate_date": null,
"coupon_type": 1,
"events_count": 1,
"events_data": [
{
"id": 84521,
"game_id": 737779544,
"main_game_id": 737779544,
"is_sub_game": false,
"parent_game_id": null,
"sub_game_key": null,
"raw_pointer": "line#737779544#1#1#0#1.85",
"line_type": "line",
"is_live": false,
"bet_group_id": 1,
"bet_group_name": "Match Result",
"bet_id": 1,
"bet_name": "First Team to Win",
"sport_id": 1,
"sport_name": "Football",
"tournament_id": 10001,
"tournament": "National League",
"event_date": 1784971800000,
"status": 0,
"opp1": "Team A",
"opp2": "Team B",
"coef": 1.85,
"calc_coef": null,
"bet_score": "line#737779544#1#1#0#1.85",
"calculate_date": null,
"calculate_score": null,
"settlement_reason_code": null,
"settlement_reason": null,
"placement_score_full": null,
"placement_score_periods": null,
"calculation_score_full": null,
"calculation_score_periods": null,
"timer": null,
"dop_name": null,
"rate": "0",
"sgame_id": null,
"game_num": null,
"stat_id": null,
"team1_id": 101,
"team2_id": 102,
"opp_icon1": 101,
"opp_icon2": 102
}
]
}
After a single wins, the primary settlement fields change:
{
"status": 2,
"real_win": 18.5,
"calculate_coef": 1.85,
"calculate_date": 1784973600000,
"events_data": [
{
"id": 84521,
"status": 1,
"calc_coef": 1.85,
"calculate_date": 1784973600000,
"calculate_score": "2:1",
"settlement_reason_code": "AUTOMATIC_SETTLEMENT",
"settlement_reason": "Calculated automatically",
"calculation_score_full": "2:1"
}
]
}
This is a shortened snapshot of the changes, not a separate response format.
Nullable fields
null is a normal value when data:
- has not yet been calculated;
- does not apply to the particular sport;
- is unavailable from the provider;
- applies only to live betting or sub-events.
Do not automatically replace null with numeric 0 or an empty string: these values may have a different meaning in the contract.
It is particularly important to preserve:
real_win = null before final settlement
calculate_coef = null before final settlement
calculate_date = null before settlement
calc_coef = null before bet settlement
settlement_reason_code = null before bet settlement
settlement_reason = null before bet settlement
Dates and decimal values
All dates in this model are Unix timestamps in milliseconds:
1784973600000
Do not confuse them with Unix timestamps in seconds.
Amounts and odds are decimal numbers without a fixed number of decimal places. The partner defines the display and rounding rules in its own system.
Use a decimal data type rather than a binary float to store money and perform financial calculations.
Language of names
Sport, tournament, participant, bet group, and outcome names use the lang specified when the coupon was placed.
The API supports approximately 50 languages. Submit a two-letter language code; the full list is not published in this documentation.
The language is fixed when the coupon is placed. An existing coupon cannot currently be retrieved in another translation. Support for multiple language variants of one coupon is in development.
Differences between the full model and callback
A callback provides a settlement snapshot rather than the complete coupon record.
| Full API model | Callback | Note |
|---|---|---|
coupon_code | coupon_code | The same coupon. |
events_data[].id | events_data[].uuid | The same bet ID; provided as a string in the callback. |
real_win | realWin | Actual payout. |
calculate_coef | calculate_coefficient | Coupon settlement multiplier. |
events_data[].calc_coef | events_data[].calculate_coefficient | Bet settlement multiplier. |
events_data[].settlement_reason_code | events_data[].settlement_reason_code | Stable settlement reason code. |
events_data[].settlement_reason | events_data[].settlement_reason | Settlement reason text. |
| Complete record | Short settlement snapshot | Names, amount, and some original data are absent from callbacks. |
No batchId | Includes batchId | batchId identifies a delivery batch version. |
Callbacks do not include, in particular:
amount;- sport, tournament, team, market, and outcome names;
- some original coupon data.
If callback processing requires missing fields, store them when the coupon is placed or retrieve the full model through the Client API.
Currency
The currency field is submitted when placing a coupon but is not included in the full coupon response model or callbacks.
If the partner needs to display the currency or associate financial operations with it, store the submitted currency value in the partner’s system after successful coupon placement.
Any string identifier for a regular, virtual, internal, or fictional currency is supported.
Recommended stored data
The partner decides which data is required. For a reliable integration, store at least:
Coupon level
coupon_code;amount;- the
currencysubmitted at placement, when used; coupon_type;status;real_win;original_coef;calculate_coef;date;calculate_date.
Bet level
coupon_code;events_data[].id;raw_pointer;game_id;bet_group_id;bet_id;coef;status;calc_coef;calculate_date;settlement_reason_code;settlement_reasonwhen the text is required for logs or display.
For display, also store the required names, participants, and score data.
Storing the entire response is optional. However, coupon_code must always be stored: it is the primary linking key between the partner’s system and the SportAPI Coupon Settlement System.
Checklist
coupon_codeis stored as a string with leading zeros.- Coupons and bets are stored as separate related entities.
- A bet is identified by
coupon_code + id. - Callback
uuidis matched to full-modelid. batchIdis not used as a coupon or bet ID.real_winis used for the final payout.potential_winis not used as the actual payout.- Coupon and bet statuses are read from different reference tables.
calculate_dateisnull, not0, before settlement.bet_scoreis not interpreted as the match score.- Nullable fields are handled without artificial value substitution.
settlement_reason_code, notsettlement_reasontext, is used for reason logic.- Dates are read as Unix milliseconds.
- The partner stores currency at placement when required.
- The language of names is fixed when the coupon is placed.
Next section: Cashout.