{"id":4689,"date":"2026-10-13T10:00:00","date_gmt":"2026-10-13T10:00:00","guid":{"rendered":"https:\/\/oddspapi.io\/blog\/?p=4689"},"modified":"2026-10-02T13:28:28","modified_gmt":"2026-10-02T13:28:28","slug":"novig-api-odds-access","status":"publish","type":"post","link":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/","title":{"rendered":"Novig API: Read Both Sides of a 191-Market NFL Board"},"content":{"rendered":"<p>Does Novig have an API? Yes. Novig publishes a trading API at <a href=\"https:\/\/docs.novig.com\/\">docs.novig.com<\/a>: you create a management key in your Novig profile, open a subaccount, sign each REST request with Ed25519 or P-256, and follow the order book and your fills on a websocket. It is built to place orders on the Novig exchange.<\/p>\n<p>If you want to read Novig&#8217;s prices next to Pinnacle, Kalshi, ProphetX and 350+ other bookmakers, with closing lines for backtests, OddsPapi carries the book under one slug: <code>novig.us<\/code>. It ships three levels of back and lay depth on every outcome. On 16 NFL Week 3 fixtures (24-29 September 2026), <strong><code>novig.us<\/code> closed the moneyline at a 0.51% median overround against Pinnacle&#8217;s 2.63%<\/strong>, and its no-vig price sat a median 0.67 points from Pinnacle&#8217;s. This guide shows you how to find the slug, read both sides of the order book, pull the player props and check the close yourself.<\/p>\n<h2>What the Novig trading API covers, and what a price pipeline needs<\/h2>\n<p>A trading API answers one question well: what can I fill on this venue right now? A pricing model asks more. It wants the Novig price next to the sharp books, in one schema, plus every snapshot after the fixture is played. If you already read Kalshi or ProphetX, you know the cost: one auth scheme per venue, one market format per venue, and your own recorder for history.<\/p>\n<p>OddsPapi gives Novig the same JSON shape as every other book on the board. A Novig outcome looks like a Pinnacle outcome, plus an <code>exchangeMeta<\/code> block that holds the ladder. Our <a href=\"https:\/\/oddspapi.io\/blog\/nfl-prediction-market-liquidity\/\">NFL prediction market liquidity study<\/a> ranked seven peer-to-peer venues on depth. This post goes one level down: how to read the <code>novig.us<\/code> block itself.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>Novig trading API<\/th>\n<th>OddsPapi <code>novig.us<\/code><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Built for<\/td>\n<td>Placing and managing orders on Novig<\/td>\n<td>Reading Novig prices next to other books<\/td>\n<\/tr>\n<tr>\n<td>Auth<\/td>\n<td>Management key from your Novig profile, signed requests (Ed25519 or P-256)<\/td>\n<td>One <code>apiKey<\/code> query parameter<\/td>\n<\/tr>\n<tr>\n<td>Venues<\/td>\n<td>Novig<\/td>\n<td>Novig plus 350+ bookmakers and exchanges, one schema<\/td>\n<\/tr>\n<tr>\n<td>Depth<\/td>\n<td>Order book and fills on a websocket<\/td>\n<td>Three back and three lay levels per outcome, REST and WebSocket<\/td>\n<\/tr>\n<tr>\n<td>Played fixtures<\/td>\n<td>See Novig&#8217;s docs<\/td>\n<td><code>\/v4\/historical-odds<\/code> on the free tier, back to 20+ days before an NFL kickoff<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>Where novig.us prices today<\/h2>\n<p>We probed up to five upcoming fixtures with odds in each of 35 tournaments across 17 sports on 2 October 2026 at 13:08 UTC, with <code>bookmakers=novig.us<\/code>. Novig priced six tournaments:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Tournament<\/th>\n<th>Fixtures priced<\/th>\n<th>Markets per fixture<\/th>\n<th>Player prop markets<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>NFL<\/td>\n<td>5 of 5<\/td>\n<td>175 to 197 (median 191)<\/td>\n<td>121 to 140<\/td>\n<\/tr>\n<tr>\n<td>NCAA football<\/td>\n<td>5 of 5<\/td>\n<td>55 to 77<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>MLB (postseason)<\/td>\n<td>4 of 5<\/td>\n<td>22 to 45<\/td>\n<td>3 to 18<\/td>\n<\/tr>\n<tr>\n<td>NHL<\/td>\n<td>5 of 5<\/td>\n<td>23 to 25<\/td>\n<td>7 to 9<\/td>\n<\/tr>\n<tr>\n<td>WTA Beijing singles<\/td>\n<td>5 of 5<\/td>\n<td>13 to 14<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>UFC 332<\/td>\n<td>5 of 5<\/td>\n<td>5 to 6<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>The fifth MLB fixture was the next day&#8217;s game in the same series, and Novig had not opened it yet. On the soccer, basketball, CFL, AHL, Japanese and Korean baseball, darts, rugby and esports fixtures we sampled, the slug returned no prices. For those, Kalshi, <code>polymarket.us<\/code> and Pinnacle cover most of the gap. NBA preseason had no fixtures in the window, so we did not test it.<\/p>\n<h2>Step 1: find the Novig slug<\/h2>\n<p>Authentication is one query parameter, <code>apiKey<\/code>. The helper waits out a 429 for as long as the error body says, backs off on a 5xx, and returns <code>None<\/code> on a 404.<\/p>\n<pre class=\"wp-block-code\"><code>import os, time, requests\nfrom datetime import datetime, timedelta, timezone\nfrom statistics import median\n\nAPI_KEY = os.environ[&quot;ODDSPAPI_API_KEY&quot;]\nBASE = &quot;https:\/\/api.oddspapi.io\/v4&quot;\n\ndef get(path, **params):\n    params[&quot;apiKey&quot;] = API_KEY\n    for _ in range(5):\n        r = requests.get(f&quot;{BASE}\/{path}&quot;, params=params, timeout=180)\n        if r.status_code == 429:                      # rate limited: wait as told\n            time.sleep(r.json().get(&quot;error&quot;, {}).get(&quot;retryMs&quot;, 2000) \/ 1000 + 0.5)\n            continue\n        if r.status_code &gt;= 500:                      # transient: back off and retry\n            time.sleep(2)\n            continue\n        if r.status_code == 404:                      # empty window\n            return None\n        r.raise_for_status()\n        return r.json()\n    raise RuntimeError(f&quot;gave up on {path}&quot;)\n\nbooks = get(&quot;bookmakers&quot;)\nnovig = next(b for b in books if b[&quot;slug&quot;] == &quot;novig.us&quot;)\nprint(novig)\nprint(f&quot;{len(books)} bookmakers in the catalogue&quot;)<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>{&#x27;bookmakerName&#x27;: &#x27;Novig US&#x27;, &#x27;slug&#x27;: &#x27;novig.us&#x27;, &#x27;liveOdds&#x27;: True, &#x27;cloneOf&#x27;: None}\n363 bookmakers in the catalogue<\/code><\/pre>\n<p>One slug, <code>liveOdds: True<\/code>, no clone. Pass it alone in <code>bookmakers=<\/code> when you probe coverage. A 200 with the slug missing means Novig has not priced that fixture; a 403 would mean your key cannot read the book.<\/p>\n<h2>Step 2: count Novig&#8217;s markets per fixture<\/h2>\n<p>This step pulls the next two fixtures in four tournaments and counts Novig&#8217;s markets. It reads the global <code>\/v4\/markets<\/code> catalogue once to flag player props.<\/p>\n<pre class=\"wp-block-code\"><code># Reuses get() and the imports from Step 1.\nMARKETS = {m[&quot;marketId&quot;]: m for m in get(&quot;markets&quot;)}       # name lookup for every market ID\n\nnow = datetime.now(timezone.utc)\nwindow = {&quot;from&quot;: now.strftime(&quot;%Y-%m-%d&quot;), &quot;to&quot;: (now + timedelta(days=4)).strftime(&quot;%Y-%m-%d&quot;)}\nTOURNAMENTS = {31: &quot;NFL&quot;, 27653: &quot;NCAAF&quot;, 109: &quot;MLB&quot;, 234: &quot;NHL&quot;}\n\nfor tid, name in TOURNAMENTS.items():\n    fixtures = get(&quot;fixtures&quot;, tournamentId=tid, **window) or []\n    upcoming = sorted((f for f in fixtures if f[&quot;hasOdds&quot;] and f[&quot;startTime&quot;] &gt; now.isoformat()),\n                      key=lambda f: f[&quot;startTime&quot;])[:2]\n    for fx in upcoming:\n        data = get(&quot;odds&quot;, fixtureId=fx[&quot;fixtureId&quot;], bookmakers=&quot;novig.us&quot;)\n        book = data[&quot;bookmakerOdds&quot;].get(&quot;novig.us&quot;)\n        time.sleep(1.0)\n        if not book:\n            print(f&quot;{name:&lt;6} {fx[&#x27;participant1Name&#x27;][:22]:&lt;22} not priced yet&quot;)\n            continue\n        props = sum(MARKETS.get(int(mid), {}).get(&quot;playerProp&quot;, False) for mid in book[&quot;markets&quot;])\n        print(f&quot;{name:&lt;6} {fx[&#x27;participant1Name&#x27;][:22]:&lt;22} v {fx[&#x27;participant2Name&#x27;][:22]:&lt;22} &quot;\n              f&quot;{len(book[&#x27;markets&#x27;]):&gt;3} markets, {props:&gt;3} player props&quot;)<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>NFL    Washington Commanders  v Indianapolis Colts     193 markets, 136 player props\nNFL    Baltimore Ravens       v Tennessee Titans       197 markets, 140 player props\nNCAAF  Delaware Blue Hens     v Liberty Flames          72 markets,   0 player props\nNCAAF  Virginia Tech Hokies   v Pittsburgh Panthers     77 markets,   0 player props\nMLB    Cleveland Guardians    v Chicago White Sox       43 markets,  18 player props\nMLB    Los Angeles Dodgers    v Atlanta Braves          22 markets,   3 player props\nNHL    Detroit Red Wings      v New York Rangers        24 markets,   7 player props\nNHL    Carolina Hurricanes    v Washington Capitals     25 markets,   9 player props<\/code><\/pre>\n<p>The NFL board is the deep one. On the five Week 4 Sunday fixtures we pulled, Novig listed 26 to 31 players with props each, across receiving yards, rushing yards, passing yards, receptions, touchdowns and first touchdown scorer. College football carries spreads, totals, team totals and first-half lines, with no props. The NHL board adds shots on goal, points, assists, goals and saves.<\/p>\n<h2>Step 3: read both sides of the Novig order book<\/h2>\n<p>Every Novig price ships an <code>exchangeMeta<\/code> block with up to three <code>back<\/code> levels and three <code>lay<\/code> levels. Each level carries four numbers: <code>price<\/code> (decimal odds), <code>cents<\/code> (the contract price, 0 to 1), <code>size<\/code> (contracts) and <code>limit<\/code> (the stake at that level). This step resolves the moneyline by name, then prints the ladder for both outcomes.<\/p>\n<pre class=\"wp-block-code\"><code># Reuses get() and the imports from Step 1.\nMARKETS = {m[&quot;marketId&quot;]: m for m in get(&quot;markets&quot;)}\nnow = datetime.now(timezone.utc)\nfixtures = get(&quot;fixtures&quot;, tournamentId=31,                   # NFL\n               **{&quot;from&quot;: now.strftime(&quot;%Y-%m-%d&quot;), &quot;to&quot;: (now + timedelta(days=4)).strftime(&quot;%Y-%m-%d&quot;)})\nfx = min((f for f in fixtures if f[&quot;startTime&quot;] &gt; now.isoformat()), key=lambda f: f[&quot;startTime&quot;])\nbook = get(&quot;odds&quot;, fixtureId=fx[&quot;fixtureId&quot;], bookmakers=&quot;novig.us&quot;)[&quot;bookmakerOdds&quot;][&quot;novig.us&quot;]\n\n# Resolve the moneyline by name, never by a hardcoded ID\nmid = next(k for k in book[&quot;markets&quot;]\n           if MARKETS[int(k)][&quot;marketName&quot;].startswith(&quot;Winner&quot;) and MARKETS[int(k)][&quot;period&quot;] == &quot;result&quot;)\nnames = {o[&quot;outcomeId&quot;]: o[&quot;outcomeName&quot;] for o in MARKETS[int(mid)][&quot;outcomes&quot;]}\nlegs = {names[int(oid)]: o[&quot;players&quot;][&quot;0&quot;] for oid, o in book[&quot;markets&quot;][mid][&quot;outcomes&quot;].items()}\nlegs = dict(sorted(legs.items()))                            # &quot;1&quot; first, then &quot;2&quot;\nteam = {&quot;1&quot;: fx[&quot;participant1Name&quot;], &quot;2&quot;: fx[&quot;participant2Name&quot;]}\nprint(f&quot;{fx[&#x27;participant1Name&#x27;]} v {fx[&#x27;participant2Name&#x27;]}  market {mid}\\n&quot;)\n\nfor name, p in legs.items():\n    print(f&quot;Outcome {name} ({team[name]})&quot;)\n    for side in (&quot;back&quot;, &quot;lay&quot;):\n        for lvl in p[&quot;exchangeMeta&quot;][side]:\n            ok = abs(lvl[&quot;limit&quot;] - lvl[&quot;size&quot;] * lvl[&quot;cents&quot;]) &lt; 0.02\n            print(f&quot;  {side:&lt;4} {lvl[&#x27;price&#x27;]:&gt;6.3f}  cents {lvl[&#x27;cents&#x27;]:.3f}  size {lvl[&#x27;size&#x27;]:&gt;9.2f}  &quot;\n                  f&quot;limit {lvl[&#x27;limit&#x27;]:&gt;8.2f}  limit == size x cents: {ok}&quot;)\n\na, b = legs.values()\nmirror = all(abs(x[&quot;limit&quot;] - y[&quot;limit&quot;]) &lt;= 0.02 and x[&quot;price&quot;] == y[&quot;price&quot;]\n             for x, y in zip(a[&quot;exchangeMeta&quot;][&quot;lay&quot;], b[&quot;exchangeMeta&quot;][&quot;back&quot;]))\nover = 1 \/ a[&quot;price&quot;] + 1 \/ b[&quot;price&quot;] - 1\nprint(f&quot;\\nOutcome 1 lay ladder == outcome 2 back ladder: {mirror}&quot;)\nprint(f&quot;Best-back overround: {over:.2%}   top-of-book stake: {min(a[&#x27;limit&#x27;], b[&#x27;limit&#x27;]):.2f}&quot;)<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>Washington Commanders v Indianapolis Colts  market 141\n\nOutcome 1 (Washington Commanders)\n  back  2.778  cents 0.360  size  67211.32  limit 24196.08  limit == size x cents: True\n  back  2.740  cents 0.365  size  14071.56  limit  5136.12  limit == size x cents: True\n  back  2.703  cents 0.370  size  47064.12  limit 17413.72  limit == size x cents: True\n  lay   1.550  cents 0.645  size    351.63  limit   226.80  limit == size x cents: True\n  lay   1.538  cents 0.650  size  19536.17  limit 12698.51  limit == size x cents: True\n  lay   1.527  cents 0.655  size  16487.45  limit 10799.28  limit == size x cents: True\nOutcome 2 (Indianapolis Colts)\n  back  1.550  cents 0.645  size    351.63  limit   226.80  limit == size x cents: True\n  back  1.538  cents 0.650  size  19536.17  limit 12698.51  limit == size x cents: True\n  back  1.527  cents 0.655  size  16487.45  limit 10799.28  limit == size x cents: True\n  lay   2.778  cents 0.360  size  67211.32  limit 24196.08  limit == size x cents: True\n  lay   2.740  cents 0.365  size  14071.56  limit  5136.12  limit == size x cents: True\n  lay   2.703  cents 0.370  size  47064.12  limit 17413.72  limit == size x cents: True\n\nOutcome 1 lay ladder == outcome 2 back ladder: True\nBest-back overround: 0.51%   top-of-book stake: 226.80<\/code><\/pre>\n<p>Read three things off that output.<\/p>\n<ul>\n<li><strong>One book, two views.<\/strong> Outcome 1&#8217;s lay ladder is outcome 2&#8217;s back ladder, level for level. Across 2,211 active two-way pairs on the 29 boards in our census, the mirror held on 2,200, to a 0.02 rounding on <code>limit<\/code>. So you can read one outcome and know both sides of the market. Do not count Novig twice in a consensus by treating the lay ladder as a second quote.<\/li>\n<li><strong><code>limit<\/code> is <code>size<\/code> times <code>cents<\/code>.<\/strong> That held on 13,499 of 13,499 ladder levels. Size counts contracts. Limit is what it costs to take them.<\/li>\n<li><strong>The top level can be thin while level two is deep.<\/strong> The Colts back at 1.550 carried 226.80 of stake. One tick worse, at 1.538, it carried 12,698.51. A fill model that reads only the best price undercounts this book.<\/li>\n<\/ul>\n<p>The best-back prices on that moneyline add up to a 0.51% overround: the two contract prices, 0.360 and 0.645, sum to 1.005, one half-cent tick. Novig also publishes <code>bookmakerChangedAt<\/code> on 4,497 of 6,674 prices in our census, so you can measure how old a quote is on most of the board.<\/p>\n<p>On the same five NFL boards, with the same filter, the other venues priced the moneyline like this:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Venue<\/th>\n<th>Median best-back overround, NFL moneyline (5 fixtures, 2 Oct)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>polymarket.us<\/code><\/td>\n<td>0.25%<\/td>\n<\/tr>\n<tr>\n<td><code>novig.us<\/code><\/td>\n<td>0.50%<\/td>\n<\/tr>\n<tr>\n<td><code>prophetx<\/code><\/td>\n<td>0.66%<\/td>\n<\/tr>\n<tr>\n<td><code>kalshi<\/code><\/td>\n<td>1.01%<\/td>\n<\/tr>\n<tr>\n<td><code>pinnacle<\/code><\/td>\n<td>3.61%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>On an exchange, check depth before you trust a tight price. <code>polymarket.us<\/code> shipped <code>limit: 0<\/code> on these prices, so check its <code>size<\/code> before you size against it. The <a href=\"https:\/\/oddspapi.io\/blog\/prophet-exchange-api-us-regulated\/\">ProphetX guide<\/a> covers that venue&#8217;s ladder, which has no <code>size<\/code> field.<\/p>\n<h2>Step 4: pull Novig player props by player<\/h2>\n<p>On player props, the <code>players<\/code> dict is keyed by player ID, and each entry carries a <code>playerName<\/code> in &#8220;Last, First&#8221; form. A parser that hardcodes <code>players[\"0\"]<\/code> sees an empty prop board. This step reuses the fixture and book from Step 3.<\/p>\n<pre class=\"wp-block-code\"><code># Reuses MARKETS, fx and book from Step 3.\nfrom collections import defaultdict\n\nby_player = defaultdict(list)\nstake = {&quot;player props&quot;: [], &quot;game lines&quot;: []}\nfor mid, m in book[&quot;markets&quot;].items():\n    meta = MARKETS[int(mid)]\n    outcome_name = {o[&quot;outcomeId&quot;]: o[&quot;outcomeName&quot;] for o in meta[&quot;outcomes&quot;]}\n    for oid, o in m[&quot;outcomes&quot;].items():\n        for pid, p in o[&quot;players&quot;].items():                # props are keyed by player ID, not &quot;0&quot;\n            if not p.get(&quot;active&quot;):\n                continue\n            stake[&quot;player props&quot; if meta[&quot;playerProp&quot;] else &quot;game lines&quot;].append(p[&quot;limit&quot;])\n            if meta[&quot;playerProp&quot;]:\n                by_player[p[&quot;playerName&quot;]].append((meta[&quot;marketName&quot;], meta[&quot;handicap&quot;],\n                                                   outcome_name[int(oid)], p))\n\nprint(f&quot;{len(by_player)} players with an active prop\\n&quot;)\nfor name, rows in sorted(by_player.items(), key=lambda kv: -len(kv[1]))[:5]:\n    families = sorted({r[0].replace(&quot; (incl. overtime)&quot;, &quot;&quot;).replace(&quot;Over Under &quot;, &quot;&quot;) for r in rows})\n    print(f&quot;{name:&lt;22} {len(rows):&gt;3} prices  {&#x27;, &#x27;.join(families)}&quot;)\n\nfor kind, limits in stake.items():\n    print(f&quot;\\nMedian top-of-book stake, {kind}: {median(limits):,.2f} over {len(limits)} prices&quot;, end=&quot;&quot;)\n\nname, rows = max(by_player.items(), key=lambda kv: len(kv[1]))\nrungs = defaultdict(dict)\nfor market, line, side, p in rows:\n    if market.startswith(&quot;Over Under Rush Yards&quot;):\n        rungs[line][side] = p\nprint(f&quot;\\n\\n{name}, Rush Yards rungs with both sides posted&quot;)\nfor line, sides in sorted(rungs.items()):\n    if len(sides) == 2:\n        o, u = sides[&quot;Over&quot;], sides[&quot;Under&quot;]\n        print(f&quot;  {line:&gt;6}  over {o[&#x27;price&#x27;]:&gt;6.3f}  under {u[&#x27;price&#x27;]:&gt;6.3f}  &quot;\n              f&quot;overround {1\/o[&#x27;price&#x27;] + 1\/u[&#x27;price&#x27;] - 1:&gt;6.2%}  stake {min(o[&#x27;limit&#x27;], u[&#x27;limit&#x27;]):&gt;7.2f}&quot;)<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>31 players with an active prop\n\nTaylor, Jonathan        61 prices  Longest Rush Yards, Player Receiving Yards, Player Receptions, Player TD, Player To Score First TD, Rush Attempts, Rush Yards\nMariota, Marcus         59 prices  Longest Rush Yards, Pass Attempts, Pass Completions, Pass Yards, Player Interceptions, Player TD, Player TD Passes, Player To Score First TD, Rush Attempts, Rush Yards\nJones, Daniel           52 prices  Longest Rush Yards, Pass Attempts, Pass Completions, Pass Yards, Player Interceptions, Player TD, Player TD Passes, Player To Score First TD, Rush Attempts, Rush Yards\nMcLaurin, Terry         48 prices  Player Receiving Yards, Player Receptions, Player TD, Player To Score First TD\nDowns, Josh             45 prices  Player Receiving Yards, Player Receptions, Player TD, Player To Score First TD\n\nMedian top-of-book stake, player props: 17.08 over 523 prices\nMedian top-of-book stake, game lines: 525.67 over 114 prices\n\nTaylor, Jonathan, Rush Yards rungs with both sides posted\n    49.5  over  1.111  under  2.564  overround 29.01%  stake   19.80\n    59.5  over  1.220  under  2.222  overround 26.97%  stake    9.84\n    69.5  over  1.351  under  3.030  overround  7.02%  stake    0.99\n    79.5  over  1.562  under  2.326  overround  7.01%  stake    1.72\n    89.5  over  1.835  under  1.942  overround  5.99%  stake   26.55\n    90.5  over  2.000  under  1.887  overround  2.99%  stake   12.00\n    92.5  over  2.151  under  1.449  overround 15.50%  stake  445.16\n    99.5  over  2.198  under  1.667  overround  5.48%  stake  141.13\n   109.5  over  2.740  under  1.449  overround  5.51%  stake    2.76\n   139.5  over  5.882  under  1.053  overround 11.97%  stake   14.45<\/code><\/pre>\n<p>Novig&#8217;s prop book runs wider and thinner than its game lines. On the five NFL boards, 962 prop rungs had both sides posted. Their median overround was 5.98%, and the median top-of-book stake was 10.30. The 279 two-sided game-line rungs, alt spreads and totals included, ran at 2.03% with a median stake of 312.50. Within one player, the spread moves from rung to rung: Jonathan Taylor&#8217;s tightest rushing line, 90.5, priced at 2.99%, and the rungs either side of it were two to five times wider. Scan for the tight rung before you compare Novig with a sportsbook prop. Our <a href=\"https:\/\/oddspapi.io\/blog\/nfl-player-props-api\/\">NFL player props guide<\/a> shows the same markets across the retail books.<\/p>\n<h2>Step 5: check Novig&#8217;s NFL closing line against Pinnacle<\/h2>\n<p>OddsPapi stores every Novig snapshot. On the two Week 1 fixtures we checked, <code>novig.us<\/code> history began 20 and 28 days before kickoff. This step pulls Novig and Pinnacle from <code>\/v4\/historical-odds<\/code> for every played Week 3 fixture, takes the last active snapshot before kickoff on each side, and compares the two closes.<\/p>\n<pre class=\"wp-block-code\"><code># Reuses get() and the imports from Step 1.\nMARKETS = {m[&quot;marketId&quot;]: m for m in get(&quot;markets&quot;)}\nts = lambda s: datetime.fromisoformat(s.replace(&quot;Z&quot;, &quot;+00:00&quot;))\n\ndef close(book, start):\n    &quot;&quot;&quot;Last ACTIVE pre-kickoff snapshot per outcome on the moneyline, or None.&quot;&quot;&quot;\n    if not book:\n        return None\n    mid = next((k for k in book[&quot;markets&quot;] if MARKETS[int(k)][&quot;marketName&quot;].startswith(&quot;Winner&quot;)\n                and MARKETS[int(k)][&quot;period&quot;] == &quot;result&quot;), None)\n    if mid is None:\n        return None\n    out = {}\n    for oid, o in book[&quot;markets&quot;][mid][&quot;outcomes&quot;].items():\n        snaps = [s for s in o[&quot;players&quot;][&quot;0&quot;] if s[&quot;active&quot;] and ts(s[&quot;createdAt&quot;]) &lt; start]\n        if snaps:\n            out[oid] = snaps[-1][&quot;price&quot;]\n    return out if len(out) == 2 else None\n\nplayed = get(&quot;fixtures&quot;, tournamentId=31, **{&quot;from&quot;: &quot;2026-09-24&quot;, &quot;to&quot;: &quot;2026-09-30&quot;})   # NFL Week 3\nplayed = [f for f in played if f[&quot;statusName&quot;] == &quot;Finished&quot;]\nrows = []\nfor f in played:\n    hist = get(&quot;historical-odds&quot;, fixtureId=f[&quot;fixtureId&quot;], bookmakers=&quot;novig.us,pinnacle&quot;)\n    time.sleep(4.6)                                          # \/historical-odds needs the longer pause\n    start = ts(f[&quot;startTime&quot;])\n    n, p = close(hist[&quot;bookmakers&quot;].get(&quot;novig.us&quot;), start), close(hist[&quot;bookmakers&quot;].get(&quot;pinnacle&quot;), start)\n    if not (n and p):\n        continue\n    n_over, p_over = sum(1 \/ v for v in n.values()), sum(1 \/ v for v in p.values())\n    k = sorted(n)[0]                                         # participant 1&#x27;s outcome\n    gap = abs((1 \/ n[k]) \/ n_over - (1 \/ p[k]) \/ p_over)     # no-vig probability gap\n    better = sum(n[o] &gt;= p[o] for o in n)\n    rows.append((n_over - 1, p_over - 1, gap, better))\n    print(f&quot;{f[&#x27;participant1Name&#x27;][:20]:&lt;20} v {f[&#x27;participant2Name&#x27;][:20]:&lt;20} &quot;\n          f&quot;novig {n_over - 1:&gt;5.2%}  pinnacle {p_over - 1:&gt;5.2%}  no-vig gap {gap * 100:.2f} pts&quot;)\n\nprint(f&quot;\\n{len(rows)} fixtures. Median close overround: novig.us {median(r[0] for r in rows):.2%}, &quot;\n      f&quot;pinnacle {median(r[1] for r in rows):.2%}&quot;)\nprint(f&quot;Median no-vig gap {median(r[2] for r in rows) * 100:.2f} pts, max {max(r[2] for r in rows) * 100:.2f}&quot;)\nprint(f&quot;novig.us close at or above pinnacle on {sum(r[3] for r in rows)} of {2 * len(rows)} sides&quot;)<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>Green Bay Packers    v Atlanta Falcons      novig 0.49%  pinnacle 2.71%  no-vig gap 0.83 pts\nBuffalo Bills        v Los Angeles Chargers novig 0.97%  pinnacle 3.04%  no-vig gap 0.49 pts\nCleveland Browns     v Carolina Panthers    novig 0.49%  pinnacle 2.54%  no-vig gap 0.26 pts\nDetroit Lions        v New York Jets        novig 0.52%  pinnacle 3.01%  no-vig gap 0.09 pts\nIndianapolis Colts   v Houston Texans       novig 0.50%  pinnacle 2.52%  no-vig gap 0.44 pts\nJacksonville Jaguars v New England Patriots novig 0.49%  pinnacle 2.58%  no-vig gap 0.19 pts\nMiami Dolphins       v Kansas City Chiefs   novig 1.03%  pinnacle 3.24%  no-vig gap 1.38 pts\nNew York Giants      v Tennessee Titans     novig 1.01%  pinnacle 2.36%  no-vig gap 0.65 pts\nPittsburgh Steelers  v Cincinnati Bengals   novig 0.51%  pinnacle 2.52%  no-vig gap 0.68 pts\nWashington Commander v Seattle Seahawks     novig 0.52%  pinnacle 3.06%  no-vig gap 1.38 pts\nSan Francisco 49ers  v Arizona Cardinals    novig 0.51%  pinnacle 3.07%  no-vig gap 1.33 pts\nTampa Bay Buccaneers v Minnesota Vikings    novig 0.49%  pinnacle 2.45%  no-vig gap 0.54 pts\nDallas Cowboys       v Baltimore Ravens     novig 1.01%  pinnacle 2.59%  no-vig gap 1.18 pts\nNew Orleans Saints   v Las Vegas Raiders    novig 0.99%  pinnacle 2.68%  no-vig gap 0.74 pts\nDenver Broncos       v Los Angeles Rams     novig 0.51%  pinnacle 2.45%  no-vig gap 0.96 pts\nChicago Bears        v Philadelphia Eagles  novig 0.49%  pinnacle 2.77%  no-vig gap 0.37 pts\n\n16 fixtures. Median close overround: novig.us 0.51%, pinnacle 2.63%\nMedian no-vig gap 0.67 pts, max 1.38\nnovig.us close at or above pinnacle on 30 of 32 sides<\/code><\/pre>\n<p>Novig closed 11 of the 16 moneylines at one half-cent tick (0.49% to 0.52%) and the other five at two ticks. Its no-vig probability landed within 1.38 points of Pinnacle&#8217;s on all 16, with a median gap of 0.67. The quoted Novig price was at or above Pinnacle&#8217;s on 30 of 32 sides. Novig&#8217;s <a href=\"https:\/\/support.novig.com\/en\/articles\/16195057-fees-on-novig\">fee schedule<\/a> lists no fee on pre-game straight trades, which is what a closing price is. Live and futures trades carry a taker fee, so net those out before you compare an in-play Novig price.<\/p>\n<p>Two things to keep in mind when you build on this history. Snapshots record polling, so collapse identical consecutive prices before you count line moves: the Week 3 moneylines held a median of 1,589 snapshots and 295 price changes each. And historical snapshots carry <code>exchangeMeta: null<\/code>, so the three-level ladder exists live only; the history keeps the top-level <code>price<\/code> and <code>limit<\/code>. To turn these closes into a strategy test, start from our <a href=\"https:\/\/oddspapi.io\/blog\/backtest-betting-model-free-historical-odds\/\">backtesting guide<\/a>. For live fills, swap the polling loop for the <a href=\"https:\/\/oddspapi.io\/blog\/websocket-odds-api-real-time-betting-data\/\">WebSocket feed<\/a>.<\/p>\n<p>For a one-page view of the slug, see the <a href=\"https:\/\/oddspapi.io\/sportsbooks\/novig-us\">Novig US sportsbook page<\/a>. To compare Novig with the two biggest prediction markets, read <a href=\"https:\/\/oddspapi.io\/blog\/kalshi-vs-polymarket-api\/\">Kalshi API vs Polymarket API<\/a>.<\/p>\n<h2>Novig API FAQ<\/h2>\n<h3>Does Novig have an API?<\/h3>\n<p>Yes. Novig documents a trading API at docs.novig.com, with signed REST requests and a websocket for the order book and your fills. To read Novig prices next to 350+ other bookmakers, with history, use the novig.us slug on OddsPapi.<\/p>\n<h3>How do I get Novig odds in Python?<\/h3>\n<p>Call \/v4\/odds with a fixtureId and bookmakers=novig.us, passing your key as the apiKey query parameter. Each outcome returns a decimal price, a limit and an exchangeMeta block with three back and three lay levels.<\/p>\n<h3>Which sports does novig.us cover on OddsPapi?<\/h3>\n<p>On 2 October 2026, novig.us priced the NFL (175 to 197 markets per fixture, including player props), NCAA football, MLB, the NHL, WTA singles and the UFC.<\/p>\n<h3>What do size, cents and limit mean in Novig&#8217;s exchangeMeta?<\/h3>\n<p>cents is the contract price between 0 and 1, size is the number of contracts at that level, and limit is the stake, equal to size times cents. That identity held on 13,499 of 13,499 ladder levels we measured.<\/p>\n<h3>Can I get historical Novig odds?<\/h3>\n<p>Yes. \/v4\/historical-odds returns every novig.us snapshot on a played fixture, on the free tier. On 16 NFL Week 3 fixtures, Novig closed the moneyline at a 0.51% median overround, against 2.63% at Pinnacle.<\/p>\n<h2>Read the Novig book next to the board<\/h2>\n<p>Every call in this guide runs on the free key: 350+ bookmakers in the catalogue, free historical odds for the closing-line check, and a WebSocket feed when polling gets too slow. <a href=\"https:\/\/oddspapi.io\/en\/sign-up\">Get a free API key<\/a> and run Step 3 on Sunday&#8217;s NFL slate.<\/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\": \"Does Novig have an API?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes. Novig documents a trading API at docs.novig.com, with signed REST requests and a websocket for the order book and your fills. To read Novig prices next to 350+ other bookmakers, with history, use the novig.us slug on OddsPapi.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"How do I get Novig odds in Python?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Call \/v4\/odds with a fixtureId and bookmakers=novig.us, passing your key as the apiKey query parameter. Each outcome returns a decimal price, a limit and an exchangeMeta block with three back and three lay levels.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Which sports does novig.us cover on OddsPapi?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"On 2 October 2026, novig.us priced the NFL (175 to 197 markets per fixture, including player props), NCAA football, MLB, the NHL, WTA singles and the UFC.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"What do size, cents and limit mean in Novig's exchangeMeta?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"cents is the contract price between 0 and 1, size is the number of contracts at that level, and limit is the stake, equal to size times cents. That identity held on 13,499 of 13,499 ladder levels we measured.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Can I get historical Novig odds?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes. \/v4\/historical-odds returns every novig.us snapshot on a played fixture, on the free tier. On 16 NFL Week 3 fixtures, Novig closed the moneyline at a 0.51% median overround, against 2.63% at Pinnacle.\"\n      }\n    }\n  ]\n}\n<\/script><\/p>\n<p><!--\nFocus Keyphrase: novig api\nSEO Title: Novig API: Read Both Sides of a 191-Market NFL Board\nMeta Description: Read the Novig API order book next to 350+ books. On 16 NFL Week 3 fixtures, novig.us closed the moneyline at 0.51% overround against Pinnacle's 2.63%.\nSlug: novig-api-odds-access\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Read the Novig API order book next to 350+ books. On 16 NFL Week 3 fixtures, novig.us closed the moneyline at 0.51% overround against Pinnacle&#8217;s 2.63%.<\/p>\n","protected":false},"author":2,"featured_media":4690,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[4,52,105,9,11,10],"class_list":["post-4689","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to-guides","tag-historical-odds","tag-nfl","tag-novig","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>Novig API: Read Both Sides of a 191-Market NFL Board | 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\/novig-api-odds-access\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Novig API: Read Both Sides of a 191-Market NFL Board | OddsPapi Blog\" \/>\n<meta property=\"og:description\" content=\"Read the Novig API order book next to 350+ books. On 16 NFL Week 3 fixtures, novig.us closed the moneyline at 0.51% overround against Pinnacle&#039;s 2.63%.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/\" \/>\n<meta property=\"og:site_name\" content=\"OddsPapi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-13T10:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.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=\"19 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/\"},\"author\":{\"name\":\"Odds API Writer\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\"},\"headline\":\"Novig API: Read Both Sides of a 191-Market NFL Board\",\"datePublished\":\"2026-10-13T10:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/\"},\"wordCount\":1597,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp\",\"keywords\":[\"historical odds\",\"NFL\",\"Novig\",\"Odds API\",\"Python\",\"Sports Betting API\"],\"articleSection\":[\"How To Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/\",\"name\":\"Novig API: Read Both Sides of a 191-Market NFL Board | OddsPapi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp\",\"datePublished\":\"2026-10-13T10:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp\",\"width\":1200,\"height\":675,\"caption\":\"Novig API header image\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oddspapi.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Novig API: Read Both Sides of a 191-Market NFL Board\"}]},{\"@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":"Novig API: Read Both Sides of a 191-Market NFL Board | 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\/novig-api-odds-access\/","og_locale":"en_US","og_type":"article","og_title":"Novig API: Read Both Sides of a 191-Market NFL Board | OddsPapi Blog","og_description":"Read the Novig API order book next to 350+ books. On 16 NFL Week 3 fixtures, novig.us closed the moneyline at 0.51% overround against Pinnacle's 2.63%.","og_url":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/","og_site_name":"OddsPapi Blog","article_published_time":"2026-10-13T10:00:00+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.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":"19 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#article","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/"},"author":{"name":"Odds API Writer","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13"},"headline":"Novig API: Read Both Sides of a 191-Market NFL Board","datePublished":"2026-10-13T10:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/"},"wordCount":1597,"commentCount":0,"publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp","keywords":["historical odds","NFL","Novig","Odds API","Python","Sports Betting API"],"articleSection":["How To Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/","url":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/","name":"Novig API: Read Both Sides of a 191-Market NFL Board | OddsPapi Blog","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp","datePublished":"2026-10-13T10:00:00+00:00","breadcrumb":{"@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#primaryimage","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/novig-api-odds-access.webp","width":1200,"height":675,"caption":"Novig API header image"},{"@type":"BreadcrumbList","@id":"https:\/\/oddspapi.io\/blog\/novig-api-odds-access\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oddspapi.io\/blog\/"},{"@type":"ListItem","position":2,"name":"Novig API: Read Both Sides of a 191-Market NFL Board"}]},{"@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\/4689","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=4689"}],"version-history":[{"count":2,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/4689\/revisions"}],"predecessor-version":[{"id":4692,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/4689\/revisions\/4692"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media\/4690"}],"wp:attachment":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media?parent=4689"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/categories?post=4689"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/tags?post=4689"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}