GET /odds/history - Fetch Odds Movement

Get the tick-by-tick odds history of an Event

GET https://api.sockodds.com/v2/odds/history/

SockOdds extension. Every price, line and bet-limit change every bookmaker has published for one event, oldest first — the raw movement behind opening, closing and steam. Captured since 2026-08-14 and kept indefinitely; the last ~28 days are answered from the live store and everything older from the archive.

Usage notesFilter with oddID and bookmakerID — an NFL game logs ~25,000 ticks a day, and each request reads at most 50,000 ticks per tier before paging. Your plan's league scope and bookmaker cap apply exactly as on /events/. One bookmaker is one series: where a book reaches the log under two sources, the higher-ranked source is kept for the whole window. `notice` says when the archive tier did not answer, in which case the series is incomplete at its old end.

Query parameters

ParameterTypeDescription
eventIDstringThe eventID to get odds history for (required) e.g. afl_2026-09-12_brisbane_lions_vs_adelaide_crows
oddIDstringAn oddID or comma-separated list of oddIDs to include ticks for. `oddIDs` is accepted as an alias. e.g. points-home-game-ml-home
bookmakerIDstringA bookmakerID or comma-separated list of bookmakerIDs to include ticks for e.g. sportsbet,pinnacle
fromdate-timeStart of the window. Defaults to 21 days before the event's kickoff date. e.g. 2026-08-22T00:00:00Z
todate-timeEnd of the window (exclusive, capped at now). Defaults to 2 days after kickoff. from/to may span at most 400 days.
limitnumberThe maximum number of ticks to return (default 1000, max 5000)
cursorstringThe cursor for the request. Used to get the next group of results. This is an opaque token — pass the nextCursor value from the prior response unchanged.

Response

Paginated: { "success": true, "data": OddsHistoryTick[], "nextCursor": string | null }

OddsHistoryTick

One recorded change to one bookmaker's price on one market (SockOdds extension). Odds are given as American strings (bookOdds) and decimals.

FieldTypeDescription
eventIDstringThe event
oddIDstringThe market side, in the oddID format (statID-statEntityID-periodID-betTypeID-sideID)
bookmakerIDstringThe bookmaker
changedAtstring (date-time)When the bookmaker's quote changed
kindstringopen = first quote seen · move = price, line or main-line status changed · limit = only the bet limit changed (Pinnacle) · close = the quote was withdrawn
bookOddsstring | nullThe new price as American odds; null on a close
decimalOddsnumber | nullThe new price as decimal odds
previousBookOddsstring | nullThe price this change replaced (American); null on an open
previousDecimalOddsnumber | nullThe price this change replaced (decimal)
linenumber | nullThe spread or total the price applies to; null for moneylines and yes/no markets
isMainLineboolean | nullWhether this line was the bookmaker's headline line at the time
layOddsnumber | nullExchange lay price, where the bookmaker is an exchange
maxStakenumber | nullThe bet limit after the change, where the bookmaker publishes one
previousMaxStakenumber | nullThe bet limit before the change

Status codes

StatusBody
200Success
400{"success":false,"error":"Invalid params"}
401{"success":false,"error":"Invalid API key"}
403{"success":false,"error":"Inactive API key"}
404{"success":false,"error":"Not found"}
429{"success":false,"error":"Rate limit exceeded"} (Retry-After header)
500{"success":false,"error":"Query failed"}
503

Code samples

curl -X GET "https://api.sockodds.com/v2/odds/history/?eventID=afl_2026-09-12_brisbane_lions_vs_adelaide_crows&oddID=points-home-game-ml-home&bookmakerID=sportsbet,pinnacle" \
  -H "x-api-key: YOUR_API_KEY"
const r = await fetch("https://api.sockodds.com/v2/odds/history/?eventID=afl_2026-09-12_brisbane_lions_vs_adelaide_crows&oddID=points-home-game-ml-home&bookmakerID=sportsbet,pinnacle", { headers: { "x-api-key": "YOUR_API_KEY" } });
const { success, data, nextCursor, notice } = await r.json();
import requests
r = requests.get("https://api.sockodds.com/v2/odds/history/", params=dict(eventID="afl_2026-09-12_brisbane_lions_vs_adelaide_crows", oddID="points-home-game-ml-home", bookmakerID="sportsbet,pinnacle"), headers={"x-api-key": "YOUR_API_KEY"})
body = r.json()
req, _ := http.NewRequest("GET", "https://api.sockodds.com/v2/odds/history/?eventID=afl_2026-09-12_brisbane_lions_vs_adelaide_crows&oddID=points-home-game-ml-home&bookmakerID=sportsbet,pinnacle", nil)
req.Header.Set("x-api-key", "YOUR_API_KEY")
res, err := http.DefaultClient.Do(req)
HttpRequest req = HttpRequest.newBuilder().uri(URI.create("https://api.sockodds.com/v2/odds/history/?eventID=afl_2026-09-12_brisbane_lions_vs_adelaide_crows&oddID=points-home-game-ml-home&bookmakerID=sportsbet,pinnacle"))
    .header("x-api-key", "YOUR_API_KEY").GET().build();
HttpResponse<String> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");
var body = await http.GetStringAsync("https://api.sockodds.com/v2/odds/history/?eventID=afl_2026-09-12_brisbane_lions_vs_adelaide_crows&oddID=points-home-game-ml-home&bookmakerID=sportsbet,pinnacle");

Try it

// the response appears here
Need help?FAQ · Email · Contact