API reference
Price history
One market's price moves for an event, per book per selection, from first recorded price to the off.
GET
/odds/v1/history- Cost
- 2 tokens (1 to 5 books)
- Authentication
- X-API-Key, your own key (not the demo key)
Parameters
event_idstringrequiredAn event_id from /events. Upcoming, live or finished.marketstringrequiredOne market key from /odds, e.g. head_to_head.bookcomma listrequiredOne book, or up to 5, from /books, e.g. betfair,pinnacle.selection_keystringoptionalOne selection_key from /odds, live or finished.Default:allsinceISO-8601optionalLower bound on the tick time. since and until are at most 31 days apart when both are given.Default:first recorded moveuntilISO-8601optionalUpper bound on the tick time.Default:the off (finished) or nowformatstringoptionaldecimal, american or fractional. See Odds formats.Default:decimal
Request
The demo key (Free plan) cannot call this endpoint: it answers 403 plan_required. Set ODDS_API_KEY to your own key first.
curl -s "https://api.b337.ai/odds/v1/history?event_id=baseball%2Fus%2Fmlb%2Fphiladelphia_phillies_v_tampa_bay_rays%2F2026-09-26&market=head_to_head&book=betfair%2Cpinnacle" \
-H "X-API-Key: $ODDS_API_KEY"import os
import requests
resp = requests.get(
"https://api.b337.ai/odds/v1/history",
params={"event_id": "baseball/us/mlb/philadelphia_phillies_v_tampa_bay_rays/2026-09-26", "market": "head_to_head", "book": "betfair,pinnacle"},
headers={"X-API-Key": os.environ["ODDS_API_KEY"]},
timeout=10,
)
resp.raise_for_status()
print(resp.json())// Node 18+, saved as an .mjs file
const res = await fetch("https://api.b337.ai/odds/v1/history?event_id=baseball%2Fus%2Fmlb%2Fphiladelphia_phillies_v_tampa_bay_rays%2F2026-09-26&market=head_to_head&book=betfair%2Cpinnacle", {
headers: { "X-API-Key": process.env.ODDS_API_KEY },
});
console.log(await res.json());Response
200 OK
{"schema_version": 1,
"event_id": "baseball/us/mlb/philadelphia_phillies_v_tampa_bay_rays/2026-09-26",
"market": "head_to_head", "books": ["betfair", "pinnacle"], "status": "finished",
"odds_format": "decimal", "since": null, "until": "2026-09-26T23:15:00Z",
"truncated": false,
"selections": [
{"selection_key": "4ec43f065e08", "name": "Philadelphia Phillies",
"label": "Philadelphia Phillies", "player": null, "line": null,
"direction": null, "period": null,
"books": {"betfair": [{"t": "2026-09-26T03:57:44Z", "odds": 1.98}, "...21 more...",
{"t": "2026-09-26T23:11:57Z", "odds": 1.86}],
"pinnacle": [{"t": "2026-09-26T13:06:22Z", "odds": 1.9434}, "...12 more...",
{"t": "2026-09-26T19:49:58Z", "odds": 1.8475}]}}],
"generated_at": "2026-10-05T05:02:31Z"}Fields
- A point is a price change, oldest first (
tis UTC); the price holds until the next point.odds: nullmeans the book stopped offering the selection at that time. - Every selection we recorded for those books comes back, under the same selection_key as /odds. A selection or book with no recorded changes is omitted.
untilin the body is the bound actually used: the off for a finished event by default,nullfor up to now.- We record changes for each sport's main markets; other markets may return no series. History is kept from 2026-07-22, with no expiry.
- Paging: a response holds at most 5,000 points (the newest kept).
truncated: truemeans older points were dropped; ask again withuntilset to your oldesttto page back. formatconverts everyodds; see odds formats.
book is required (1 to 5 books) and the demo key cannot call this endpoint.