Concepts
Opening and closing prices
open_odds and close_odds ride on every price, in every tier, at no extra cost. Finished events add fair_odds.
open_odds
The first price we recorded for that book and selection. It is not necessarily the bookmaker's own opening line: we record from when we first saw the market, and only each sport's main markets.
close_odds
The book's price at the off (the moment the event went in-play). It appears once the event is no longer prematch and the close has been cut, a few minutes after the off. So it is always absent while status is prematch.
On a finished event odds equals close_odds: the book's last price at or before the off. closed_at (equal to updated_at) is when we recorded it, lag_seconds how long before the off, and source how it was captured. A price that had not moved for more than 3 hours before the off is not stored. Closing prices start on 2026-08-26.
Both are in the requested format, like odds, on every tier at no extra cost.
fair_odds
On a finished event, a selection can carry fair_odds: the starting price, being pinnacle's close with its margin removed (fair_method: power, fair_anchor: pinnacle). It is present only where pinnacle priced a complete two- or three-way set, and never on handicaps. Compare a book's close_odds to it to measure closing line value.
{"selection_key": "8f21d4b611a6", "name": "Over", "line": 2.5, "direction": "over",
"period": "1st_5_innings",
"fair_odds": 1.4857, "fair_method": "power", "fair_anchor": "pinnacle",
"prices": {"pinnacle": {"odds": 1.4525, "close_odds": 1.4525, "closed_at": "2026-09-26T23:13:10Z",
"updated_at": "2026-09-26T23:13:10Z", "lag_seconds": 110, "source": "capture"}}}When they are absent
Either field is absent, never null, when we do not have it: no exact match between the book's price and its recorded history (we never approximate a line, player or period), no close cut yet, or the history store was unreachable. Absence never fails the request.
On the WebSocket they arrive in snapshot frames; changes frames do not repeat them.
Example
An in-play event with format=american, trimmed to one market. sportsbet has both fields; tab has an opening price but no close cut yet, so close_odds is absent.
{
"odds_format": "american",
"event": {"status": "in_play"},
"markets": [
{"market": "head_to_head", "name": "Head to Head", "selections": [
{"selection_key": "9ff4816815ed", "label": "Carlton Blues",
"prices": {"sportsbet": {"odds": -118, "updated_at": "2026-10-04T10:12:41Z",
"open_odds": -143, "close_odds": -125},
"tab": {"odds": -120, "updated_at": "2026-10-04T10:12:20Z",
"open_odds": -139}}}]}
]
}