{"id":4039,"date":"2026-09-22T10:00:00","date_gmt":"2026-09-22T10:00:00","guid":{"rendered":"https:\/\/oddspapi.io\/blog\/?p=4039"},"modified":"2026-09-11T13:18:28","modified_gmt":"2026-09-11T13:18:28","slug":"nba-opening-night-odds-api","status":"publish","type":"post","link":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/","title":{"rendered":"NBA Odds API: Rank 217 Books Pricing Opening Night"},"content":{"rendered":"<p>The 2026-27 NBA season tips off on 20 October. On 11 September, 39 days out, one <strong>NBA odds API<\/strong> call on the Detroit Pistons v Boston Celtics opener returns <strong>217 bookmakers and 531 distinct market IDs<\/strong>. The board is already there. Rank it the naive way and you put a book on top whose price last moved on 2 September.<\/p>\n<p>This post measures that board. It covers what the NBA slate holds 39 days before the first jump ball, the three flags that separate a live quote from a parked one, and how far 217 quotes shrink once you dedupe them. Every number comes from a live call made on 11 September 2026. Re-run the scripts and your numbers will differ, because the board moves.<\/p>\n<h2>What the NBA Board Holds 39 Days Out<\/h2>\n<p>Sixteen NBA fixtures sit on the board between 20 and 24 October. All sixteen return <code>hasOdds: true<\/code>, and all sixteen carry a real board when you probe <code>\/odds<\/code>. Book count tracks the calendar:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Tip-off (UTC)<\/th>\n<th>Fixture<\/th>\n<th>Bookmakers<\/th>\n<th>Market IDs<\/th>\n<th>On market 111<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>20 Oct 19:00<\/td>\n<td>Detroit Pistons v Boston Celtics<\/td>\n<td>217<\/td>\n<td>531<\/td>\n<td>211<\/td>\n<\/tr>\n<tr>\n<td>20 Oct 23:00<\/td>\n<td>New York Knicks v Philadelphia 76ers<\/td>\n<td>212<\/td>\n<td>518<\/td>\n<td>206<\/td>\n<\/tr>\n<tr>\n<td>21 Oct 01:30<\/td>\n<td>San Antonio Spurs v Oklahoma City Thunder<\/td>\n<td>214<\/td>\n<td>516<\/td>\n<td>203<\/td>\n<\/tr>\n<tr>\n<td>21 Oct 23:30<\/td>\n<td>Miami Heat v Minnesota Timberwolves<\/td>\n<td>175<\/td>\n<td>599<\/td>\n<td>169<\/td>\n<\/tr>\n<tr>\n<td>22 Oct 02:00<\/td>\n<td>Los Angeles Lakers v Golden State Warriors<\/td>\n<td>175<\/td>\n<td>537<\/td>\n<td>170<\/td>\n<\/tr>\n<tr>\n<td>22 Oct 00:30<\/td>\n<td>Houston Rockets v Dallas Mavericks<\/td>\n<td>168<\/td>\n<td>522<\/td>\n<td>162<\/td>\n<\/tr>\n<tr>\n<td>23 Oct 01:30<\/td>\n<td>Oklahoma City Thunder v Denver Nuggets<\/td>\n<td>166<\/td>\n<td>585<\/td>\n<td>164<\/td>\n<\/tr>\n<tr>\n<td>23 Oct 23:00<\/td>\n<td>Boston Celtics v New York Knicks<\/td>\n<td>146<\/td>\n<td>523<\/td>\n<td>140<\/td>\n<\/tr>\n<tr>\n<td>24 Oct 01:30<\/td>\n<td>San Antonio Spurs v Houston Rockets<\/td>\n<td>145<\/td>\n<td>534<\/td>\n<td>145<\/td>\n<\/tr>\n<\/tbody>\n<\/table><figcaption>Measured 11 September 2026. Internal test feeds excluded.<\/figcaption><\/figure>\n<p>Opening night carries 217 books. Four days into the season that drops to 145. The books open the marquee fixtures first and fill the rest of the calendar as it approaches, which is the same ramp the NFL board shows in our <a href=\"https:\/\/oddspapi.io\/blog\/when-do-nfl-odds-open\/\">272-fixture study of when NFL odds open<\/a>.<\/p>\n<p>Two market IDs carry the result, and they settle differently. Market <code>111<\/code> is &#8220;Winner (incl. overtime)&#8221;, the two-way moneyline, and it sits on 140 to 211 books per fixture. Market <code>113<\/code> is &#8220;Regular Time Result&#8221;, a three-way with a live draw leg graded on the score at the end of the fourth quarter. It runs on 40 to 65 books. Merging the two is a grading error. Our <a href=\"https:\/\/oddspapi.io\/blog\/euroleague-basketball-odds-api\/\">EuroLeague odds API post<\/a> works through the settlement difference in full.<\/p>\n<h3>Who Is On the Board, and With How Much<\/h3>\n<p>Menu width splits the board into two groups. The crypto and casino brands ship the full ladder: <code>gamdom<\/code> carries 486 market IDs on the opener, and 21 more slugs carry 483 each. The US retail books carry the core four and stop there.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Bookmaker<\/th>\n<th>Market IDs on the 20 Oct opener<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>gamdom<\/code><\/td>\n<td>486<\/td>\n<\/tr>\n<tr>\n<td><code>bcgame<\/code>, <code>betfury<\/code>, <code>duel<\/code>, <code>roobet<\/code> and 18 more<\/td>\n<td>483<\/td>\n<\/tr>\n<tr>\n<td><code>draftkings<\/code><\/td>\n<td>5<\/td>\n<\/tr>\n<tr>\n<td><code>bet365<\/code><\/td>\n<td>5<\/td>\n<\/tr>\n<tr>\n<td><code>betmgm<\/code><\/td>\n<td>4<\/td>\n<\/tr>\n<tr>\n<td><code>kalshi<\/code><\/td>\n<td>1<\/td>\n<\/tr>\n<tr>\n<td><code>tipico<\/code>, <code>fanatics<\/code>, <code>mrgreen<\/code>, <code>888sport.es<\/code><\/td>\n<td>1<\/td>\n<\/tr>\n<\/tbody>\n<\/table><figcaption>Measured 11 September 2026 on fixture <code>id1100013273682354<\/code>.<\/figcaption><\/figure>\n<p>Pinnacle, Betfair Exchange and Polymarket post their NBA regular-season board closer to tip-off. Pass <code>bookmakers=pinnacle<\/code> alone and the call returns HTTP 200 with the slug absent from <code>bookmakerOdds<\/code>, which is the API telling you the book has no price on this fixture yet. A 403 would mean your key cannot read the slug. Kalshi opened three of the sixteen boards, all on 20 and 21 October.<\/p>\n<p>That changes how you build a fair price in September. You cannot anchor on Pinnacle, so de-vig the deduped consensus of the books that are up. Our <a href=\"https:\/\/oddspapi.io\/blog\/consensus-odds-fair-odds-calculator-python\/\">consensus odds calculator<\/a> covers the maths.<\/p>\n<h2>Why a Plain Best-Price Scan Ranks the Wrong Book<\/h2>\n<p>Most odds clients read one field. They walk the outcomes, check <code>active<\/code> on the price row, and rank what survives. On a board opened six weeks early that filter is too loose.<\/p>\n<p>On the Detroit v Boston opener, 199 of the 211 moneyline quotes carry <code>active: true<\/code> at the price level. Rank those by margin and <code>1xbet<\/code> tops the table at 2.05%. Open the record and the price last changed at <code>2026-09-02T03:41:26Z<\/code>, nine days before the call, and the market it sits in reports <code>marketActive: false<\/code>. The price row says active. The market around it says closed.<\/p>\n<p>The OddsPapi payload carries three separate liveness flags, and each one means something different:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Level<\/th>\n<th>What it tells you<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>suspended<\/code> \/ <code>bookmakerIsActive<\/code><\/td>\n<td>Bookmaker<\/td>\n<td>The book has the whole fixture up or down<\/td>\n<\/tr>\n<tr>\n<td><code>marketActive<\/code><\/td>\n<td>Market<\/td>\n<td>This market ID is open for bets at this book<\/td>\n<\/tr>\n<tr>\n<td><code>active<\/code><\/td>\n<td>Price<\/td>\n<td>This outcome is priced and takeable<\/td>\n<\/tr>\n<tr>\n<td><code>changedAt<\/code><\/td>\n<td>Price<\/td>\n<td>When the book last moved this number<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>Apply them in that order on the opener and the count falls in steps: 211 books quote market 111, 199 pass the price-level <code>active<\/code> check, 195 pass the book-level flags, 99 sit in a market flagged open, and 39 moved their moneyline inside the last 48 hours. The board median margin shifts from 5.68% to 6.43% across that funnel, and the top of the leaderboard changes hands: <code>duel<\/code> at 2.13%, repriced 24 minutes before the call, with <code>kalshi<\/code> behind it at 2.98%.<\/p>\n<p>In-play the same fields behave differently again. Bet365 flips <code>bookmakerIsActive<\/code> to <code>false<\/code> half a minute after kick-off and keeps repricing to full time, which we measured second by second in the <a href=\"https:\/\/oddspapi.io\/blog\/bet365-live-odds-api\/\">bet365 live odds post<\/a>. Pre-match, trust the flags. In-play, read <code>changedAt<\/code>.<\/p>\n<h2>Old Way vs OddsPapi<\/h2>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Task<\/th>\n<th>Scraping or a single-book API<\/th>\n<th>OddsPapi<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Books on one NBA fixture<\/td>\n<td>1 to 20, one integration each<\/td>\n<td>217 in one call, from a catalogue of 357 slugs<\/td>\n<\/tr>\n<tr>\n<td>Knowing a price is live<\/td>\n<td>Infer from a page that renders the same either way<\/td>\n<td>Three flags plus <code>changedAt<\/code> on every price row<\/td>\n<\/tr>\n<tr>\n<td>Alternate totals and handicaps<\/td>\n<td>Scrape each rung<\/td>\n<td>531 market IDs with the line in the <code>handicap<\/code> field<\/td>\n<\/tr>\n<tr>\n<td>Opening and closing lines<\/td>\n<td>Run your own collector for a season<\/td>\n<td>Free historical odds on every played fixture<\/td>\n<\/tr>\n<tr>\n<td>Sub-second updates<\/td>\n<td>Poll and get blocked<\/td>\n<td>WebSocket push on the odds channel<\/td>\n<\/tr>\n<tr>\n<td>Cost to start<\/td>\n<td>Proxies, maintenance, legal risk<\/td>\n<td>Free tier, no card<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>Build It: Rank the NBA Opening-Night Board in Python<\/h2>\n<p>Four steps. Every snippet below ran against the live API on 11 September 2026.<\/p>\n<h3>Step 1: Find the NBA Tournament and Its Fixtures<\/h3>\n<p>Authentication is a query parameter, never a header. Basketball is <code>sportId=11<\/code>, and the NBA is <code>tournamentId=132<\/code>. Filter <code>\/fixtures<\/code> on the tournament ID: it cuts the payload by about 20x and lifts the 10-day range cap.<\/p>\n<pre class=\"wp-block-code\"><code>import os, time, requests\n\nAPI_KEY = os.environ[\"ODDSPAPI_API_KEY\"]\nBASE = \"https:\/\/api.oddspapi.io\/v4\"\nBASKETBALL = 11\n\ndef get(path, **params):\n    params[\"apiKey\"] = API_KEY\n    r = requests.get(f\"{BASE}\/{path}\", params=params)\n    r.raise_for_status()\n    time.sleep(1.2)\n    return r.json()\n\nnba = next(t for t in get(\"tournaments\", sportId=BASKETBALL)\n           if t[\"tournamentSlug\"] == \"nba\")\nprint(nba[\"tournamentId\"], nba[\"tournamentName\"], nba[\"futureFixtures\"], \"future fixtures\")\n\nfixtures = get(\"fixtures\", sportId=BASKETBALL, tournamentId=nba[\"tournamentId\"],\n               **{\"from\": \"2026-09-11\", \"to\": \"2026-11-15\"})\nfixtures.sort(key=lambda f: f[\"startTime\"])\nprint(f\"{len(fixtures)} fixtures on the board\")\nfor f in fixtures[:5]:\n    print(f[\"startTime\"][:16], f[\"participant1Name\"], \"v\", f[\"participant2Name\"],\n          \"hasOdds\", f[\"hasOdds\"])<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>132 NBA 21 future fixtures\n16 fixtures on the board\n2026-10-20T19:00 Detroit Pistons v Boston Celtics hasOdds True\n2026-10-20T23:00 New York Knicks v Philadelphia 76ers hasOdds True\n2026-10-21T01:30 San Antonio Spurs v Oklahoma City Thunder hasOdds True\n2026-10-21T23:00 Orlando Magic v Atlanta Hawks hasOdds True\n2026-10-21T23:00 Washington Wizards v Milwaukee Bucks hasOdds True<\/code><\/pre>\n<p>Set <code>to<\/code> to the day after the last day you want. It is a midnight-UTC instant, so a same-day query returns the 00:00Z fixtures and nothing else. A 404 on <code>\/fixtures<\/code> means an empty window, not a failure, so do not let <code>raise_for_status()<\/code> kill a season loop on the first off-season month.<\/p>\n<h3>Step 2: Measure the Board on One Fixture<\/h3>\n<p>Drop the internal test feeds before you count anything. Slugs matching <code>pinnacle+<\/code> and the names <code>demo<\/code>, <code>singbet-b<\/code> and <code>vertexv1<\/code> ship inside live payloads and will count Pinnacle three times.<\/p>\n<pre class=\"wp-block-code\"><code>import collections\n\nINTERNAL = (\"demo\", \"singbet-b\", \"vertexv1\")\n\npayload = get(\"odds\", fixtureId=\"id1100013273682354\")\nbooks = {s: b for s, b in payload[\"bookmakerOdds\"].items()\n         if not s.startswith(\"pinnacle+\") and s not in INTERNAL}\n\nmenu = collections.Counter({s: len(b.get(\"markets\") or {}) for s, b in books.items()})\nmarket_ids = {int(m) for b in books.values() for m in (b.get(\"markets\") or {})}\nprint(f\"{len(books)} bookmakers, {len(market_ids)} distinct market IDs\")\nprint(\"widest menus :\", menu.most_common(3))\nprint(\"narrowest    :\", menu.most_common()[-3:])\nfor slug in (\"draftkings\", \"betmgm\", \"bet365\", \"kalshi\", \"pinnacle\", \"betfair-ex\"):\n    print(f\"  {slug:&lt;12} {menu.get(slug, 'not on this board')}\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>217 bookmakers, 531 distinct market IDs\nwidest menus : [('gamdom', 486), ('500.casino', 483), ('bcgame', 483)]\nnarrowest    : [('mrgreen.dk', 1), ('pointsbet.com.au', 1), ('tipico', 1)]\n  draftkings   5\n  betmgm       4\n  bet365       5\n  kalshi       1\n  pinnacle     not on this board\n  betfair-ex   not on this board<\/code><\/pre>\n<p>The <code>markets=<\/code> and <code>marketId=<\/code> parameters on <code>\/odds<\/code> shrink the response but do not restrict which market IDs come back. Filter client-side.<\/p>\n<h3>Step 3: Apply the Three Flags and Rank on Margin<\/h3>\n<p>This is the part that changes your leaderboard. Check the book, then the market, then the price, then the clock.<\/p>\n<pre class=\"wp-block-code\"><code>import statistics as st\nfrom datetime import datetime, timezone\n\nMONEYLINE = 111                      # \"Winner (incl. overtime)\"\nFRESH_HOURS = 48\n\ndef parse(ts):\n    return datetime.fromisoformat(ts.replace(\"Z\", \"+00:00\"))\n\ndef moneyline_rows(payload):\n    now = datetime.now(timezone.utc)\n    rows = []\n    for slug, book in payload[\"bookmakerOdds\"].items():\n        if slug.startswith(\"pinnacle+\") or slug in INTERNAL:\n            continue\n        market = (book.get(\"markets\") or {}).get(str(MONEYLINE))\n        if not market:\n            continue\n        legs = {}\n        for outcome_id, outcome in market[\"outcomes\"].items():\n            price = (outcome.get(\"players\") or {}).get(\"0\")\n            if price:\n                legs[outcome_id] = price\n        if len(legs) != 2:                                   # guard the leg count\n            continue\n        if book.get(\"suspended\") or book.get(\"bookmakerIsActive\") is False:\n            continue                                         # flag 1: the book is up\n        if market.get(\"marketActive\") is not True:\n            continue                                         # flag 2: the market is up\n        if not all(leg.get(\"active\") for leg in legs.values()):\n            continue                                         # flag 3: both prices are live\n        stamps = [leg.get(\"changedAt\") for leg in legs.values()]\n        if not all(stamps):\n            continue\n        age = min((now - parse(s)).total_seconds() \/ 3600 for s in stamps)\n        if age &gt; FRESH_HOURS:                                # and it moved recently\n            continue\n        margin = (sum(1 \/ leg[\"price\"] for leg in legs.values()) - 1) * 100\n        rows.append((slug, margin, age, {o: l[\"price\"] for o, l in legs.items()}))\n    return sorted(rows, key=lambda r: r[1])\n\nrows = moneyline_rows(get(\"odds\", fixtureId=\"id1100013273682354\"))\nprint(f\"{len(rows)} books clear all three flags\")\nprint(f\"board median margin {st.median(m for _, m, _, _ in rows):.2f}%\")\nfor slug, margin, age, prices in rows[:8]:\n    print(f\"{slug:&lt;20} {margin:5.2f}%  last moved {age:5.1f}h ago  {prices}\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>39 books clear all three flags\nboard median margin 6.43%\nduel                  2.13%  last moved   0.4h ago  {'111': 1.85, '112': 2.08}\nkalshi                2.98%  last moved   0.0h ago  {'112': 2.128, '111': 1.786}\nborgata               4.34%  last moved  45.6h ago  {'112': 2.05, '111': 1.8}\nbet365.it             4.56%  last moved   1.2h ago  {'112': 2.0, '111': 1.833}\nbetify                5.06%  last moved   1.8h ago  {'111': 1.8, '112': 2.02}\nbetplay.io            5.06%  last moved   1.8h ago  {'111': 1.8, '112': 2.02}\nroobet                5.06%  last moved   1.8h ago  {'111': 1.8, '112': 2.02}\nbet365.de             6.32%  last moved   1.2h ago  {'111': 1.8, '112': 1.97}<\/code><\/pre>\n<p>The <code>len(legs) != 2<\/code> guard earns its place. On the EuroLeague slate we found three separate books shipping a two-way market with one leg missing, one of them at an overround of minus 52%, which puts it first on an unguarded leaderboard. Margin ranking is also orientation-independent, so it survives a feed that lists the outcomes in a different order. Best-price scanning is not, and the fix is in our <a href=\"https:\/\/oddspapi.io\/blog\/line-shopping-python-best-odds\/\">line shopping guide<\/a>.<\/p>\n<h3>Step 4: Dedupe Before You Quote a Book Count<\/h3>\n<p>Distinct slugs quote byte-identical prices. The <code>cloneOf<\/code> field does not catch it: 117 of the 357 catalogue slugs carry a parent, and the clusters below cut across that.<\/p>\n<pre class=\"wp-block-code\"><code>clusters = collections.defaultdict(list)\nfor slug, book in payload[\"bookmakerOdds\"].items():\n    if slug.startswith(\"pinnacle+\") or slug in INTERNAL:\n        continue\n    market = (book.get(\"markets\") or {}).get(\"111\")\n    if not market:\n        continue\n    legs = {o: (od.get(\"players\") or {}).get(\"0\") for o, od in market[\"outcomes\"].items()}\n    legs = {o: p for o, p in legs.items() if p and p.get(\"active\")}\n    if len(legs) != 2:\n        continue\n    key = tuple(sorted((o, round(p[\"price\"], 3)) for o, p in legs.items()))\n    clusters[key].append(slug)\n\nquotes = sum(len(v) for v in clusters.values())\nprint(f\"{quotes} quotes collapse to {len(clusters)} distinct prices \"\n      f\"({100 * (1 - len(clusters) \/ quotes):.1f}% duplicated)\")\nfor key, slugs in sorted(clusters.items(), key=lambda kv: -len(kv[1]))[:3]:\n    print(f\"  {len(slugs):&gt;3} books at {dict(key)}  e.g. {', '.join(slugs[:5])}\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>199 quotes collapse to 38 distinct prices (80.9% duplicated)\n   26 books at {'111': 1.8, '112': 2.05}  e.g. betboo.bet.br, betmgm, betway, betway.de, betway.es\n   23 books at {'111': 1.741, '112': 2.0}  e.g. 7bet.co.uk, 7bet.lt, allbritishcasino, alphawin, betinia.dk\n   21 books at {'111': 1.82, '112': 2.02}  e.g. atg.se, ballybet, betcity.nl, betparx, betplay<\/code><\/pre>\n<p>Four in five quotes on the opener repeat a price another slug already posted. Feed a raw 199-book sample into a consensus and the 26-slug cluster at 1.80 \/ 2.05 counts 26 times. Dedupe on the price tuple first, then average the 38 that remain.<\/p>\n<h3>Bonus: How Far Back the NBA History Goes<\/h3>\n<p>Historical odds are free on every plan, including the free tier. On a played fixture the endpoint returns the full snapshot series per book. The 2026 Finals game between the New York Knicks and the San Antonio Spurs shows where each book&#8217;s board starts:<\/p>\n<pre class=\"wp-block-code\"><code>FIXTURE = \"id1100013270505016\"           # New York Knicks v San Antonio Spurs, 9 Jun 2026\nTIP = parse(\"2026-06-09T00:30:00Z\")\n\ndata = get(\"historical-odds\", fixtureId=FIXTURE, bookmakers=\"pinnacle,draftkings,bet365\")\nfor slug, book in data[\"bookmakers\"].items():\n    stamps, snapshots = [], 0\n    for market in book[\"markets\"].values():\n        for outcome in market[\"outcomes\"].values():\n            for series in outcome[\"players\"].values():\n                snapshots += len(series)\n                stamps += [s[\"createdAt\"] for s in series]\n    lead = (TIP - parse(min(stamps))).total_seconds() \/ 3600\n    print(f\"{slug:&lt;12} {len(book['markets']):&gt;3} markets  {snapshots:&gt;6} snapshots  \"\n          f\"opens T-{lead:.0f}h\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>bet365        21 markets     373 snapshots  opens T-66h\ndraftkings   633 markets  174950 snapshots  opens T-68h\npinnacle     443 markets   77163 snapshots  opens T-69h<\/code><\/pre>\n<p>Three points worth keeping. The endpoint caps at three bookmaker slugs per call, and one unreadable slug fails the whole batch. Sleep 4.6 seconds after each successful call. And the closing price is the last snapshot with <code>active: true<\/code> before <code>startTime<\/code>, not the last snapshot in the series, because snapshots keep arriving after the jump ball. Our <a href=\"https:\/\/oddspapi.io\/blog\/backtest-betting-model-free-historical-odds\/\">backtesting guide<\/a> builds a full season loop on top of this.<\/p>\n<h2>Four Traps on the NBA Board<\/h2>\n<ol>\n<li><strong>The price row lies on its own.<\/strong> Read <code>marketActive<\/code> and <code>changedAt<\/code> alongside <code>active<\/code>. On the 20 October opener that is the difference between 199 books and 39.<\/li>\n<li><strong>Market 111 and market 113 are different bets.<\/strong> The three-way settles on the score at the end of regulation. The two-way settles after overtime. Never merge them into one price.<\/li>\n<li><strong>Fixture count is not coverage.<\/strong> Every NBA fixture in the window returns <code>hasOdds: true<\/code>, and the boards behind them range from 145 books to 217. Probe <code>\/odds<\/code> before you commit.<\/li>\n<li><strong>Alternate totals live in the <code>handicap<\/code> field.<\/strong> Market <code>11248<\/code> and market <code>11252<\/code> share the name &#8220;Over Under (incl. overtime)&#8221; and carry 221.5 and 223.5. Split on the pair, never on the name alone. The same pattern shows up across the <a href=\"https:\/\/oddspapi.io\/blog\/nfl-alternate-lines-api\/\">NFL alternate lines ladder<\/a>.<\/li>\n<\/ol>\n<h2>Start Pulling the NBA Board<\/h2>\n<p>The free tier reads every endpoint used above: <code>\/tournaments<\/code>, <code>\/fixtures<\/code>, <code>\/odds<\/code> and <code>\/historical-odds<\/code>, across a catalogue of 357 bookmaker slugs. No card, no sales call. When polling stops keeping up, the same data pushes over a <a href=\"https:\/\/oddspapi.io\/blog\/websocket-odds-api-real-time-betting-data\/\">WebSocket odds channel<\/a>.<\/p>\n<p><a href=\"https:\/\/oddspapi.io\/en\/sign-up\">Get a free API key<\/a> and run the four scripts on tonight&#8217;s board. If you want the player-prop side of the NBA feed, which opens closer to tip-off, start with our <a href=\"https:\/\/oddspapi.io\/blog\/nba-odds-api-player-props-spreads\/\">NBA player props and spreads guide<\/a>.<\/p>\n<h2>Frequently Asked Questions<\/h2>\n<h3>How many bookmakers price an NBA fixture?<\/h3>\n<p>On 11 September 2026, 39 days before tip-off, the Detroit Pistons v Boston Celtics opener returned 217 bookmakers and 531 distinct market IDs in a single <code>\/odds<\/code> call. Fixtures later in the opening week returned 145 to 175 books. The catalogue holds 357 slugs, and the count on any one fixture depends on how close it is and how big the matchup is.<\/p>\n<h3>What is the difference between market 111 and market 113 in basketball?<\/h3>\n<p>Market <code>111<\/code> is &#8220;Winner (incl. overtime)&#8221;, a two-way moneyline settled on the final score. Market <code>113<\/code> is &#8220;Regular Time Result&#8221;, a three-way with a draw leg settled on the score at the end of the fourth quarter. They are separate bets with separate settlement rules, so keep them apart in your parser.<\/p>\n<h3>Why does a bookmaker show an active price in a closed market?<\/h3>\n<p>The payload carries liveness at three levels. <code>suspended<\/code> and <code>bookmakerIsActive<\/code> describe the book, <code>marketActive<\/code> describes the market, and <code>active<\/code> describes the individual price row. A book can leave a price row flagged active inside a market it has flagged closed. Read <code>changedAt<\/code> as well, so you know when the number last moved.<\/p>\n<h3>Can I get historical NBA odds for free?<\/h3>\n<p>Yes. The <code>\/historical-odds<\/code> endpoint is on the free tier and returns the full snapshot series per bookmaker on a played fixture. On the 2026 Finals game tested here, Pinnacle returned 443 market IDs and 77,163 snapshots. The endpoint takes up to three bookmaker slugs per call, and 4.6 seconds of spacing between calls keeps you under the rate limit.<\/p>\n<h3>How do I find the NBA tournament ID?<\/h3>\n<p>Call <code>\/v4\/tournaments?sportId=11<\/code> and match on <code>tournamentSlug == \"nba\"<\/code>. The ID is <code>132<\/code>. Pass it to <code>\/fixtures<\/code> as <code>tournamentId<\/code>, which shrinks the payload and lifts the 10-day date-range cap that applies when <code>sportId<\/code> is your only filter.<\/p>\n<p><script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [\n    {\n      \"@type\": \"Question\",\n      \"name\": \"How many bookmakers price an NBA fixture?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"On 11 September 2026, 39 days before tip-off, the Detroit Pistons v Boston Celtics opener returned 217 bookmakers and 531 distinct market IDs in a single \/odds call. Fixtures later in the opening week returned 145 to 175 books. The catalogue holds 357 slugs, and the count on any one fixture depends on how close it is and how big the matchup is.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"What is the difference between market 111 and market 113 in basketball?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Market 111 is Winner (incl. overtime), a two-way moneyline settled on the final score. Market 113 is Regular Time Result, a three-way with a draw leg settled on the score at the end of the fourth quarter. They are separate bets with separate settlement rules, so keep them apart in your parser.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Why does a bookmaker show an active price in a closed market?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"The payload carries liveness at three levels. suspended and bookmakerIsActive describe the book, marketActive describes the market, and active describes the individual price row. A book can leave a price row flagged active inside a market it has flagged closed. Read changedAt as well, so you know when the number last moved.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Can I get historical NBA odds for free?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes. The \/historical-odds endpoint is on the free tier and returns the full snapshot series per bookmaker on a played fixture. On the 2026 Finals game tested here, Pinnacle returned 443 market IDs and 77,163 snapshots. The endpoint takes up to three bookmaker slugs per call, and 4.6 seconds of spacing between calls keeps you under the rate limit.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"How do I find the NBA tournament ID?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Call \/v4\/tournaments?sportId=11 and match on tournamentSlug == nba. The ID is 132. Pass it to \/fixtures as tournamentId, which shrinks the payload and lifts the 10-day date-range cap that applies when sportId is your only filter.\"\n      }\n    }\n  ]\n}\n<\/script><\/p>\n<p><!--\nFOCUS KEYPHRASE: NBA odds API\nSEO TITLE: NBA Odds API: Rank 217 Books Pricing Opening Night\nMETA DESCRIPTION: The Oct 20 opener is on the board 39 days out with 531 market IDs. Filter on marketActive and changedAt: 39 books moved the moneyline today.\nSLUG: nba-opening-night-odds-api\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Oct 20 opener is on the board 39 days out with 531 market IDs. Filter on marketActive and changedAt: 39 books moved the moneyline today.<\/p>\n","protected":false},"author":2,"featured_media":4040,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[75,16,9,11,10],"class_list":["post-4039","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to-guides","tag-basketball","tag-nba","tag-odds-api","tag-python","tag-sports-betting-api"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>NBA Odds API: Rank 217 Books Pricing Opening Night | OddsPapi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"NBA Odds API: Rank 217 Books Pricing Opening Night | OddsPapi Blog\" \/>\n<meta property=\"og:description\" content=\"The Oct 20 opener is on the board 39 days out with 531 market IDs. Filter on marketActive and changedAt: 39 books moved the moneyline today.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/\" \/>\n<meta property=\"og:site_name\" content=\"OddsPapi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-22T10:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Odds API Writer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/oddspapi.io\/logo-v2.webp\" \/>\n<meta name=\"twitter:creator\" content=\"@oddspapiapi\" \/>\n<meta name=\"twitter:site\" content=\"@oddspapiapi\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Odds API Writer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/\"},\"author\":{\"name\":\"Odds API Writer\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\"},\"headline\":\"NBA Odds API: Rank 217 Books Pricing Opening Night\",\"datePublished\":\"2026-09-22T10:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/\"},\"wordCount\":1795,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp\",\"keywords\":[\"Basketball\",\"NBA\",\"Odds API\",\"Python\",\"Sports Betting API\"],\"articleSection\":[\"How To Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/\",\"name\":\"NBA Odds API: Rank 217 Books Pricing Opening Night | OddsPapi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp\",\"datePublished\":\"2026-09-22T10:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp\",\"width\":1200,\"height\":675,\"caption\":\"NBA Odds API header image\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oddspapi.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"NBA Odds API: Rank 217 Books Pricing Opening Night\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\",\"url\":\"https:\/\/oddspapi.io\/blog\/\",\"name\":\"OddsPapi\",\"description\":\"Sports Odds API Tutorials &amp; Guides\",\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"alternateName\":\"Odds Papi\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/oddspapi.io\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\",\"name\":\"OddsPapi\",\"url\":\"https:\/\/oddspapi.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2025\/11\/oddspapi.png\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2025\/11\/oddspapi.png\",\"width\":135,\"height\":135,\"caption\":\"OddsPapi\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/oddspapiapi\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\",\"name\":\"Odds API Writer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/33b204f24af3d02e35b25ae730c0536121ca6a783fdb196e7611c9e49fcd13eb?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/33b204f24af3d02e35b25ae730c0536121ca6a783fdb196e7611c9e49fcd13eb?s=96&d=mm&r=g\",\"caption\":\"Odds API Writer\"},\"url\":\"https:\/\/oddspapi.io\/blog\/author\/andy-lavelle\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"NBA Odds API: Rank 217 Books Pricing Opening Night | OddsPapi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/","og_locale":"en_US","og_type":"article","og_title":"NBA Odds API: Rank 217 Books Pricing Opening Night | OddsPapi Blog","og_description":"The Oct 20 opener is on the board 39 days out with 531 market IDs. Filter on marketActive and changedAt: 39 books moved the moneyline today.","og_url":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/","og_site_name":"OddsPapi Blog","article_published_time":"2026-09-22T10:00:00+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp","type":"image\/webp"}],"author":"Odds API Writer","twitter_card":"summary_large_image","twitter_image":"https:\/\/oddspapi.io\/logo-v2.webp","twitter_creator":"@oddspapiapi","twitter_site":"@oddspapiapi","twitter_misc":{"Written by":"Odds API Writer","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#article","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/"},"author":{"name":"Odds API Writer","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13"},"headline":"NBA Odds API: Rank 217 Books Pricing Opening Night","datePublished":"2026-09-22T10:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/"},"wordCount":1795,"commentCount":1,"publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp","keywords":["Basketball","NBA","Odds API","Python","Sports Betting API"],"articleSection":["How To Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/","url":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/","name":"NBA Odds API: Rank 217 Books Pricing Opening Night | OddsPapi Blog","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp","datePublished":"2026-09-22T10:00:00+00:00","breadcrumb":{"@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#primaryimage","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/09\/nba-opening-night-odds-api.webp","width":1200,"height":675,"caption":"NBA Odds API header image"},{"@type":"BreadcrumbList","@id":"https:\/\/oddspapi.io\/blog\/nba-opening-night-odds-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oddspapi.io\/blog\/"},{"@type":"ListItem","position":2,"name":"NBA Odds API: Rank 217 Books Pricing Opening Night"}]},{"@type":"WebSite","@id":"https:\/\/oddspapi.io\/blog\/#website","url":"https:\/\/oddspapi.io\/blog\/","name":"OddsPapi","description":"Sports Odds API Tutorials &amp; Guides","publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"alternateName":"Odds Papi","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/oddspapi.io\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/oddspapi.io\/blog\/#organization","name":"OddsPapi","url":"https:\/\/oddspapi.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2025\/11\/oddspapi.png","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2025\/11\/oddspapi.png","width":135,"height":135,"caption":"OddsPapi"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/oddspapiapi"]},{"@type":"Person","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13","name":"Odds API Writer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/33b204f24af3d02e35b25ae730c0536121ca6a783fdb196e7611c9e49fcd13eb?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/33b204f24af3d02e35b25ae730c0536121ca6a783fdb196e7611c9e49fcd13eb?s=96&d=mm&r=g","caption":"Odds API Writer"},"url":"https:\/\/oddspapi.io\/blog\/author\/andy-lavelle\/"}]}},"_links":{"self":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/4039","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/comments?post=4039"}],"version-history":[{"count":2,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/4039\/revisions"}],"predecessor-version":[{"id":4042,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/4039\/revisions\/4042"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media\/4040"}],"wp:attachment":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media?parent=4039"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/categories?post=4039"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/tags?post=4039"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}