{"id":3151,"date":"2026-07-30T10:00:00","date_gmt":"2026-07-30T10:00:00","guid":{"rendered":"https:\/\/oddspapi.io\/blog\/?p=3151"},"modified":"2026-07-18T15:41:12","modified_gmt":"2026-07-18T15:41:12","slug":"mls-odds-api","status":"publish","type":"post","link":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/","title":{"rendered":"MLS Odds API: Live Major League Soccer Odds &#038; Goalscorer Props (Python)"},"content":{"rendered":"<p>MLS has no public odds API. Major League Soccer sells its data rights, the league app shows you one price, and the generic sports APIs that do carry soccer bury MLS somewhere under 1,300 other competitions with a thin book list. If you want every price on a Sunday night Inter Miami match in one JSON call, you have to aggregate it yourself or find someone who already did.<\/p>\n<p>This guide pulls live MLS odds in Python: match result, totals, the full Asian handicap ladder, and anytime goalscorer props with real player names. Every number below came off the live API on a real MLS fixture before this post went up, including one finding that changes how you should count your bookmakers.<\/p>\n<h2>Why MLS is a good league to build on<\/h2>\n<p>MLS sits in an unusual spot. It is a soccer league priced mostly by US sportsbooks, which means the books quoting it are DraftKings, FanDuel, BetMGM, BetRivers and friends rather than the European soft books that dominate Premier League markets. Pinnacle prices it too, so you get a sharp anchor to measure everyone else against.<\/p>\n<p>On the fixture used throughout this guide, 13 bookmakers were on the board and Pinnacle alone priced 37 separate markets. Across the league, 30 MLS fixtures carried odds in a single ten-day window.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>The old way<\/th>\n<th>OddsPapi<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Scrape each sportsbook&#8217;s MLS page separately<\/td>\n<td>One call returns every book on the fixture<\/td>\n<\/tr>\n<tr>\n<td>No sharp reference price<\/td>\n<td>Pinnacle priced on every MLS fixture checked<\/td>\n<\/tr>\n<tr>\n<td>Goalscorer props locked behind the app<\/td>\n<td>Anytime scorer with player names in the JSON<\/td>\n<\/tr>\n<tr>\n<td>Pay for historical odds<\/td>\n<td>Free price history on the free tier<\/td>\n<\/tr>\n<tr>\n<td>Count 13 books, assume 13 opinions<\/td>\n<td>Detect duplicate quotes and count real ones<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>Step 1: Authenticate and find MLS<\/h2>\n<p>Grab a <a href=\"https:\/\/oddspapi.io\/blog\/free-odds-api-350-bookmakers\/\">free API key<\/a>. The key goes in the query string, not a header. MLS lives under soccer, which is <code>sportId 10<\/code>, and the tournament name in the feed is exactly <code>MLS<\/code>.<\/p>\n<pre class=\"wp-block-code\"><code>import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nBASE_URL = \"https:\/\/api.oddspapi.io\/v4\"\n\ndef api_get(path, **params):\n    params[\"apiKey\"] = API_KEY          # query param, never a header\n    r = requests.get(f\"{BASE_URL}{path}\", params=params, timeout=30)\n    r.raise_for_status()\n    return r.json()\n\nfixtures = api_get(\"\/fixtures\", sportId=10,\n                   **{\"from\": \"2026-07-18\", \"to\": \"2026-07-27\"})\n\nmls = [f for f in fixtures\n       if f.get(\"tournamentName\") == \"MLS\" and f.get(\"hasOdds\")]\n\nprint(len(mls), \"MLS fixtures with odds\")\nfor f in mls[:5]:\n    print(f[\"fixtureId\"], f[\"participant1Name\"], \"v\", f[\"participant2Name\"])\n<\/code><\/pre>\n<p>That returned 30 MLS fixtures with odds. The <code>hasOdds<\/code> filter matters: fixtures without it return metadata only and no <code>bookmakerOdds<\/code> key. Note that team names live on <code>participant1Name<\/code> and <code>participant2Name<\/code> in the <code>\/fixtures<\/code> response, not in the odds payload, which carries participant IDs only.<\/p>\n<h2>Step 2: Pull the match result market<\/h2>\n<p>The worked example is Inter Miami CF against Chicago Fire, fixture <code>id1000024266299252<\/code>. Full Time Result is market <code>101<\/code>, with outcomes <code>101<\/code> home, <code>102<\/code> draw, <code>103<\/code> away.<\/p>\n<pre class=\"wp-block-code\"><code>FID = \"id1000024266299252\"\nodds = api_get(\"\/odds\", fixtureId=FID)\nbooks = odds[\"bookmakerOdds\"]\n\ndef price(slug, market_id, outcome_id):\n    node = (books.get(slug, {}).get(\"markets\", {})\n                 .get(market_id, {}).get(\"outcomes\", {}).get(outcome_id, {}))\n    player = node.get(\"players\", {}).get(\"0\")\n    if not player or node.get(\"active\") is False:\n        return None\n    return player.get(\"price\")\n\nfor slug in sorted(books):\n    h, d, a = (price(slug, \"101\", o) for o in (\"101\", \"102\", \"103\"))\n    if h:\n        print(f\"{slug:20} {h:6} {d:6} {a:6}\")\n<\/code><\/pre>\n<p>Filter on <code>active is False<\/code> rather than testing whether <code>active<\/code> is true. The live feed sometimes ships <code>active: null<\/code> next to a perfectly good price, and a truthy check silently throws those away.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Bookmaker<\/th>\n<th>Inter Miami<\/th>\n<th>Draw<\/th>\n<th>Chicago Fire<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>pinnacle<\/td>\n<td>1.99<\/td>\n<td>4.29<\/td>\n<td>3.15<\/td>\n<\/tr>\n<tr>\n<td>kalshi<\/td>\n<td>2.041<\/td>\n<td>4.545<\/td>\n<td>3.226<\/td>\n<\/tr>\n<tr>\n<td>polymarket<\/td>\n<td>2.00<\/td>\n<td>4.545<\/td>\n<td>3.333<\/td>\n<\/tr>\n<tr>\n<td>draftkings<\/td>\n<td>1.95<\/td>\n<td>4.10<\/td>\n<td>3.00<\/td>\n<\/tr>\n<tr>\n<td>fanduel<\/td>\n<td>1.95<\/td>\n<td>4.00<\/td>\n<td>3.30<\/td>\n<\/tr>\n<tr>\n<td>bet365<\/td>\n<td>1.90<\/td>\n<td>4.00<\/td>\n<td>3.30<\/td>\n<\/tr>\n<tr>\n<td>betrivers<\/td>\n<td>1.89<\/td>\n<td>4.20<\/td>\n<td>3.30<\/td>\n<\/tr>\n<tr>\n<td>ballybet \/ betparx \/ fourwinds<\/td>\n<td>1.90<\/td>\n<td>4.20<\/td>\n<td>3.35<\/td>\n<\/tr>\n<tr>\n<td>betmgm \/ borgata<\/td>\n<td>1.52<\/td>\n<td>4.75<\/td>\n<td>4.80<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>Step 3: Count your real bookmakers, not your slugs<\/h2>\n<p>Look at the last two rows again. Three slugs quoted 1.90 \/ 4.20 \/ 3.35 and two quoted 1.52 \/ 4.75 \/ 4.80. Those are not near-misses, they match to the decimal. Checking six MLS fixtures in a row, <code>ballybet<\/code>, <code>betparx<\/code> and <code>fourwinds<\/code> were identical on all six, and <code>betmgm<\/code> and <code>borgata<\/code> were identical on all six.<\/p>\n<p>The bookmaker catalog does not tell you this. All five carry <code>cloneOf: null<\/code> in <code>\/v4\/bookmakers<\/code>, so the only way to find it is to compare prices yourself. Thirteen slugs on this fixture collapse to ten independent quotes.<\/p>\n<pre class=\"wp-block-code\"><code>from collections import defaultdict\n\ngroups = defaultdict(list)\nfor slug in books:\n    quote = tuple(price(slug, \"101\", o) for o in (\"101\", \"102\", \"103\"))\n    if None not in quote:\n        groups[quote].append(slug)\n\nprint(len(books), \"slugs ->\", len(groups), \"distinct quotes\")\nfor quote, slugs in groups.items():\n    if len(slugs) &gt; 1:\n        print(\"  duplicate:\", quote, slugs)\n\n# 13 slugs -> 10 distinct quotes\n#   duplicate: (1.9, 4.2, 3.35) ['betparx', 'ballybet', 'fourwinds']\n#   duplicate: (1.52, 4.75, 4.8) ['betmgm', 'borgata']\n<\/code><\/pre>\n<p>This matters if you build a consensus price. Averaging 13 quotes when three of them are the same feed weights that opinion triple. Deduplicate first, then average. The same trap shows up whenever you compute <a href=\"https:\/\/oddspapi.io\/blog\/consensus-odds-fair-odds-calculator-python\/\">consensus odds across many books<\/a>.<\/p>\n<h2>Step 4: De-vig Pinnacle for a fair price<\/h2>\n<p>Pinnacle is the sharp reference. Strip its margin to get a fair probability for each outcome.<\/p>\n<pre class=\"wp-block-code\"><code>quote = {o: price(\"pinnacle\", \"101\", o) for o in (\"101\", \"102\", \"103\")}\nimplied = {k: 1 \/ v for k, v in quote.items()}\ntotal = sum(implied.values())\n\nprint(f\"overround {(total - 1) * 100:.2f}%\")\nfor k, label in [(\"101\", \"Inter Miami\"), (\"102\", \"Draw\"), (\"103\", \"Chicago\")]:\n    print(f\"{label:12} fair prob {implied[k]\/total:.4f}  fair odds {total\/implied[k]:.4f}\")\n\n# overround 5.31%\n# Inter Miami  fair prob 0.4772  fair odds 2.0956\n# Draw         fair prob 0.2214  fair odds 4.5177\n# Chicago      fair prob 0.3015  fair odds 3.3172\n<\/code><\/pre>\n<p>Pinnacle carried a 5.31% margin on this three-way market. Fair prices land at 2.0956 on Inter Miami, 4.5177 on the draw and 3.3172 on Chicago. If you want the proportional, power and Shin methods compared, the <a href=\"https:\/\/oddspapi.io\/blog\/no-vig-odds-api\/\">no-vig odds guide<\/a> walks through all three.<\/p>\n<h2>Step 5: Sanity-check the outliers before you trust them<\/h2>\n<p>Run a naive best-price scan and Chicago Fire comes back at 4.80 from BetMGM against a Pinnacle fair price of 3.3172. That looks like a 45% edge. It is not.<\/p>\n<p>The free historical endpoint explains it. Pinnacle opened Inter Miami at 1.684 and drifted to 1.99 across 17 recorded price points, so the market moved substantially away from Miami. BetMGM and its twin still sat at 1.52, shorter than Pinnacle&#8217;s opening number. That is the shape of a price that has not caught up, and the 4.80 on the other side is the mirror of the same lag.<\/p>\n<pre class=\"wp-block-code\"><code>hist = api_get(\"\/historical-odds\", fixtureId=FID,\n               bookmakers=\"pinnacle,draftkings,fanduel\")   # max 3 per call\n\nsnaps = (hist[\"bookmakers\"][\"pinnacle\"][\"markets\"][\"101\"]\n             [\"outcomes\"][\"101\"][\"players\"][\"0\"])           # a LIST, not a dict\n\nprint(len(snaps), \"snapshots\",\n      snaps[0][\"price\"], \"->\", snaps[-1][\"price\"])\n# 17 snapshots 1.684 -> 1.99\n<\/code><\/pre>\n<p>Two rules follow. Compare any outlier against the sharp book&#8217;s price history before calling it value, and remember that a stale line is usually unavailable by the time you click it. Note also that the historical endpoint nests under <code>bookmakers<\/code> rather than <code>bookmakerOdds<\/code>, and <code>players[\"0\"]<\/code> is a list of snapshots instead of a single price.<\/p>\n<h2>Step 6: Totals and the Asian handicap ladder<\/h2>\n<p>MLS carries the full native market tree. Pinnacle priced 37 markets on this one fixture, including Over\/Under from 2.5 through 5.5 and Asian handicaps from -1.75 to +0.25 in quarter-goal steps.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Market<\/th>\n<th>ID<\/th>\n<th>Handicap<\/th>\n<th>Pinnacle price<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Over\/Under Full Time<\/td>\n<td>1010<\/td>\n<td>2.5<\/td>\n<td>Over 1.328 \/ Under 3.31<\/td>\n<\/tr>\n<tr>\n<td>Over\/Under Full Time<\/td>\n<td>1012<\/td>\n<td>3.5<\/td>\n<td>Over 1.869 \/ Under 1.961<\/td>\n<\/tr>\n<tr>\n<td>Asian Handicap<\/td>\n<td>1064<\/td>\n<td>-1.0<\/td>\n<td>2.77 \/ 1.458<\/td>\n<\/tr>\n<tr>\n<td>Asian Handicap<\/td>\n<td>1068<\/td>\n<td>-0.5<\/td>\n<td>2.00 \/ 1.854<\/td>\n<\/tr>\n<tr>\n<td>Asian Handicap<\/td>\n<td>1072<\/td>\n<td>0<\/td>\n<td>1.558 \/ 2.48<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>The Over\/Under 2.5 line came in at 1.328 and 3.31, a 5.51% margin. Do not hardcode these IDs across sports. Every handicap step is its own market ID, so resolve them from the catalog instead.<\/p>\n<pre class=\"wp-block-code\"><code>catalog = api_get(\"\/markets\", sportId=10)\nlookup = {m[\"marketId\"]: (m[\"marketName\"], m.get(\"handicap\")) for m in catalog}\n\nfor mid in books[\"pinnacle\"][\"markets\"]:\n    name, handicap = lookup.get(int(mid), (\"?\", None))\n    if name == \"Asian Handicap\":\n        print(mid, name, handicap)\n<\/code><\/pre>\n<p>If Asian handicaps are the reason you are here, the <a href=\"https:\/\/oddspapi.io\/blog\/asian-handicap-api-cross-book-odds\/\">cross-book Asian handicap guide<\/a> goes deeper on settlement and quarter lines.<\/p>\n<h2>Step 7: Anytime goalscorer props<\/h2>\n<p>Anytime Goal Scorer is market <code>10730<\/code>. Five books priced it on this fixture: BallyBet, BetParX, BetRivers, FourWinds and PointsBet. There is a parsing catch that will make the market look empty if you miss it.<\/p>\n<p>On game lines the <code>players<\/code> dict has a single <code>\"0\"<\/code> key. On player props it is keyed by player id, and each entry carries a <code>playerName<\/code> in <code>\"Last, First\"<\/code> format. One outcome holds the entire squad.<\/p>\n<pre class=\"wp-block-code\"><code>market = books[\"ballybet\"][\"markets\"][\"10730\"]\n\nfor outcome in market[\"outcomes\"].values():\n    rows = []\n    for player_id, node in outcome[\"players\"].items():\n        if player_id == \"0\":          # skip the game-line key\n            continue\n        rows.append((node[\"playerName\"], node[\"price\"]))\n    for name, odds in sorted(rows, key=lambda r: r[1])[:6]:\n        print(f\"{name:28} {odds}\")\n\n# Messi, Lionel                1.6\n# Cuypers, Hugo                2.05\n# Berterame, German            2.6\n# Suarez, Luis                 2.8\n# Silvetti, Mateo              3.1\n# Zinckernagel, Philip         3.2\n<\/code><\/pre>\n<p>That outcome held 26 players. Messi came back shortest at 1.60 to score at any time, Luis Suarez at 2.80. Loop the same parse across the five books that price the market and you have a goalscorer comparison nobody publishes in one place. The <a href=\"https:\/\/oddspapi.io\/blog\/player-props-api-nfl-nba-mlb-odds-python\/\">player props API guide<\/a> covers the same keying pattern for NFL, NBA and MLB.<\/p>\n<h2>Step 8: Shop the line properly<\/h2>\n<p>Put the pieces together: dedupe the duplicate feeds, skip inactive outcomes, then take the best remaining price per outcome.<\/p>\n<pre class=\"wp-block-code\"><code>def best_price(books, market_id, outcome_id):\n    seen, offers = set(), []\n    for slug in books:\n        p = price(slug, market_id, outcome_id)\n        if p is None:\n            continue\n        quote = tuple(price(slug, market_id, o) for o in (\"101\", \"102\", \"103\"))\n        if quote in seen:              # duplicate feed, count it once\n            continue\n        seen.add(quote)\n        offers.append((p, slug))\n    return sorted(offers, reverse=True)\n\nfor oid, label in [(\"101\", \"Inter Miami\"), (\"102\", \"Draw\"), (\"103\", \"Chicago\")]:\n    top = best_price(books, \"101\", oid)[:2]\n    print(label, top)\n<\/code><\/pre>\n<p>Best available on Inter Miami was 2.041 at Kalshi, ahead of Polymarket at 2.00 and Pinnacle at 1.99. Both prediction markets beat every US retail book on that side. Those are the best prices on the board, which is a shopping result and not a claim that either is a profitable bet. For the general version across every sport, see <a href=\"https:\/\/oddspapi.io\/blog\/line-shopping-python-best-odds\/\">line shopping in Python<\/a>.<\/p>\n<h2>Frequently asked questions<\/h2>\n<h3>Is there an official MLS odds API?<\/h3>\n<p>No. Major League Soccer does not publish a public odds API, and individual sportsbooks do not offer open odds endpoints either. Aggregating the books is the practical route, which is what the code above does through a single fixture call.<\/p>\n<h3>Which bookmakers price MLS?<\/h3>\n<p>On the fixture checked for this guide, 13 books were on the board: Pinnacle, Kalshi, Polymarket, DraftKings, FanDuel, BetMGM, Borgata, Bet365, BetRivers, BallyBet, BetParX, FourWinds and PointsBet. Pinnacle appeared on every MLS fixture sampled, which gives you a sharp reference price.<\/p>\n<h3>Does the API have MLS goalscorer props?<\/h3>\n<p>Yes. Anytime Goal Scorer is market 10730 and was priced by five books on the sample fixture, with 26 players and readable names in the payload. First and last goalscorer markets also appear, though on fewer books.<\/p>\n<h3>Why do some bookmakers show identical MLS odds?<\/h3>\n<p>Several slugs quote the same numbers to the decimal. Across six MLS fixtures, BallyBet, BetParX and FourWinds matched every time, as did BetMGM and Borgata. The catalog does not flag them as related, so compare quotes yourself and deduplicate before averaging books into a consensus.<\/p>\n<h3>Can I get historical MLS odds for backtesting?<\/h3>\n<p>Yes, on the free tier. The \/historical-odds endpoint returns the recorded price history for a fixture, capped at three bookmakers per call. Pinnacle showed 17 price points on the sample fixture, tracing the line from 1.684 to 1.99.<\/p>\n<h2>Start pulling MLS prices<\/h2>\n<p>One call gives you 13 books, 37 Pinnacle markets, a full Asian handicap ladder and a goalscorer board with real names. The catalog runs to 350+ bookmakers across 69 sports, and the price history is free. <a href=\"https:\/\/oddspapi.io\/blog\/free-odds-api-350-bookmakers\/\">Get your free API key<\/a> and point it at this weekend&#8217;s fixtures. If you want the broader soccer picture beyond MLS, start with the <a href=\"https:\/\/oddspapi.io\/blog\/football-odds-api-soccer-data\/\">football odds API guide<\/a>.<\/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\": \"Is there an official MLS odds API?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"No. Major League Soccer does not publish a public odds API, and individual sportsbooks do not offer open odds endpoints. Aggregating the books through a single fixture call is the practical route.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Which bookmakers price MLS odds?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"On the sample fixture, 13 books were on the board: Pinnacle, Kalshi, Polymarket, DraftKings, FanDuel, BetMGM, Borgata, Bet365, BetRivers, BallyBet, BetParX, FourWinds and PointsBet. Pinnacle appeared on every MLS fixture sampled, giving a sharp reference price.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Does the API have MLS goalscorer props?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes. Anytime Goal Scorer is market 10730, priced by five books on the sample fixture with 26 players and readable player names in the payload. First and last goalscorer markets also appear on fewer books.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Why do some bookmakers show identical MLS odds?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Several slugs quote the same numbers to the decimal. Across six MLS fixtures, BallyBet, BetParX and FourWinds matched every time, as did BetMGM and Borgata. The catalog does not flag them as related, so compare quotes and deduplicate before averaging books into a consensus.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Can I get historical MLS odds for backtesting?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes, on the free tier. The historical odds endpoint returns recorded price history for a fixture, capped at three bookmakers per call. Pinnacle showed 17 price points on the sample fixture, tracing the line from 1.684 to 1.99.\"\n      }\n    }\n  ]\n}\n<\/script><\/p>\n<p><!--\nFocus Keyphrase: MLS odds API\nSEO Title: MLS Odds API: Live Major League Soccer Odds & Goalscorer Props\nMeta Description: Pull live MLS odds in Python from 13 bookmakers including Pinnacle. Match result, Asian handicaps, goalscorer props and free historical data.\nSlug: mls-odds-api\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>No official MLS odds API? Pull live Major League Soccer prices from 13 books incl Pinnacle, plus goalscorer props and free historical odds.<\/p>\n","protected":false},"author":2,"featured_media":3152,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[8,9,11,15,10],"class_list":["post-3151","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to-guides","tag-free-api","tag-odds-api","tag-python","tag-soccer","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>MLS Odds API: Live Major League Soccer Odds &amp; Goalscorer Props (Python) | 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\/mls-odds-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MLS Odds API: Live Major League Soccer Odds &amp; Goalscorer Props (Python) | OddsPapi Blog\" \/>\n<meta property=\"og:description\" content=\"No official MLS odds API? Pull live Major League Soccer prices from 13 books incl Pinnacle, plus goalscorer props and free historical odds.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/\" \/>\n<meta property=\"og:site_name\" content=\"OddsPapi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-30T10:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-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=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/\"},\"author\":{\"name\":\"Odds API Writer\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\"},\"headline\":\"MLS Odds API: Live Major League Soccer Odds &#038; Goalscorer Props (Python)\",\"datePublished\":\"2026-07-30T10:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/\"},\"wordCount\":1393,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp\",\"keywords\":[\"Free API\",\"Odds API\",\"Python\",\"Soccer\",\"Sports Betting API\"],\"articleSection\":[\"How To Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/\",\"name\":\"MLS Odds API: Live Major League Soccer Odds & Goalscorer Props (Python) | OddsPapi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp\",\"datePublished\":\"2026-07-30T10:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp\",\"width\":2560,\"height\":1429,\"caption\":\"MLS Odds API - OddsPapi API Blog\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oddspapi.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MLS Odds API: Live Major League Soccer Odds &#038; Goalscorer Props (Python)\"}]},{\"@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":"MLS Odds API: Live Major League Soccer Odds & Goalscorer Props (Python) | 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\/mls-odds-api\/","og_locale":"en_US","og_type":"article","og_title":"MLS Odds API: Live Major League Soccer Odds & Goalscorer Props (Python) | OddsPapi Blog","og_description":"No official MLS odds API? Pull live Major League Soccer prices from 13 books incl Pinnacle, plus goalscorer props and free historical odds.","og_url":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/","og_site_name":"OddsPapi Blog","article_published_time":"2026-07-30T10:00:00+00:00","og_image":[{"width":2560,"height":1429,"url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-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":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#article","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/"},"author":{"name":"Odds API Writer","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13"},"headline":"MLS Odds API: Live Major League Soccer Odds &#038; Goalscorer Props (Python)","datePublished":"2026-07-30T10:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/"},"wordCount":1393,"commentCount":0,"publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp","keywords":["Free API","Odds API","Python","Soccer","Sports Betting API"],"articleSection":["How To Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oddspapi.io\/blog\/mls-odds-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/","url":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/","name":"MLS Odds API: Live Major League Soccer Odds & Goalscorer Props (Python) | OddsPapi Blog","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp","datePublished":"2026-07-30T10:00:00+00:00","breadcrumb":{"@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oddspapi.io\/blog\/mls-odds-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#primaryimage","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/07\/mls-odds-api-scaled.webp","width":2560,"height":1429,"caption":"MLS Odds API - OddsPapi API Blog"},{"@type":"BreadcrumbList","@id":"https:\/\/oddspapi.io\/blog\/mls-odds-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oddspapi.io\/blog\/"},{"@type":"ListItem","position":2,"name":"MLS Odds API: Live Major League Soccer Odds &#038; Goalscorer Props (Python)"}]},{"@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\/3151","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=3151"}],"version-history":[{"count":1,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/3151\/revisions"}],"predecessor-version":[{"id":3153,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/3151\/revisions\/3153"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media\/3152"}],"wp:attachment":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media?parent=3151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/categories?post=3151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/tags?post=3151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}