Odds and Betting Market Data Model
What an Odds Object Represents
Each object inside oc_list describes a specific betting selection: a team win, a draw,
a total, a handicap, a player event, or another available outcome.
Example of a standard Prematch selection:
{
"oc_group_name": "1X2",
"oc_name": "W1",
"oc_rate": 1.525,
"oc_size": 0,
"oc_pointer": "730321837|1|1|0",
"oc_block": false,
"op_id": null
}
The complete field list is also available in the Sport Line API Field Reference.
Where Odds Are Returned
| Method | Contents of game_oc_list |
|---|---|
events | Short list of the match’s main markets and best odds |
event | Full available list of markets and odds for a specific match |
topmatches?full=true | Short list equivalent to events |
toplist?full=true | Short list equivalent to events |
topmatches and toplist without full=true | No odds |
search | No odds |
To retrieve all available betting selections for a chosen match, request event using
its game_id.
Betting Market in game_oc_list
game_oc_list contains betting markets. Each market groups related selections, such as
1X2, totals, handicaps, or player-specific bets.
| Field | Type | Description |
|---|---|---|
group_id | number | Technical betting market ID |
group_name | string | Market name in the requested language |
columns | number | Recommended number of columns for displaying the market |
oc_list | array | Market selections; the structure depends on the method |
Use group_id for application logic. group_name and oc_group_name are intended for
display and depend on the requested language.
Market Structure in events
In the short match list, oc_list is a regular flat selection array:
game_oc_list[]
└── betting market
└── oc_list[]
└── selection
Actual shortened example:
{
"group_id": 1,
"group_name": "1X2",
"columns": 3,
"oc_list": [
{
"oc_name": "W1",
"oc_rate": 1.36,
"oc_pointer": "745865082|1|1|0"
},
{
"oc_name": "X",
"oc_rate": 5.35,
"oc_pointer": "745865082|1|2|0"
},
{
"oc_name": "W2",
"oc_rate": 9.4,
"oc_pointer": "745865082|1|3|0"
}
]
}
columns indicates how to lay out the selections in the interface, but the oc_list
array in events is not divided into nested columns.
The same short structure is used by topmatches?full=true and
toplist?full=true.
Market Structure in event/group
In the detailed response for a specific match, the outer oc_list array contains
columns, and each nested array contains the selections for that column:
game_oc_list[]
└── betting market
└── oc_list[] ← market columns
└── selections in the selected column
columns defines the recommended layout, but it is not a count of the nested arrays.
In actual responses, the number of items in the outer oc_list may differ from
columns. Do not require these values to be equal when validating a response.
The group format is recommended for a specific match because the API already:
- separates selections into betting markets;
- creates columns within each market;
- sorts related values within the columns;
- provides the recommended column count in
columns.
Preserve the market, column, and selection order returned by the API. There is no need to rebuild the columns or re-sort their values on the client side.
Market Examples
1X2: Three Columns
For the 1X2 market, the API returned three columns: first-team win, draw, and
second-team win.
{
"group_id": 1,
"group_name": "1X2",
"columns": 3,
"oc_list": [
[
{
"oc_name": "W1",
"oc_rate": 1.525,
"oc_size": 0,
"oc_pointer": "730321837|1|1|0"
}
],
[
{
"oc_name": "X",
"oc_rate": 5.08,
"oc_size": 0,
"oc_pointer": "730321837|1|2|0"
}
],
[
{
"oc_name": "W2",
"oc_rate": 6.15,
"oc_size": 0,
"oc_pointer": "730321837|1|3|0"
}
]
]
}
Total: Two Columns
In a Total market, the first column contains Over selections and the second contains
Under selections. Values within each column are already sorted by oc_size.
{
"group_id": 17,
"group_name": "Total",
"columns": 2,
"oc_list": [
[
{ "oc_name": "Over 0.5", "oc_size": "0.5", "oc_rate": 1.019 },
{ "oc_name": "Over 1", "oc_size": "1", "oc_rate": 1.02 },
{ "oc_name": "Over 1.5", "oc_size": "1.5", "oc_rate": 1.085 }
],
[
{ "oc_name": "Under 0.5", "oc_size": "0.5", "oc_rate": 22.0 },
{ "oc_name": "Under 1", "oc_size": "1", "oc_rate": 16.5 },
{ "oc_name": "Under 1.5", "oc_size": "1.5", "oc_rate": 5.45 }
]
]
}
This example is shortened. In the full response, each column contains more values.
Player-specific Bets
A player-specific market may have columns: 1 while containing several nested sets of
selections. In the saved Prematch response, the “Who Will Score Goal” market contained
two such sets. Use op_id to distinguish selections belonging to different players or
participants.
The available markets, number of columns, and set of selections depend on the sport and
the specific match. Do not create a fixed schema that supports only 1X2, totals, or
handicaps.
Selection Fields
| Field | Type | Description |
|---|---|---|
oc_group_name | string | Betting market name in the requested language |
oc_name | string | Name of the specific selection in the requested language |
oc_rate | number | Current decimal odds |
oc_size | string or number | Total, handicap, or another selection parameter; usually 0 for selections without a separate value |
oc_pointer | string | Primary composite code of the bet or selection. It will be passed to the bet placement and settlement system |
oc_block | boolean | false means the selection is available; true means it is blocked and unavailable |
op_id | number or null | Player or participant ID for a player-specific selection, when applicable |
oc_group_name
oc_group_name identifies the market to which the selection belongs:
{
"oc_group_name": "Total"
}
The name depends on the requested language. Do not use it as a permanent technical ID or link data between languages using the name text.
The technical market ID is available as group_id in the parent object.
oc_name
oc_name is the ready-to-display selection name:
{
"oc_name": "W1"
}
Other examples:
X
Over 3.5
Under 3.5
1 -3.5
Yes
Erling Braut Haaland - Yes
The set of names depends on the sport and betting market:
- in football, the short list often contains
W1,X, andW2; - tennis does not have a draw;
- basketball often uses first-team and second-team wins instead of
1X2; - player-specific selection names may include the player’s name.
Do not create a fixed schema that requires every match to have W1, X, and W2.
Display the markets and selections actually returned by the API.
oc_rate
oc_rate contains the current decimal odds:
{
"oc_rate": 1.525
}
The value is a number, not a string. Live and Prematch odds may change with the next response update.
When updating the interface:
- Find the selection by
oc_pointer. - Update the displayed
oc_ratevalue. - Check the new
oc_blockvalue. - If the selection is no longer returned, do not continue displaying its old odds as current.
Do not use oc_rate as an identifier. The odds may change while the selection remains
the same.
oc_size
oc_size contains a numeric value associated with the selection. For example:
- a total line;
- a handicap value;
- a player-event threshold;
- another value required by the specific bet type.
Selection Without a Separate Value
{
"oc_name": "W1",
"oc_size": 0
}
Total
{
"oc_group_name": "Total",
"oc_name": "Over 3.5",
"oc_rate": 1.23,
"oc_size": "3.5",
"oc_pointer": "746146992|17|9|3.5",
"oc_block": false,
"op_id": null
}
Negative Handicap
{
"oc_group_name": "Handicap",
"oc_name": "1 -3.5",
"oc_rate": 6.5,
"oc_size": "-3.5",
"oc_pointer": "730321837|2|7|-3.5",
"oc_block": false,
"op_id": null
}
In actual responses, oc_size may be either a number or a string. The client must
support both JSON types.
Do not check only the value type. For example, 0 may be a number, while "3.5" or
"-3.5" may be a string.
You may display the value as text. For calculations, first perform an explicit and safe numeric conversion.
oc_pointer
oc_pointer is the primary technical code of a bet or selection:
{
"oc_pointer": "730321837|2|7|-3.5"
}
The current implementation builds it from four segments:
{game_id}|{group_id}|{outcome_type_id}|{oc_size}
For the example above:
| Segment | Value | Purpose |
|---|---|---|
| 1 | 730321837 | Match ID |
| 2 | 2 | Betting market ID |
| 3 | 7 | Internal selection type ID |
| 4 | -3.5 | oc_size value |
In a client integration, treat oc_pointer as an opaque string:
- store it in full;
- compare the complete value;
- do not generate it yourself;
- do not replace it with
oc_name; - do not use individual segments as a unique ID.
oc_name depends on the language, while oc_rate may change. Use the complete
oc_pointer to match updates for the same selection.
Use in the Bet Placement System
Sport Line API provides the sports line but does not itself place or settle bets. When
a separate bet placement and settlement service is connected to the project, pass the
complete oc_pointer to it as the code of the selected bet.
selected Sport Line API selection
↓ oc_pointer
bet placement and settlement system
Pass the value exactly as received from Sport Line API. Do not build oc_pointer
yourself or replace it with the oc_name text.
Continue with the Coupon API documentation:
oc_block
oc_block determines whether a selection is available.
Available selection:
{
"oc_rate": 1.525,
"oc_block": false
}
Blocked selection from an actual Live response:
{
"oc_group_name": "Double Chance",
"oc_name": "1X",
"oc_rate": 1.001,
"oc_size": 0,
"oc_pointer": "746266481|8|4|0",
"oc_block": true,
"op_id": null
}
If oc_block=true, do not treat the selection as available merely because oc_rate
still contains a numeric value. Disable or hide it in the interface according to the
product’s rules.
Check oc_block again with every update. Its status may change independently of the
odds value.
op_id
For standard selections, op_id is usually null:
{
"op_id": null
}
For a player-specific bet, the field may contain a player or participant ID:
{
"oc_group_name": "Who Will Score Goal",
"oc_name": "Erling Braut Haaland - Yes",
"oc_rate": 1.53,
"oc_size": "0.5",
"oc_pointer": "730321837|119|5869|0.5",
"oc_block": false,
"op_id": 133826394
}
Do not require op_id for every selection. Use it only when the bet applies to a
specific player or participant.
Requires clarification: in the saved Prematch response, several selections for different players in one player-specific market had the same
oc_pointerbut differentop_idvalues. Until the bet placement system contract is clarified, store bothoc_pointerandop_idfor player-specific selections.
Live and Prematch
The odds fields have the same purpose in Live and Prematch, but their data is updated independently:
- Live and Prematch versions of a match have different
game_idvalues; oc_pointercontainsgame_id, so the pointers will also differ;- update odds and blocked states from the corresponding sports line type;
- do not carry Prematch odds into Live.
Practical Integration Rules
- Retrieve the short odds list from
events. - For the full list, request
eventusing thegroupformat. - Use the complete
oc_pointerto match standard selections between updates; also storeop_idfor player-specific selections. - Display the current
oc_rate, not a previously stored value. - Always check
oc_block. - Support both string and number values for
oc_size. - Do not expect the same selection set for different sports.
- Do not link Live and Prematch odds.
- Preserve the market, column, and selection order returned in the
groupformat.