{"id":3186,"date":"2026-08-14T10:00:00","date_gmt":"2026-08-14T10:00:00","guid":{"rendered":"https:\/\/oddspapi.io\/blog\/?p=3186"},"modified":"2026-08-29T14:57:45","modified_gmt":"2026-08-29T14:57:45","slug":"college-football-odds-api","status":"publish","type":"post","link":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/","title":{"rendered":"College Football Odds API: NCAAF Lines, Spreads and Totals"},"content":{"rendered":"<p>You point <code>\/odds<\/code> at a Week 1 college football game, filter on <code>active == True<\/code> the way every parsing tutorial tells you to, and get back almost nothing. Fifteen bookmakers are on the fixture. Your dict is empty.<\/p>\n<p>The odds are there. On the eight NCAA Week 1 fixtures we pulled on August 5, 2026, bookmakers had posted <strong>1,649 prices and flagged 958 of them <code>active: false<\/code><\/strong>. That is 58% of the college board sitting in the payload as suspended quotes. Filter them out and the season looks like it does not exist. Leave them in and you are reading numbers nobody will take a bet on.<\/p>\n<p>This guide covers the college football side of the OddsPapi feed: finding the NCAA tournament inside <code>sportId=14<\/code>, parsing spreads and totals where every line carries its own market ID, and reading the <code>active<\/code> flag so your scanner sees the board the way a trader does.<\/p>\n<h2>Why college football breaks odds parsers<\/h2>\n<p>The pro leagues train you into bad habits. An NFL Sunday game has sixteen books quoting a stable moneyline, one spread everyone agrees on, and a prop tree that fills in reliably. College football has 136 FBS programs, a schedule that runs from a Week 0 game in Dublin to December bowl season, and a book-by-book opening pattern that looks nothing like the NFL.<\/p>\n<p>Three things make it awkward:<\/p>\n<ul>\n<li><strong>Books open in waves.<\/strong> Pinnacle appeared on three of our eight Week 1 fixtures and quoted a moneyline on two of them. SBOBet, Circa, Bet365 and ten others appeared on all eight. Caesars posted a 109-market alt-line ladder on UNLV v Memphis and left 190 of its 218 outcomes suspended.<\/li>\n<li><strong>Sport 14 is not the NFL.<\/strong> The same <code>sportId<\/code> carries NFL, NFL Preseason, CFL, NCAA, AFLE and EFA. Filter on <code>tournamentId<\/code> or you will mix Canadian football into your college model.<\/li>\n<li><strong>Every line is a different market ID.<\/strong> There is no generic &#8220;spread&#8221; endpoint. Total 49.5 is market 1484, total 49 is 1482, spread -6.5 is 14260. Hardcode one and you will read empty dicts all season.<\/li>\n<\/ul>\n<p>Scraping ESPN or a book&#8217;s own site gives you one source, no history, and a rewrite every time the front end changes. The public sports APIs that do carry college football mostly ship a handful of US retail books, charge for historical data, and skip the sharps entirely.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Task<\/th>\n<th>Scraping \/ generic API<\/th>\n<th>OddsPapi<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Books per college fixture<\/td>\n<td>1 site, or ~8 US retail<\/td>\n<td>13 to 16, including Pinnacle, SBOBet, Circa, Kalshi<\/td>\n<\/tr>\n<tr>\n<td>Suspended vs live prices<\/td>\n<td>No signal, or silently dropped<\/td>\n<td><code>active<\/code> flag on every outcome<\/td>\n<\/tr>\n<tr>\n<td>Alt spreads and totals<\/td>\n<td>Main line only<\/td>\n<td>Full ladder, 112 distinct market IDs on one game<\/td>\n<\/tr>\n<tr>\n<td>Line history<\/td>\n<td>Paid add-on<\/td>\n<td>Free tier, snapshots from the day the book opened<\/td>\n<\/tr>\n<tr>\n<td>Stake limits<\/td>\n<td>Not published<\/td>\n<td><code>limit<\/code> on Pinnacle and exchange outcomes<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>Step 1: Find the college football tournament<\/h2>\n<p>Authentication is a query parameter. No headers, no OAuth dance.<\/p>\n<pre class=\"wp-block-code\"><code>import requests, time\n\nAPI_KEY = \"YOUR_API_KEY\"\nBASE_URL = \"https:\/\/api.oddspapi.io\/v4\"\nSPORT_ID = 14  # American Football\n\nr = requests.get(f\"{BASE_URL}\/tournaments\",\n                 params={\"apiKey\": API_KEY, \"sportId\": SPORT_ID})\n\nfor t in r.json():\n    if (t.get(\"futureFixtures\") or 0) &gt; 0:\n        print(f\"{t['tournamentId']:&gt;6}  {t['tournamentName']:&lt;22} \"\n              f\"{t.get('categoryName')}  future={t['futureFixtures']}\")<\/code><\/pre>\n<p>Live output on August 5, 2026:<\/p>\n<pre class=\"wp-block-code\"><code>    31  NFL                    USA            future=118\n   233  NFL Preseason          USA            future=49\n   790  CFL                    Canada         future=47\n 27653  NCAA, Regular Season   USA            future=3507\n 51578  EFA                    International  future=3\n 51580  AFLE                   International  future=12<\/code><\/pre>\n<p><strong>College football is tournament 27653<\/strong>, slug <code>ncaa-regular-season<\/code>, and it carries 3,507 scheduled fixtures. That number dwarfs the NFL&#8217;s 118 because it covers every FBS and FCS program on the calendar. Only a fraction of them carry odds at any moment, which is the next problem to solve.<\/p>\n<h2>Step 2: Pull fixtures and check <code>hasOdds<\/code><\/h2>\n<p>The <code>\/fixtures<\/code> endpoint takes a date range up to 10 days wide. Each fixture carries a <code>hasOdds<\/code> boolean. Skip the ones where it is false, because <code>\/odds<\/code> will return metadata and no prices.<\/p>\n<pre class=\"wp-block-code\"><code>NCAA = 27653\n\nr = requests.get(f\"{BASE_URL}\/fixtures\",\n                 params={\"apiKey\": API_KEY, \"sportId\": SPORT_ID,\n                         \"from\": \"2026-08-22\", \"to\": \"2026-08-31\"})\n\ngames = [f for f in r.json()\n         if f[\"tournamentId\"] == NCAA and f[\"hasOdds\"]]\n\nprint(f\"{len(games)} college fixtures with odds\")\nfor g in games[:3]:\n    print(\" \", g[\"fixtureId\"], g[\"startTime\"][:16],\n          g[\"participant1Name\"], \"v\", g[\"participant2Name\"])<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>8 college fixtures with odds\n  id1402765370894628 2026-08-29T16:00 TCU Horned Frogs v North Carolina Tar Heels\n  id1402765370898438 2026-08-29T19:00 USC Trojans v San Jose State Spartans\n  id1402765370894634 2026-08-29T19:30 Virginia Cavaliers v NC State Wolfpack<\/code><\/pre>\n<p>Eight fixtures out of 175 scheduled in that window. Three and a half weeks before kickoff, the books have opened the marquee games and left the rest closed. Run the same query in mid-September and the count climbs into the dozens.<\/p>\n<h2>Step 3: Parse the odds and count what is live<\/h2>\n<p>Here is the shape of a <code>\/odds<\/code> response. The top-level key is <code>bookmakerOdds<\/code>, and the path to a price runs four levels deep:<\/p>\n<pre class=\"wp-block-code\"><code>bookmakerOdds[slug][\"markets\"][market_id][\"outcomes\"][outcome_id][\"players\"][\"0\"]<\/code><\/pre>\n<p>That leaf dict holds <code>price<\/code> (decimal), <code>priceAmerican<\/code>, <code>priceFractional<\/code>, <code>limit<\/code>, <code>mainLine<\/code>, and the flag this whole post turns on:<\/p>\n<pre class=\"wp-block-code\"><code>FIXTURE = \"id1402765370894628\"  # TCU v North Carolina\n\nr = requests.get(f\"{BASE_URL}\/odds\",\n                 params={\"apiKey\": API_KEY, \"fixtureId\": FIXTURE})\nbooks = r.json().get(\"bookmakerOdds\", {})\n\nlive = suspended = 0\nfor book in books.values():\n    for market in book[\"markets\"].values():\n        for outcome in market[\"outcomes\"].values():\n            for entry in outcome[\"players\"].values():\n                if entry[\"active\"]:\n                    live += 1\n                else:\n                    suspended += 1\n\nprint(f\"{len(books)} bookmakers on the fixture\")\nprint(f\"{live} live prices, {suspended} suspended \"\n      f\"({100 * live \/ (live + suspended):.1f}% live)\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>16 bookmakers on the fixture\n130 live prices, 52 suspended (71.4% live)<\/code><\/pre>\n<p>TCU v North Carolina is one of the healthier boards. Run the same count across all eight fixtures and the picture changes.<\/p>\n<h2>The <code>active<\/code> flag census: 58% of the college board is suspended<\/h2>\n<p>We ran the loop above over every NCAA Week 1 fixture carrying odds on August 5, 2026. Per book, across all eight games:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Bookmaker<\/th>\n<th>Live prices<\/th>\n<th>Suspended<\/th>\n<th>% live<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>pinnacle<\/td>\n<td>90<\/td>\n<td>0<\/td>\n<td>100.0%<\/td>\n<\/tr>\n<tr>\n<td>kalshi<\/td>\n<td>8<\/td>\n<td>0<\/td>\n<td>100.0%<\/td>\n<\/tr>\n<tr>\n<td>betmgm<\/td>\n<td>34<\/td>\n<td>6<\/td>\n<td>85.0%<\/td>\n<\/tr>\n<tr>\n<td>borgata<\/td>\n<td>32<\/td>\n<td>6<\/td>\n<td>84.2%<\/td>\n<\/tr>\n<tr>\n<td>hardrockbet<\/td>\n<td>50<\/td>\n<td>14<\/td>\n<td>78.1%<\/td>\n<\/tr>\n<tr>\n<td>fourwinds<\/td>\n<td>40<\/td>\n<td>12<\/td>\n<td>76.9%<\/td>\n<\/tr>\n<tr>\n<td>ballybet \/ betparx \/ betrivers<\/td>\n<td>26 each<\/td>\n<td>10 each<\/td>\n<td>72.2%<\/td>\n<\/tr>\n<tr>\n<td>sbobet<\/td>\n<td>56<\/td>\n<td>24<\/td>\n<td>70.0%<\/td>\n<\/tr>\n<tr>\n<td>circasports<\/td>\n<td>28<\/td>\n<td>12<\/td>\n<td>70.0%<\/td>\n<\/tr>\n<tr>\n<td>bet365<\/td>\n<td>66<\/td>\n<td>34<\/td>\n<td>66.0%<\/td>\n<\/tr>\n<tr>\n<td>draftkings<\/td>\n<td>46<\/td>\n<td>24<\/td>\n<td>65.7%<\/td>\n<\/tr>\n<tr>\n<td>pointsbet.com.au<\/td>\n<td>27<\/td>\n<td>28<\/td>\n<td>49.1%<\/td>\n<\/tr>\n<tr>\n<td>caesars<\/td>\n<td>68<\/td>\n<td>384<\/td>\n<td>15.0%<\/td>\n<\/tr>\n<tr>\n<td>williamhill<\/td>\n<td>68<\/td>\n<td>384<\/td>\n<td>15.0%<\/td>\n<\/tr>\n<tr>\n<td><strong>All books<\/strong><\/td>\n<td><strong>691<\/strong><\/td>\n<td><strong>958<\/strong><\/td>\n<td><strong>41.9%<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>Two patterns fall out of that table.<\/p>\n<p><strong>Pinnacle and Kalshi never post a dead price.<\/strong> Both hit 100% live. When Pinnacle has an opinion it will take a bet on it, and when it does not, the market is absent from the payload rather than present and suspended. That makes Pinnacle&#8217;s presence a coverage signal on college football in a way it is not on the NFL.<\/p>\n<p><strong>Caesars and William Hill inflate the market count.<\/strong> On UNLV v Memphis, Caesars posted 109 markets: 61 total lines from 44.5 to 74.5, and 44 spreads from -20.5 to +20.5. Of its 218 outcomes, 28 were live. William Hill returned byte-identical numbers, which tracks: <code>\/v4\/bookmakers<\/code> flags the pair as clones, and they quote the same feed. If you count markets to rank coverage, these two will top your table on a board you cannot bet into.<\/p>\n<p>The fix is one line in your parser. Count books that quote <em>both sides live<\/em>, not books that appear in the payload:<\/p>\n<pre class=\"wp-block-code\"><code>def live_lines(books, market_id):\n    \"\"\"{slug: (price_a, price_b)} for books quoting BOTH sides live.\"\"\"\n    out = {}\n    for slug, book in books.items():\n        market = book[\"markets\"].get(str(market_id))\n        if not market:\n            continue\n        ids = sorted(int(o) for o in market[\"outcomes\"])\n        if len(ids) != 2:\n            continue\n        a, b = (market[\"outcomes\"][str(i)][\"players\"][\"0\"] for i in ids)\n        if a[\"active\"] and b[\"active\"]:\n            out[slug] = (a[\"price\"], b[\"price\"])\n    return out<\/code><\/pre>\n<p>Applied to the TCU moneyline, that gives you 15 books. Applied to the spread on the same fixture, it gives you 4. Both numbers are correct, and only one of them is safe to build a consensus on.<\/p>\n<h2>Step 4: Resolve market IDs instead of hardcoding them<\/h2>\n<p>College football spreads and totals follow the NFL convention: <strong>one market ID per line<\/strong>. Total 48.5 is 1480, total 49 is 1482, total 49.5 is 1484. Spread -6.5 is 14260, spread -7 is 14258. There is no stable &#8220;the totals market&#8221; ID to paste into your code.<\/p>\n<p>Worse, <code>\/v4\/markets<\/code> ignores the <code>sportId<\/code> parameter. Query it with <code>sportId=10<\/code> or <code>sportId=14<\/code> and you get the identical 32,815-row global catalogue both times, cricket innings markets included. Use it as a name lookup, never as a discovery tool for what a sport supports.<\/p>\n<p>The reliable move is to read the market IDs off a live payload and count how many books quote each one:<\/p>\n<pre class=\"wp-block-code\"><code>from collections import Counter\n\ncatalog = requests.get(f\"{BASE_URL}\/markets\",\n                       params={\"apiKey\": API_KEY, \"sportId\": SPORT_ID}).json()\nmarket_info = {m[\"marketId\"]: m for m in catalog}\n\ncounts = Counter()\nfor book in books.values():\n    for mid in book[\"markets\"]:\n        counts[int(mid)] += 1\n\nfor mid, n in counts.most_common(6):\n    info = market_info.get(mid, {})\n    print(f\"  {n:&gt;2} books  id={mid:&lt;7} {info.get('marketName')}  \"\n          f\"handicap={info.get('handicap')}\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>  15 books  id=141     Winner (incl. overtime)  handicap=0\n  12 books  id=1484    Total (incl. overtime)  handicap=49.5\n  10 books  id=14260   Handicap (incl. overtime)  handicap=-6.5\n   8 books  id=1480    Total (incl. overtime)  handicap=48.5\n   8 books  id=1482    Total (incl. overtime)  handicap=49\n   6 books  id=1486    Total (incl. overtime)  handicap=50<\/code><\/pre>\n<p>The consensus line is whichever handicap the most books quote. Here that is 49.5 on the total and -6.5 on the spread. Six books also quote 50 and eight quote 49, so a scanner that assumes one number per game will miss most of the ladder.<\/p>\n<p>Do not lean on the <code>mainLine<\/code> flag to pick for you. On this fixture every book that flagged the -6.5 spread <code>mainLine: true<\/code> had also suspended it, while the four books taking bets on that line carried <code>mainLine: false<\/code>.<\/p>\n<h2>Step 5: De-vig Pinnacle, then shop the board<\/h2>\n<p>Pinnacle&#8217;s price is the sharp reference. Strip its margin to get a fair probability, then check what the rest of the board is paying.<\/p>\n<pre class=\"wp-block-code\"><code>ml = live_lines(books, 141)\n\nhome, away = ml[\"pinnacle\"]\nih, ia = 1 \/ home, 1 \/ away\ntotal = ih + ia\n\nprint(f\"Pinnacle {home}\/{away}, margin {(total - 1) * 100:.2f}%\")\nprint(f\"  fair home {ih \/ total * 100:.1f}%  ({total \/ ih:.3f})\")\nprint(f\"  fair away {ia \/ total * 100:.1f}%  ({total \/ ia:.3f})\")\n\nbest_home = max(ml.items(), key=lambda kv: kv[1][0])\nbest_away = max(ml.items(), key=lambda kv: kv[1][1])\nprint(f\"  best home {best_home[1][0]} @ {best_home[0]}\")\nprint(f\"  best away {best_away[1][1]} @ {best_away[0]}\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>Pinnacle 1.347\/3.3, margin 4.54%\n  fair home 71.0%  (1.408)\n  fair away 29.0%  (3.450)\n  best home 1.408 @ kalshi\n  best away 3.448 @ kalshi<\/code><\/pre>\n<p>Look at those four numbers. Pinnacle&#8217;s de-vigged fair line is 1.408 \/ 3.450. Kalshi is quoting 1.408 \/ 3.448. The prediction market has landed on the sharp book&#8217;s no-vig number to three decimal places, and its own margin comes out at 0.03%.<\/p>\n<p>That is worth understanding rather than trading on. Kalshi carries a real cost structure and its stake limits on this game were $1,872 on TCU and $114 on North Carolina, so the dog side is a $114 market, not an edge. What you get for free is a de-vigged reference price you did not have to compute, on a fixture where Pinnacle may not have opened at all.<\/p>\n<p>Here is the full moneyline board, sorted by margin:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Bookmaker<\/th>\n<th>TCU<\/th>\n<th>North Carolina<\/th>\n<th>Margin<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>kalshi<\/td>\n<td>1.408<\/td>\n<td>3.448<\/td>\n<td>0.03%<\/td>\n<\/tr>\n<tr>\n<td>bet365<\/td>\n<td>1.357<\/td>\n<td>3.300<\/td>\n<td>3.99%<\/td>\n<\/tr>\n<tr>\n<td>fourwinds<\/td>\n<td>1.360<\/td>\n<td>3.250<\/td>\n<td>4.30%<\/td>\n<\/tr>\n<tr>\n<td>draftkings<\/td>\n<td>1.351<\/td>\n<td>3.300<\/td>\n<td>4.32%<\/td>\n<\/tr>\n<tr>\n<td>betmgm \/ borgata<\/td>\n<td>1.350<\/td>\n<td>3.300<\/td>\n<td>4.38%<\/td>\n<\/tr>\n<tr>\n<td>pinnacle<\/td>\n<td>1.347<\/td>\n<td>3.300<\/td>\n<td>4.54%<\/td>\n<\/tr>\n<tr>\n<td>caesars \/ williamhill<\/td>\n<td>1.345<\/td>\n<td>3.300<\/td>\n<td>4.65%<\/td>\n<\/tr>\n<tr>\n<td>ballybet \/ betparx<\/td>\n<td>1.380<\/td>\n<td>3.100<\/td>\n<td>4.72%<\/td>\n<\/tr>\n<tr>\n<td>betrivers<\/td>\n<td>1.380<\/td>\n<td>3.050<\/td>\n<td>5.25%<\/td>\n<\/tr>\n<tr>\n<td>hardrockbet<\/td>\n<td>1.333<\/td>\n<td>3.250<\/td>\n<td>5.79%<\/td>\n<\/tr>\n<tr>\n<td>sbobet<\/td>\n<td>1.350<\/td>\n<td>3.040<\/td>\n<td>6.97%<\/td>\n<\/tr>\n<tr>\n<td>pointsbet.com.au<\/td>\n<td>1.300<\/td>\n<td>3.200<\/td>\n<td>8.17%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>Fifteen slugs collapse to twelve distinct price tuples. Caesars and William Hill are identical, BetMGM and Borgata are identical, BallyBet and BetParx are identical. Dedupe on the price tuple before you average anything or your &#8220;consensus&#8221; quietly triple-weights one trading desk. For the same reason, treat a book count as a count of independent opinions, not of logos.<\/p>\n<p>One more thing the margin column shows: <strong>Pinnacle is not the tightest book on this game<\/strong>. Six books priced the college moneyline inside Pinnacle&#8217;s 4.54%. That inverts what you see on MLB or the Premier League, and it is a symptom of an early-season market rather than a soft-book mistake. The next section explains why.<\/p>\n<h2>Reading the limits: how to tell a real market from a placeholder<\/h2>\n<p>Pinnacle publishes a <code>limit<\/code> on every outcome, and the limit encodes a maximum win rather than a maximum stake. Back out the base with <code>limit * (price - 1)<\/code> for a favourite and you get the figure the trading desk stands behind.<\/p>\n<p>On TCU v North Carolina, Pinnacle&#8217;s limit was 720 on a 1.347 favourite. That works out to a base of 250. On Virginia v NC State, 543 at 1.460 gives the same 250. For comparison, Pinnacle was running bases of 1,875 to 7,500 on same-day MLB games this summer, and a Premier League opener two months out sat at 250 before doubling to 500 as the season approached.<\/p>\n<p>A base of 250 means the sharpest book on the planet will let you win $250 on this game. Three weeks out, on a college fixture, that is a placeholder line. It explains the wide margin, and it is the single most useful signal in the payload for deciding whether a number is worth modelling against.<\/p>\n<p>Free historical odds let you watch the number wake up:<\/p>\n<pre class=\"wp-block-code\"><code>r = requests.get(f\"{BASE_URL}\/historical-odds\",\n                 params={\"apiKey\": API_KEY, \"fixtureId\": FIXTURE,\n                         \"bookmakers\": \"pinnacle\"})\n\n# NOTE: on \/historical-odds the top key is \"bookmakers\" (not \"bookmakerOdds\")\n# and players[\"0\"] is a LIST of snapshots, not a single dict.\nsnaps = (r.json()[\"bookmakers\"][\"pinnacle\"][\"markets\"][\"141\"]\n          [\"outcomes\"][\"141\"][\"players\"][\"0\"])\n\nfor s in snaps:\n    print(s[\"createdAt\"][:19], s[\"price\"], \"limit\", s[\"limit\"])<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>2026-07-30T10:14:30 1.344 limit 726\n...\n2026-08-04T16:29:20 1.347 limit 720<\/code><\/pre>\n<p>Pinnacle opened this game on July 30, a full month before kickoff, and moved it once in six days. Against a Premier League fixture that repriced thousands of times over a comparable window, the college board is asleep. Poll it daily rather than every thirty seconds, and spend your request budget on the games that are moving.<\/p>\n<h2>How the board fills in: the NFL preseason control<\/h2>\n<p>To check whether the suspended-price pattern is a college quirk or a time-to-kickoff effect, we ran the same census on NFL Preseason fixtures the same afternoon:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Fixture<\/th>\n<th>Days out<\/th>\n<th>Books<\/th>\n<th>Prices<\/th>\n<th>% live<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Arizona v Carolina<\/td>\n<td>2<\/td>\n<td>16<\/td>\n<td>906<\/td>\n<td>66.0%<\/td>\n<\/tr>\n<tr>\n<td>Cincinnati v Detroit<\/td>\n<td>8<\/td>\n<td>2<\/td>\n<td>4<\/td>\n<td>100.0%<\/td>\n<\/tr>\n<tr>\n<td>Houston v LA Chargers<\/td>\n<td>9<\/td>\n<td>2<\/td>\n<td>4<\/td>\n<td>100.0%<\/td>\n<\/tr>\n<tr>\n<td>NCAA Week 1 (8 fixtures)<\/td>\n<td>24<\/td>\n<td>13 to 16<\/td>\n<td>1,649<\/td>\n<td>41.9%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>The two books quoting those distant preseason games are Kalshi and Polymarket. No sportsbook had opened them at all. Prediction markets price first, sportsbooks arrive later with a deep menu that is mostly suspended, and the menu goes live as kickoff approaches. If you are building a college football scanner, that ordering tells you where to point it in August versus October.<\/p>\n<h2>What college football does not have<\/h2>\n<p>Three honest gaps, so you do not build against something that is not there.<\/p>\n<p><strong>No player props.<\/strong> Across all eight Week 1 fixtures and 112 distinct market IDs, we found zero player markets. No passing yards, no anytime touchdown, nothing keyed by player. The NFL catalogue carries Player To Score TD (14388) and First TD (14390), and US retail books do price them, but college prop menus had not opened. Re-probe in September before promising a prop feed.<\/p>\n<p><strong>No outrights.<\/strong> The American football catalogue has no futures markets beyond a coin toss, so national championship, conference and Heisman odds are out of reach. <code>\/fixtures<\/code> is strictly two-participant.<\/p>\n<p><strong>No scores.<\/strong> The feed carries schedules, status and odds. If you need results to grade a model, join out via the <code>externalProviders<\/code> block on each fixture, which ships Betradar, OpticOdds and Pinnacle IDs.<\/p>\n<h2>A working college football scanner<\/h2>\n<p>Everything above, wired into one loop over the slate. It respects the per-endpoint rate limit with a one-second gap and skips anything without a live two-sided market.<\/p>\n<pre class=\"wp-block-code\"><code>import requests, time\nfrom collections import Counter\n\nAPI_KEY  = \"YOUR_API_KEY\"\nBASE_URL = \"https:\/\/api.oddspapi.io\/v4\"\nNCAA     = 27653\n\ndef live_lines(books, market_id):\n    out = {}\n    for slug, book in books.items():\n        market = book[\"markets\"].get(str(market_id))\n        if not market:\n            continue\n        ids = sorted(int(o) for o in market[\"outcomes\"])\n        if len(ids) != 2:\n            continue\n        a, b = (market[\"outcomes\"][str(i)][\"players\"][\"0\"] for i in ids)\n        if a[\"active\"] and b[\"active\"]:\n            out[slug] = (a[\"price\"], b[\"price\"])\n    return out\n\ndef devig(price_a, price_b):\n    ia, ib = 1 \/ price_a, 1 \/ price_b\n    total = ia + ib\n    return ia \/ total, ib \/ total, total - 1\n\nfixtures = requests.get(f\"{BASE_URL}\/fixtures\", params={\n    \"apiKey\": API_KEY, \"sportId\": 14,\n    \"from\": \"2026-08-22\", \"to\": \"2026-08-31\"}).json()\n\nfor f in [x for x in fixtures if x[\"tournamentId\"] == NCAA and x[\"hasOdds\"]]:\n    time.sleep(1.0)   # per-endpoint cooldown, honour retryMs on a 429\n    resp = requests.get(f\"{BASE_URL}\/odds\", params={\n        \"apiKey\": API_KEY, \"fixtureId\": f[\"fixtureId\"]})\n    if resp.status_code != 200:      # a 429 body is valid JSON, check this first\n        print(\"rate limited, backing off\"); time.sleep(2); continue\n\n    books = resp.json().get(\"bookmakerOdds\", {})\n    ml = live_lines(books, 141)\n    if len(ml) &lt; 3:\n        continue\n\n    name = f\"{f['participant1Name']} v {f['participant2Name']}\"\n    best_a = max(ml.items(), key=lambda kv: kv[1][0])\n    best_b = max(ml.items(), key=lambda kv: kv[1][1])\n\n    line = f\"{name:&lt;52} {len(ml):&gt;2} books\"\n    if \"pinnacle\" in ml:\n        pa, pb, margin = devig(*ml[\"pinnacle\"])\n        line += f\"  | sharp {pa:.1%}\/{pb:.1%} (vig {margin:.2%})\"\n    else:\n        line += \"  | no Pinnacle line\"\n    print(line)\n    print(f\"    best: {best_a[1][0]} @ {best_a[0]}  \/  \"\n          f\"{best_b[1][1]} @ {best_b[0]}\")<\/code><\/pre>\n<p>Swap 141 for the handicap or total ID the most books quote and the same loop shops spreads and totals. Point it at <code>tournamentId<\/code> 31 and it covers the NFL without another line changing.<\/p>\n<h2>Where to go next<\/h2>\n<p>The parsing patterns here carry across the rest of the feed. For the pro game, the <a href=\"https:\/\/oddspapi.io\/blog\/free-nfl-odds-api-guide\/\">NFL Odds API guide<\/a> covers the same endpoints with a fuller prop tree, and <a href=\"https:\/\/oddspapi.io\/blog\/nfl-key-numbers-half-point-cost\/\">NFL key numbers<\/a> puts a price on the half point once you have spreads flowing. To turn the board into a best-price table across every book, see <a href=\"https:\/\/oddspapi.io\/blog\/line-shopping-python-best-odds\/\">line shopping in Python<\/a>. The <code>limit<\/code> field gets a full treatment in <a href=\"https:\/\/oddspapi.io\/blog\/betting-limits-api-stake-sizing\/\">betting limits and stake sizing<\/a>, and if you want the three-way comparison of de-vig methods used above, read <a href=\"https:\/\/oddspapi.io\/blog\/no-vig-odds-api\/\">no-vig odds<\/a>. New to the API, start with the <a href=\"https:\/\/oddspapi.io\/blog\/free-odds-api-350-bookmakers\/\">free odds API overview<\/a>.<\/p>\n<h2>FAQ<\/h2>\n<h3>Is there a free college football odds API?<\/h3>\n<p>Yes. OddsPapi&#8217;s free tier covers NCAA football through the same <code>\/v4\/odds<\/code> endpoint as every other sport, including Pinnacle, SBOBet, Circa, Kalshi and the US retail books, plus historical price snapshots at no cost. Authentication is an <code>apiKey<\/code> query parameter.<\/p>\n<h3>Why does my college football odds request return no prices?<\/h3>\n<p>Two likely causes. The fixture&#8217;s <code>hasOdds<\/code> field is false, in which case <code>\/odds<\/code> returns metadata only. Or your parser filters on <code>active == True<\/code> and the books have posted their lines suspended, which accounted for 58% of quoted prices on the Week 1 board we sampled in August 2026.<\/p>\n<h3>What is the market ID for a college football spread?<\/h3>\n<p>Each line has its own ID. Spread -6.5 is 14260, spread -7 is 14258, total 49.5 is 1484, total 49 is 1482. Read the IDs off a live <code>\/odds<\/code> payload, count how many books quote each, and use the one with the widest coverage rather than hardcoding a value.<\/p>\n<h3>Does the API cover college football player props?<\/h3>\n<p>Not on the Week 1 board sampled in August 2026. All 112 market IDs across eight fixtures were game lines: moneyline, spreads, totals, team totals and odd\/even. NFL player props are in the catalogue as markets 14388 and 14390, so re-probe college fixtures closer to the season.<\/p>\n<h3>Can I get college football futures or national championship odds?<\/h3>\n<p>No. The American football catalogue carries no outright markets beyond a coin toss, and <code>\/fixtures<\/code> only returns two-participant events. Championship, conference and award odds are out of scope.<\/p>\n<h3>How often should I poll college football odds?<\/h3>\n<p>Daily is enough three weeks out. Pinnacle opened TCU v North Carolina on July 30 and changed the price once in the following six days. Tighten the cadence in game week, and use the <code>limit<\/code> field to tell which games the sharp books have started taking real money on.<\/p>\n<p><script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [\n    {\"@type\":\"Question\",\"name\":\"Is there a free college football odds API?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes. OddsPapi's free tier covers NCAA football through the same \/v4\/odds endpoint as every other sport, including Pinnacle, SBOBet, Circa, Kalshi and the US retail books, plus historical price snapshots at no cost. Authentication is an apiKey query parameter.\"}},\n    {\"@type\":\"Question\",\"name\":\"Why does my college football odds request return no prices?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Two likely causes. The fixture's hasOdds field is false, in which case \/odds returns metadata only. Or your parser filters on active == True and the books have posted their lines suspended, which accounted for 58% of quoted prices on the Week 1 board sampled in August 2026.\"}},\n    {\"@type\":\"Question\",\"name\":\"What is the market ID for a college football spread?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Each line has its own ID. Spread -6.5 is 14260, spread -7 is 14258, total 49.5 is 1484, total 49 is 1482. Read the IDs off a live \/odds payload, count how many books quote each, and use the one with the widest coverage rather than hardcoding a value.\"}},\n    {\"@type\":\"Question\",\"name\":\"Does the API cover college football player props?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Not on the Week 1 board sampled in August 2026. All 112 market IDs across eight fixtures were game lines: moneyline, spreads, totals, team totals and odd\/even. NFL player props are in the catalogue as markets 14388 and 14390, so re-probe college fixtures closer to the season.\"}},\n    {\"@type\":\"Question\",\"name\":\"Can I get college football futures or national championship odds?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"No. The American football catalogue carries no outright markets beyond a coin toss, and \/fixtures only returns two-participant events. Championship, conference and award odds are out of scope.\"}},\n    {\"@type\":\"Question\",\"name\":\"How often should I poll college football odds?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Daily is enough three weeks out. Pinnacle opened TCU v North Carolina on July 30 and changed the price once in the following six days. Tighten the cadence in game week, and use the limit field to tell which games the sharp books have started taking real money on.\"}}\n  ]\n}\n<\/script><\/p>\n<h2>Get the feed<\/h2>\n<p>Week 0 kicks off on August 22. The board is thin now and it will not stay that way, so wire up the parser while the games are cheap to poll. A free key gives you every college fixture in the catalogue, 349 bookmakers across 69 sports, and historical snapshots from the day each book opened its line.<\/p>\n<p><strong><a href=\"https:\/\/oddspapi.io\/\">Grab a free API key<\/a> and stop guessing which prices are real.<\/strong><\/p>\n<p><!--\nFocus Keyphrase: college football odds api\nSEO Title: College Football Odds API: Live NCAAF Lines, Spreads & Totals (Python)\nMeta Description: Pull live NCAAF lines, spreads and totals in Python. College football odds API with Pinnacle, Kalshi and 14 more books on a free tier.\nSlug: college-football-odds-api\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pull live NCAAF lines, spreads and totals in Python. College football odds API with Pinnacle, Kalshi and 14 more books on a free tier.<\/p>\n","protected":false},"author":2,"featured_media":3187,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[81,8,9,11,10],"class_list":["post-3186","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to-guides","tag-college-football","tag-free-api","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>College Football Odds API: NCAAF Lines, Spreads and Totals | 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\/college-football-odds-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"College Football Odds API: NCAAF Lines, Spreads and Totals | OddsPapi Blog\" \/>\n<meta property=\"og:description\" content=\"Pull live NCAAF lines, spreads and totals in Python. College football odds API with Pinnacle, Kalshi and 14 more books on a free tier.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/\" \/>\n<meta property=\"og:site_name\" content=\"OddsPapi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-14T10:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-29T14:57:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1429\" \/>\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=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/\"},\"author\":{\"name\":\"Odds API Writer\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\"},\"headline\":\"College Football Odds API: NCAAF Lines, Spreads and Totals\",\"datePublished\":\"2026-08-14T10:00:00+00:00\",\"dateModified\":\"2026-08-29T14:57:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/\"},\"wordCount\":2368,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp\",\"keywords\":[\"College Football\",\"Free API\",\"Odds API\",\"Python\",\"Sports Betting API\"],\"articleSection\":[\"How To Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/\",\"name\":\"College Football Odds API: NCAAF Lines, Spreads and Totals | OddsPapi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp\",\"datePublished\":\"2026-08-14T10:00:00+00:00\",\"dateModified\":\"2026-08-29T14:57:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp\",\"width\":2560,\"height\":1429,\"caption\":\"College Football Odds API - OddsPapi API Blog\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oddspapi.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"College Football Odds API: NCAAF Lines, Spreads and Totals\"}]},{\"@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":"College Football Odds API: NCAAF Lines, Spreads and Totals | 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\/college-football-odds-api\/","og_locale":"en_US","og_type":"article","og_title":"College Football Odds API: NCAAF Lines, Spreads and Totals | OddsPapi Blog","og_description":"Pull live NCAAF lines, spreads and totals in Python. College football odds API with Pinnacle, Kalshi and 14 more books on a free tier.","og_url":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/","og_site_name":"OddsPapi Blog","article_published_time":"2026-08-14T10:00:00+00:00","article_modified_time":"2026-08-29T14:57:45+00:00","og_image":[{"width":2560,"height":1429,"url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.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":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#article","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/"},"author":{"name":"Odds API Writer","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13"},"headline":"College Football Odds API: NCAAF Lines, Spreads and Totals","datePublished":"2026-08-14T10:00:00+00:00","dateModified":"2026-08-29T14:57:45+00:00","mainEntityOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/"},"wordCount":2368,"commentCount":3,"publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp","keywords":["College Football","Free API","Odds API","Python","Sports Betting API"],"articleSection":["How To Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/","url":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/","name":"College Football Odds API: NCAAF Lines, Spreads and Totals | OddsPapi Blog","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp","datePublished":"2026-08-14T10:00:00+00:00","dateModified":"2026-08-29T14:57:45+00:00","breadcrumb":{"@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oddspapi.io\/blog\/college-football-odds-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#primaryimage","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/08\/college-football-odds-api-scaled.webp","width":2560,"height":1429,"caption":"College Football Odds API - OddsPapi API Blog"},{"@type":"BreadcrumbList","@id":"https:\/\/oddspapi.io\/blog\/college-football-odds-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oddspapi.io\/blog\/"},{"@type":"ListItem","position":2,"name":"College Football Odds API: NCAAF Lines, Spreads and Totals"}]},{"@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\/3186","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=3186"}],"version-history":[{"count":2,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/3186\/revisions"}],"predecessor-version":[{"id":3799,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/3186\/revisions\/3799"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media\/3187"}],"wp:attachment":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media?parent=3186"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/categories?post=3186"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/tags?post=3186"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}