{"id":2877,"date":"2026-05-12T10:00:00","date_gmt":"2026-05-12T10:00:00","guid":{"rendered":"https:\/\/oddspapi.io\/blog\/?p=2877"},"modified":"2026-04-12T14:58:03","modified_gmt":"2026-04-12T14:58:03","slug":"player-props-api-nfl-nba-mlb-odds-python","status":"publish","type":"post","link":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/","title":{"rendered":"Player Props API: How to Get NFL, NBA &#038; MLB Prop Odds in Python"},"content":{"rendered":"<h2>Every Player Props API Gives You 40 Bookmakers. Here Are 350+.<\/h2>\n<p>You need player prop odds for your model, your scanner, or your +EV tool. You go to The Odds API \u2014 40 bookmakers. You try SportsGameOdds \u2014 85 books, but the free tier gives you 9 with a 10-minute delay. Neither has Singbet or SBOBet. Neither shows you what the JSON actually looks like.<\/p>\n<p>SportsGameOdds has written <strong>four blog posts<\/strong> about player props. Not one of them includes a JSON response structure or a working code example. The Odds API&#8217;s player props post is 800 words of marketing copy.<\/p>\n<p>This post is different. You&#8217;ll get:<\/p>\n<ul>\n<li>Working Python code that fetches real player prop odds from <strong>350+ bookmakers<\/strong><\/li>\n<li>The actual JSON structure \u2014 so you can parse it without guessing<\/li>\n<li>Native combo props (PRA, Double-Double, Triple-Double) as first-class markets<\/li>\n<li>Cross-bookmaker line shopping for props<\/li>\n<li>Free historical prop odds for backtesting your models<\/li>\n<\/ul>\n<p>Let&#8217;s build.<\/p>\n<h2>Player Props: Old Way vs OddsPapi<\/h2>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Feature<\/th>\n<th>Scraping<\/th>\n<th>The Odds API<\/th>\n<th>SportsGameOdds<\/th>\n<th>OddsPapi<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Bookmakers with Props<\/strong><\/td>\n<td>1-2 sites<\/td>\n<td>~15<\/td>\n<td>~85 (9 on free)<\/td>\n<td><strong>350+<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>Sharp Books (Pinnacle, Singbet)<\/strong><\/td>\n<td>&#10060;<\/td>\n<td>&#10060;<\/td>\n<td>Pinnacle only<\/td>\n<td><strong>All three (+ SBOBet)<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>Combo Props (PRA, Double-Double)<\/strong><\/td>\n<td>Manual scrape<\/td>\n<td>Limited<\/td>\n<td>Generic<\/td>\n<td><strong>Native market IDs<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>JSON Response Shown in Docs<\/strong><\/td>\n<td>N\/A<\/td>\n<td>&#10060;<\/td>\n<td>&#10060;<\/td>\n<td><strong>&#9989; (this post)<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>Historical Prop Odds<\/strong><\/td>\n<td>&#10060;<\/td>\n<td>Paid add-on<\/td>\n<td>Pro tier ($299+\/mo)<\/td>\n<td><strong>Free tier<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>Authentication<\/strong><\/td>\n<td>N\/A<\/td>\n<td>Header token<\/td>\n<td>Header token<\/td>\n<td><strong>Query param<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>Free Tier Latency<\/strong><\/td>\n<td>N\/A<\/td>\n<td>~60s delay<\/td>\n<td>10-min delay<\/td>\n<td><strong>Real-time<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>What Are Player Props in API Terms?<\/h2>\n<p>Player props are markets tied to <strong>individual player performance<\/strong>, not the game outcome. Points scored, rebounds grabbed, passing yards thrown, strikeouts pitched. In OddsPapi&#8217;s data model, player props work like team markets with two key differences:<\/p>\n<ol>\n<li>The <code>playerName<\/code> field in the outcome is <strong>non-null<\/strong> (e.g., &#8220;Cunningham, Cade&#8221;)<\/li>\n<li>The <code>players<\/code> dict uses <strong>player IDs as keys<\/strong> (e.g., <code>\"2068637\"<\/code>) \u2014 not <code>\"0\"<\/code> like team markets<\/li>\n<\/ol>\n<p>Here&#8217;s what&#8217;s available per sport:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Sport<\/th>\n<th>Market Types<\/th>\n<th>Example Props<\/th>\n<th>Market IDs in Catalog<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>NBA<\/strong><\/td>\n<td>29<\/td>\n<td>Points, Rebounds, Assists, PRA, 3-Pointers, Steals, Blocks, Double-Double, Triple-Double<\/td>\n<td>439<\/td>\n<\/tr>\n<tr>\n<td><strong>NFL<\/strong><\/td>\n<td>32<\/td>\n<td>Pass Yards, Rush Yards, Receiving Yards, TDs (Anytime, First, 2nd, 3rd), Pass Completions, Tackles<\/td>\n<td>1,243<\/td>\n<\/tr>\n<tr>\n<td><strong>MLB<\/strong><\/td>\n<td>30<\/td>\n<td>Strikeouts, Hits, Runs, RBIs, Total Bases, Home Runs, Stolen Bases, Walks, Outs<\/td>\n<td>122<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>That is not a typo. A single NFL fixture can have <strong>1,243 player prop market IDs<\/strong> across 32 market types \u2014 each handicap line (Over 249.5 yards, Over 250.5 yards) gets its own unique market ID.<\/p>\n<h2>Tutorial: Fetching Player Prop Odds with Python<\/h2>\n<h3>Step 1 \u2014 Authentication<\/h3>\n<p>Install <code>requests<\/code> if you haven&#8217;t, then verify your connection:<\/p>\n<pre class=\"wp-block-code\"><code>\nimport requests\nimport time\n\nAPI_KEY = \"YOUR_API_KEY\"\nBASE_URL = \"https:\/\/api.oddspapi.io\/v4\"\n\ndef api_get(endpoint, **params):\n    params[\"apiKey\"] = API_KEY\n    resp = requests.get(f\"{BASE_URL}\/{endpoint}\", params=params)\n    resp.raise_for_status()\n    return resp.json()\n\n# Verify connection\nsports = api_get(\"sports\")\nprint(f\"Connected \u2014 {len(sports)} sports available\")\n<\/code><\/pre>\n<p><strong>Important:<\/strong> <code>apiKey<\/code> is a <strong>query parameter<\/strong>, not a header. This trips up developers migrating from other APIs. <a href=\"https:\/\/oddspapi.io\/en\/docs\/api\" target=\"_blank\">Full API docs here<\/a>.<\/p>\n<h3>Step 2 \u2014 Discovering Player Prop Markets<\/h3>\n<p>Before you can fetch prop odds, you need to know the market IDs. The <code>\/markets<\/code> endpoint gives you the full catalog for any sport:<\/p>\n<pre class=\"wp-block-code\"><code>\n# Fetch the NBA market catalog\ncatalog = api_get(\"markets\", sportId=11)\n\n# Filter for player prop markets\nprop_keywords = [\"Player\", \"First Basket\", \"Double\", \"Triple\"]\nprop_markets = [\n    m for m in catalog\n    if any(kw in m[\"marketName\"] for kw in prop_keywords)\n]\n\n# Build lookup dicts\nmarket_names = {m[\"marketId\"]: m[\"marketName\"] for m in catalog}\noutcome_names = {\n    (m[\"marketId\"], o[\"outcomeId\"]): o[\"outcomeName\"]\n    for m in catalog for o in m.get(\"outcomes\", [])\n}\n\n# Show unique prop types\nprop_types = sorted(set(m[\"marketName\"] for m in prop_markets))\nprint(f\"{len(prop_types)} player prop types in NBA:\")\nfor name in prop_types[:10]:\n    example = next(m for m in prop_markets if m[\"marketName\"] == name)\n    print(f\"  {name} (e.g. ID {example['marketId']}, line {example.get('handicap', 0)})\")\n<\/code><\/pre>\n<p>Each handicap line has its own <code>marketId<\/code>. &#8220;Over Under Player Points&#8221; at line 17.5 and at line 19.5 are <strong>different market IDs<\/strong>. The <code>handicap<\/code> field tells you the line. Don&#8217;t hardcode market IDs \u2014 build lookups from the catalog.<\/p>\n<h3>Step 3 \u2014 Fetching Prop Odds for a Fixture<\/h3>\n<p>Find an NBA game and pull live prop odds from multiple bookmakers:<\/p>\n<pre class=\"wp-block-code\"><code>\n# Find NBA fixtures with odds\nfixtures = api_get(\"fixtures\", sportId=11, **{\n    \"from\": \"2026-04-12\",\n    \"to\": \"2026-04-15\"\n})\nnba_with_odds = [\n    f for f in fixtures\n    if f.get(\"hasOdds\") and \"nba\" in f.get(\"tournamentSlug\", \"\").lower()\n]\nprint(f\"NBA fixtures with odds: {len(nba_with_odds)}\")\n\n# Pick the first fixture\nfixture = nba_with_odds[0]\nfid = fixture[\"fixtureId\"]\nprint(f\"{fixture['participant1Name']} vs {fixture['participant2Name']}\")\n\ntime.sleep(0.2)  # Rate limit safety\n\n# Fetch odds from multiple bookmakers\nodds = api_get(\"odds\", fixtureId=fid,\n               bookmakers=\"hardrockbet,fanduel,thescore,betrivers,caesars,pinnacle\")\n\n# Check which bookmakers responded\nbk_odds = odds.get(\"bookmakerOdds\", {})\nprint(f\"Bookmakers in response: {list(bk_odds.keys())}\")\n<\/code><\/pre>\n<div style=\"background:#1a1a2e;border-left:4px solid #f97316;padding:16px 20px;margin:24px 0;border-radius:4px;\"><strong>&#9888;&#65039; Not all bookmakers carry player props.<\/strong> In our testing, <strong>Hard Rock Bet<\/strong>, <strong>FanDuel<\/strong>, <strong>theScore<\/strong>, and <strong>BetRivers<\/strong> consistently return NBA player props. Pinnacle doesn&#8217;t offer as many player prop markets as US soft books \u2014 but when Pinnacle does price a prop, that line is the sharpest benchmark you have. Only fixtures with <code>hasOdds: true<\/code> will return odds.<\/div>\n<h3>Step 4 \u2014 Parsing Props into a Clean Table<\/h3>\n<p>Here&#8217;s the key: for player props, the <code>players<\/code> dict uses <strong>player IDs as keys<\/strong> (not <code>\"0\"<\/code>), and <code>playerName<\/code> is populated. Here&#8217;s what a player prop outcome looks like in the raw JSON:<\/p>\n<pre class=\"wp-block-code\"><code>\n# Raw JSON structure for a player prop outcome:\n# response[\"bookmakerOdds\"][\"hardrockbet\"][\"markets\"][\"111678\"][\"outcomes\"][\"111678\"][\"players\"]\n# {\n#     \"2068637\": {\n#         \"active\": true,\n#         \"betslip\": \"https:\/\/app.hardrock.bet\/?deep_link_value=betslip\/...\",\n#         \"bookmakerOutcomeId\": \"5383800863007572306\",\n#         \"changedAt\": \"2026-04-12T10:08:45.327607+00:00\",\n#         \"limit\": null,\n#         \"playerName\": \"Cunningham, Cade\",\n#         \"price\": 1.625,\n#         \"exchangeMeta\": {}\n#     }\n# }\n<\/code><\/pre>\n<p>Now let&#8217;s parse all player props across every bookmaker into a clean table:<\/p>\n<pre class=\"wp-block-code\"><code>\n# Parse all player props from the odds response\nprops = []\nfor bk_slug, bk_data in bk_odds.items():\n    for mid_str, mdata in bk_data.get(\"markets\", {}).items():\n        mid = int(mid_str)\n        mname = market_names.get(mid, \"Unknown\")\n\n        for oid_str, odata in mdata.get(\"outcomes\", {}).items():\n            oid = int(oid_str)\n            oname = outcome_names.get((mid, oid), oid_str)\n\n            for player_id, pdata in odata.get(\"players\", {}).items():\n                if not isinstance(pdata, dict):\n                    continue\n                if not pdata.get(\"playerName\"):\n                    continue  # Skip team-level markets\n\n                props.append({\n                    \"player\": pdata[\"playerName\"],\n                    \"market\": mname,\n                    \"line\": next(\n                        (m[\"handicap\"] for m in catalog if m[\"marketId\"] == mid),\n                        0\n                    ),\n                    \"outcome\": oname,\n                    \"price\": pdata[\"price\"],\n                    \"book\": bk_slug,\n                    \"active\": pdata.get(\"active\", True),\n                })\n\nprint(f\"\\nFound {len(props)} player prop entries\")\nprint(f\"Players: {len(set(p['player'] for p in props))}\")\nprint(f\"Bookmakers: {sorted(set(p['book'] for p in props))}\")\nprint(f\"Prop types: {len(set(p['market'] for p in props))}\")\n\n# Print a sample\nprint(f\"\\n{'Player':<22} {'Market':<30} {'Line':>6} {'Side':<8} {'Price':>6} {'Book'}\")\nprint(\"-\" * 100)\nfor p in sorted(props, key=lambda x: (x[\"player\"], x[\"market\"]))[:15]:\n    print(f\"{p['player']:<22} {p['market']:<30} {p['line']:>6} {p['outcome']:<8} {p['price']:>6} {p['book']}\")\n<\/code><\/pre>\n<h3>Step 5 \u2014 Line Shopping Across Bookmakers<\/h3>\n<p>The real value of 350+ bookmakers: <strong>price divergence<\/strong>. The same player prop at different books means different edges. Here&#8217;s how to find the best price for any prop:<\/p>\n<pre class=\"wp-block-code\"><code>\n# Group props by player + market + line + outcome for cross-book comparison\nfrom collections import defaultdict\n\ncomparisons = defaultdict(list)\nfor p in props:\n    key = (p[\"player\"], p[\"market\"], p[\"line\"], p[\"outcome\"])\n    comparisons[key].append((p[\"book\"], p[\"price\"]))\n\n# Show props available at 2+ bookmakers (line shopping opportunities)\nprint(\"=== Line Shopping Opportunities ===\\n\")\nfor (player, market, line, outcome), books in sorted(comparisons.items()):\n    if len(books) < 2:\n        continue\n    books_sorted = sorted(books, key=lambda x: -x[1])  # Best price first\n    best_book, best_price = books_sorted[0]\n    worst_book, worst_price = books_sorted[-1]\n    edge = ((best_price - worst_price) \/ worst_price) * 100\n\n    print(f\"{player} \u2014 {market} ({line}) {outcome}\")\n    for book, price in books_sorted:\n        marker = \" \u2190 BEST\" if book == best_book else \"\"\n        print(f\"  {book:<16} {price:.3f}{marker}\")\n    print(f\"  Edge: {edge:.1f}%\\n\")\n<\/code><\/pre>\n<p>When you're pulling from 4+ bookmakers, you'll regularly find 5-10% price differences on the same player prop. That's the difference between a losing model and a profitable one. For a deeper dive into building automated scanners, see our <a href=\"\/blog\/arbitrage-betting-bot-python\/\">arbitrage betting bot tutorial<\/a> and <a href=\"\/blog\/value-betting-scanner-python\/\">value betting scanner guide<\/a>.<\/p>\n<h2>Combo Props: PRA, Double-Double, Triple-Double<\/h2>\n<p>Most APIs either don't support combo props or force you to reconstruct them from individual lines. OddsPapi handles them as <strong>native markets<\/strong> with their own market IDs \u2014 because that's how bookmakers actually price them.<\/p>\n<pre class=\"wp-block-code\"><code>\n# Filter the catalog for combo prop markets\ncombo_keywords = [\"Points + Assists + Rebounds\", \"Points + Assists\",\n                  \"Points + Rebounds\", \"Assists + Rebounds\",\n                  \"Steals + Blocks\", \"Double\", \"Triple\"]\n\ncombo_markets = [\n    m for m in prop_markets\n    if any(kw in m[\"marketName\"] for kw in combo_keywords)\n]\n\ncombo_types = sorted(set(m[\"marketName\"] for m in combo_markets))\nprint(f\"Combo prop types available ({len(combo_types)}):\")\nfor name in combo_types:\n    lines = [m[\"handicap\"] for m in combo_markets if m[\"marketName\"] == name]\n    print(f\"  {name} ({len(lines)} lines: {min(lines)}-{max(lines)})\")\n\n# Show combo props from our live odds\ncombo_props = [p for p in props if any(kw in p[\"market\"] for kw in combo_keywords)]\nprint(f\"\\nLive combo props found: {len(combo_props)}\")\nfor p in combo_props:\n    print(f\"  {p['player']} \u2014 {p['market']} ({p['line']}) {p['outcome']}: {p['price']} @ {p['book']}\")\n<\/code><\/pre>\n<p><strong>Points + Assists + Rebounds<\/strong> (PRA) is a single market with a single line \u2014 not three separate bets multiplied together. <strong>Double-Double<\/strong> and <strong>Triple-Double<\/strong> are binary yes\/no markets. None of the competitor blog posts even mention combo props exist.<\/p>\n<h2>Historical Player Prop Odds<\/h2>\n<p>The <code>\/historical-odds<\/code> endpoint works for player prop markets too. You can pull the full price history for any prop \u2014 see how the line moved from open to close, and backtest your models against closing prices.<\/p>\n<pre class=\"wp-block-code\"><code>\n# Fetch historical odds for a fixture (max 3 bookmakers per call)\nhistorical = api_get(\"historical-odds\",\n                     fixtureId=fid,\n                     bookmakers=\"hardrockbet,fanduel,thescore\")\n\n# The historical endpoint uses \"bookmakers\" (not \"bookmakerOdds\")\n# and players[\"0\"] is a LIST of snapshots, not a dict\nfor bk_slug, bk_data in historical.get(\"bookmakers\", {}).items():\n    for mid_str, mdata in bk_data.get(\"markets\", {}).items():\n        mid = int(mid_str)\n        mname = market_names.get(mid, \"Unknown\")\n        if \"Player\" not in mname:\n            continue\n\n        for oid_str, odata in mdata.get(\"outcomes\", {}).items():\n            for player_id, snapshots in odata.get(\"players\", {}).items():\n                if not isinstance(snapshots, list) or not snapshots:\n                    continue\n                # Each snapshot has: price, createdAt, limit, active, exchangeMeta\n                player_name = snapshots[0].get(\"playerName\", player_id)\n                print(f\"\\n{player_name} \u2014 {mname} @ {bk_slug}\")\n                print(f\"  {len(snapshots)} price snapshots:\")\n                for snap in snapshots[:5]:\n                    print(f\"    {snap['createdAt'][:19]} \u2192 {snap['price']}\")\n<\/code><\/pre>\n<p>Competitors charge $79-299+\/month for historical data. OddsPapi includes it on the <strong>free tier<\/strong>. Backtest your player prop model against Pinnacle closing lines without paying a cent. For a full backtesting workflow, see our <a href=\"\/blog\/backtest-betting-model-free-historical-odds\/\">historical odds backtesting tutorial<\/a>.<\/p>\n<h2>Which Bookmakers Actually Carry Props?<\/h2>\n<p>Let's be honest: not all 350+ bookmakers offer player props. Prop coverage varies by sport, fixture, and timing. Here's what we've found in practice:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Bookmaker<\/th>\n<th>NBA Props<\/th>\n<th>Prop Types<\/th>\n<th>Notes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Hard Rock Bet<\/strong><\/td>\n<td>&#9989; Deep<\/td>\n<td>Points, Rebounds, Assists, PRA, 3PT, Steals, Blocks, Combos, First Point<\/td>\n<td>Deepest prop coverage in testing<\/td>\n<\/tr>\n<tr>\n<td><strong>FanDuel<\/strong><\/td>\n<td>&#9989; Strong<\/td>\n<td>Points, Rebounds, Assists, 3PT, Double-Double, Triple-Double (alt lines: 10+, 15+, 20+...)<\/td>\n<td>Best for alt\/milestone lines<\/td>\n<\/tr>\n<tr>\n<td><strong>theScore<\/strong><\/td>\n<td>&#9989; Good<\/td>\n<td>Points, Rebounds, Assists, 3PT (O\/U with multiple lines)<\/td>\n<td>Wide line spread per stat<\/td>\n<\/tr>\n<tr>\n<td><strong>BetRivers<\/strong><\/td>\n<td>&#9989; Moderate<\/td>\n<td>Points, Rebounds, Assists, 3PT, PRA (milestone format)<\/td>\n<td>Solid for milestone props<\/td>\n<\/tr>\n<tr>\n<td><strong>Caesars<\/strong><\/td>\n<td>&#9989; Moderate<\/td>\n<td>Points, Rebounds, Assists, spreads<\/td>\n<td>Prop coverage varies by game<\/td>\n<\/tr>\n<tr>\n<td><strong>Pinnacle<\/strong><\/td>\n<td>&#10071; Limited<\/td>\n<td>Mainline markets primarily<\/td>\n<td>When Pinnacle prices a prop, it's the sharpest line available<\/td>\n<\/tr>\n<tr>\n<td><strong>DraftKings<\/strong><\/td>\n<td>&#10071; Limited<\/td>\n<td>Mainline markets primarily<\/td>\n<td>Props may appear closer to game time<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p><strong>NFL props<\/strong> are the richest during the season \u2014 we've verified Anytime TD, First TD, and stat props from FanDuel, Caesars, and Hard Rock Bet during live games. <strong>MLB props<\/strong> (strikeouts, hits, runs) are available but thinner. Check our <a href=\"\/blog\/nba-odds-api-player-props-spreads\/\">NBA Odds API<\/a>, <a href=\"\/blog\/free-nfl-odds-api-guide\/\">NFL Odds API<\/a>, and <a href=\"\/blog\/mlb-odds-api-run-lines-totals\/\">MLB Odds API<\/a> guides for sport-specific deep dives.<\/p>\n<p>The takeaway: use soft books (FanDuel, Hard Rock, BetRivers) for prop <strong>coverage<\/strong>, and sharp books (Pinnacle) for prop <strong>pricing benchmarks<\/strong>. That's the combo that makes 350+ bookmakers worth it.<\/p>\n<h2>Frequently Asked Questions<\/h2>\n<h3>What is a player props API?<\/h3>\n<p>A player props API delivers real-time odds for individual player performance markets \u2014 points scored, yards thrown, strikeouts pitched \u2014 from multiple bookmakers via a single endpoint. Instead of scraping each sportsbook individually, you make one API call and get structured JSON with prices from every book that offers the prop.<\/p>\n<h3>Which sports have player props on OddsPapi?<\/h3>\n<p>NBA, NFL, and MLB have the deepest player prop coverage. The market catalog also includes prop types for NHL (goals, saves, shots on goal), soccer (shots, tackles, goals), and cricket (runs, wickets). Prop availability depends on the sport, league, and how close the fixture is to game time.<\/p>\n<h3>Can I get historical player prop odds?<\/h3>\n<p>Yes. The <code>\/historical-odds<\/code> endpoint returns the full price history for any market ID, including player props. You get timestamped snapshots showing how the line moved from open to close. Historical data is included on the <strong>free tier<\/strong> \u2014 no upgrade required.<\/p>\n<h3>What are combo props (PRA)?<\/h3>\n<p>Combo props combine multiple stats into a single market. \"Points + Assists + Rebounds\" (PRA) Over 29.5 is one bet on a player's combined stat line. OddsPapi handles these as <strong>native markets<\/strong> with unique market IDs \u2014 they're real bookmaker-priced lines, not reconstructed from individual props.<\/p>\n<h3>How many bookmakers offer player props?<\/h3>\n<p>It varies by sport and fixture. For NBA, we've consistently seen 4-6 bookmakers returning player props per game (Hard Rock Bet, FanDuel, theScore, BetRivers, and Caesars lead). The total bookmaker count (350+) refers to OddsPapi's full catalog across all market types \u2014 player prop coverage is a subset concentrated among US retail sportsbooks.<\/p>\n<h2>Start Building with Player Prop Data<\/h2>\n<p>Stop guessing which books have the best player prop lines. Query 350+ bookmakers in one API call, parse native combo props, shop lines across books, and backtest your prop models with free historical data.<\/p>\n<p><strong><a href=\"https:\/\/oddspapi.io\" target=\"_blank\">Get your free API key at oddspapi.io \u2192<\/a><\/strong><\/p>\n<p><!--\nFocus Keyphrase: player props API\nSEO Title: Player Props API: Get NFL, NBA & MLB Prop Odds (Python Tutorial)\nMeta Description: Get player prop odds from 350+ bookmakers via one API. Python tutorial for NBA, NFL & MLB props with tested code. Free tier available.\nSlug: player-props-api-nfl-nba-mlb-odds-python\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Get player prop odds from 350+ bookmakers via one API. Python tutorial for NBA, NFL &#038; MLB props with tested code. Free tier available.<\/p>\n","protected":false},"author":2,"featured_media":2878,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[8,17,16,52,9,51,11,10],"class_list":["post-2877","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to-guides","tag-free-api","tag-mlb","tag-nba","tag-nfl","tag-odds-api","tag-player-props","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>Player Props API: How to Get NFL, NBA &amp; MLB Prop Odds in Python | Odds API Development 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\/player-props-api-nfl-nba-mlb-odds-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Player Props API: How to Get NFL, NBA &amp; MLB Prop Odds in Python | Odds API Development Blog\" \/>\n<meta property=\"og:description\" content=\"Get player prop odds from 350+ bookmakers via one API. Python tutorial for NBA, NFL &amp; MLB props with tested code. Free tier available.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/\" \/>\n<meta property=\"og:site_name\" content=\"Odds API Development Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-12T10:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-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=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/\"},\"author\":{\"name\":\"Odds API Writer\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\"},\"headline\":\"Player Props API: How to Get NFL, NBA &#038; MLB Prop Odds in Python\",\"datePublished\":\"2026-05-12T10:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/\"},\"wordCount\":1390,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp\",\"keywords\":[\"Free API\",\"MLB\",\"NBA\",\"NFL\",\"Odds API\",\"Player Props\",\"Python\",\"Sports Betting API\"],\"articleSection\":[\"How To Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/\",\"name\":\"Player Props API: How to Get NFL, NBA & MLB Prop Odds in Python | Odds API Development Blog\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp\",\"datePublished\":\"2026-05-12T10:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp\",\"width\":2560,\"height\":1429,\"caption\":\"Player Props API - OddsPapi API Blog\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oddspapi.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Player Props API: How to Get NFL, NBA &#038; MLB Prop Odds in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\",\"url\":\"https:\/\/oddspapi.io\/blog\/\",\"name\":\"OddsPapi\",\"description\":\"Sports Odds APIs 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":"Player Props API: How to Get NFL, NBA & MLB Prop Odds in Python | Odds API Development 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\/player-props-api-nfl-nba-mlb-odds-python\/","og_locale":"en_US","og_type":"article","og_title":"Player Props API: How to Get NFL, NBA & MLB Prop Odds in Python | Odds API Development Blog","og_description":"Get player prop odds from 350+ bookmakers via one API. Python tutorial for NBA, NFL & MLB props with tested code. Free tier available.","og_url":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/","og_site_name":"Odds API Development Blog","article_published_time":"2026-05-12T10:00:00+00:00","og_image":[{"width":2560,"height":1429,"url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-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":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#article","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/"},"author":{"name":"Odds API Writer","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13"},"headline":"Player Props API: How to Get NFL, NBA &#038; MLB Prop Odds in Python","datePublished":"2026-05-12T10:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/"},"wordCount":1390,"commentCount":0,"publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp","keywords":["Free API","MLB","NBA","NFL","Odds API","Player Props","Python","Sports Betting API"],"articleSection":["How To Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/","url":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/","name":"Player Props API: How to Get NFL, NBA & MLB Prop Odds in Python | Odds API Development Blog","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp","datePublished":"2026-05-12T10:00:00+00:00","breadcrumb":{"@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#primaryimage","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/04\/player-props-api-nfl-nba-mlb-odds-python-scaled.webp","width":2560,"height":1429,"caption":"Player Props API - OddsPapi API Blog"},{"@type":"BreadcrumbList","@id":"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oddspapi.io\/blog\/"},{"@type":"ListItem","position":2,"name":"Player Props API: How to Get NFL, NBA &#038; MLB Prop Odds in Python"}]},{"@type":"WebSite","@id":"https:\/\/oddspapi.io\/blog\/#website","url":"https:\/\/oddspapi.io\/blog\/","name":"OddsPapi","description":"Sports Odds APIs 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\/2877","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=2877"}],"version-history":[{"count":1,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/2877\/revisions"}],"predecessor-version":[{"id":2879,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/2877\/revisions\/2879"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media\/2878"}],"wp:attachment":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media?parent=2877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/categories?post=2877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/tags?post=2877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}