{"id":5209,"date":"2026-10-26T10:00:00","date_gmt":"2026-10-26T10:00:00","guid":{"rendered":"https:\/\/oddspapi.io\/blog\/?p=5209"},"modified":"2026-10-19T13:40:44","modified_gmt":"2026-10-19T13:40:44","slug":"south-america-sports-betting-api","status":"publish","type":"post","link":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/","title":{"rendered":"South America Sports Betting API: Rank 247 Books per Fixture"},"content":{"rendered":"<p>If you need a South America sports betting API, you want the Argentine, Colombian and Peruvian boards as JSON, with the local books next to the global ones. OddsPapi carries 68 South American soccer tournaments in the same schema as the Premier League, and one key reads all of them. On 19 October 2026, between 13:11 and 13:20 UTC, we read 26 open boards across nine tournaments: the median fixture carried 247 bookmakers, and the deepest Argentine board carried 276.<\/p>\n<p>You also need a reference close for each tournament, the book that settles tightest. We pulled the closing 1X2 on 62 played fixtures from 10 to 19 October. Of the three books we tracked, Pinnacle closed tightest in Argentina, Brazil, Chile, Ecuador, Uruguay and Paraguay. In Peru and Bolivia, the Peruvian book Apuesta Total closed under Pinnacle on all 12 fixtures. This guide pulls the tournaments, ranks every book on each board, and checks the close.<\/p>\n<h2>Why a scraper per country gives you a partial board<\/h2>\n<p>If you scrape South American books, you maintain one parser per site and one per country, and you still miss most of the board. On the boards we read, the median fixture drew 247 books. Many of them are crypto and offshore sportsbooks, US books and European exchanges that no regional scraper touches. Some of the tightest prices on the board come from those books.<\/p>\n<p>OddsPapi returns every book in one <code>\/v4\/odds<\/code> call, with a <code>bookmakerFixtureId<\/code> and a <code>fixturePath<\/code> deep link to the event on each book&#8217;s own site. The local books ship under their own slugs: <code>apuestatotal<\/code> (Peru), <code>betplay<\/code> and <code>rushbet.co<\/code> (Colombia), <code>betano.pe<\/code>, and the Brazilian licensees that our <a href=\"https:\/\/oddspapi.io\/blog\/brasileirao-odds-api\/\">Brasileir\u00e3o odds API guide<\/a> covers.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>Scrape local sites<\/th>\n<th>OddsPapi<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Access<\/td>\n<td>No public odds API, one parser per site<\/td>\n<td>REST and WebSocket, one <code>apiKey<\/code> query parameter<\/td>\n<\/tr>\n<tr>\n<td>Books per fixture<\/td>\n<td>The sites you scrape<\/td>\n<td>247 on the median open board we read, 350+ in the catalogue<\/td>\n<\/tr>\n<tr>\n<td>Tournaments<\/td>\n<td>One site per country<\/td>\n<td>68 South American soccer tournaments with fixtures loaded<\/td>\n<\/tr>\n<tr>\n<td>Shared platforms<\/td>\n<td>Invisible<\/td>\n<td>A shared <code>bookmakerFixtureId<\/code> groups the books on one platform<\/td>\n<\/tr>\n<tr>\n<td>Played fixtures<\/td>\n<td>Only what your recorder saved<\/td>\n<td><code>\/v4\/historical-odds<\/code> on the free tier<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2>Step 1: find the South American tournaments<\/h2>\n<p>Authentication is one query parameter, <code>apiKey<\/code>. The helper waits out a 429 for as long as the error body says, backs off on a 5xx, and returns <code>None<\/code> on a 404. The script reads the soccer catalogue, keeps the ten South American countries and the two CONMEBOL club cups, and picks the biggest competition per country.<\/p>\n<pre class=\"wp-block-code\"><code>import os, time, requests\nfrom datetime import datetime, timedelta, timezone\nfrom statistics import median\n\nAPI_KEY = os.environ[&quot;ODDSPAPI_API_KEY&quot;]\nBASE = &quot;https:\/\/api.oddspapi.io\/v4&quot;\n\ndef get(path, **params):\n    params[&quot;apiKey&quot;] = API_KEY\n    for _ in range(8):\n        r = requests.get(f&quot;{BASE}\/{path}&quot;, params=params, timeout=180)\n        if r.status_code == 429:                      # rate limited: wait as told\n            time.sleep(r.json().get(&quot;error&quot;, {}).get(&quot;retryMs&quot;, 2000) \/ 1000 + 0.5)\n            continue\n        if r.status_code &gt;= 500:                      # transient: back off and retry\n            time.sleep(2)\n            continue\n        if r.status_code == 404:                      # empty window\n            return None\n        r.raise_for_status()\n        return r.json()\n    raise RuntimeError(f&quot;gave up on {path}&quot;)\n\nCOUNTRIES = [&quot;Argentina&quot;, &quot;Bolivia&quot;, &quot;Brazil&quot;, &quot;Chile&quot;, &quot;Colombia&quot;, &quot;Ecuador&quot;,\n             &quot;Paraguay&quot;, &quot;Peru&quot;, &quot;Uruguay&quot;, &quot;Venezuela&quot;]\n\ntournaments = get(&quot;tournaments&quot;, sportId=10)          # soccer\nlive = [t for t in tournaments\n        if (t[&quot;categoryName&quot;] in COUNTRIES or t[&quot;tournamentName&quot;].startswith(&quot;CONMEBOL&quot;))\n        and t[&quot;futureFixtures&quot;] &gt; 0]\nprint(f&quot;{len(live)} South American soccer tournaments with fixtures loaded\\n&quot;)\n\n# the biggest competition per country, plus the two CONMEBOL club cups\ntop = {}\nfor t in sorted(live, key=lambda t: -t[&quot;futureFixtures&quot;]):\n    key = t[&quot;tournamentName&quot;] if t[&quot;categoryName&quot;] == &quot;International Clubs&quot; else t[&quot;categoryName&quot;]\n    if &quot;Women&quot; in t[&quot;tournamentName&quot;] or &quot;Reserve&quot; in t[&quot;tournamentName&quot;]:\n        continue\n    top.setdefault(key, t)\nfor key, t in sorted(top.items()):\n    print(f&#x27;{t[&quot;tournamentId&quot;]:&gt;6}  {t[&quot;categoryName&quot;]:&lt;19} {t[&quot;tournamentName&quot;]:&lt;26} &#x27;\n          f&#x27;{t[&quot;futureFixtures&quot;]:&gt;3} future fixtures&#x27;)<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>68 South American soccer tournaments with fixtures loaded\n\n   155  Argentina           Primera LPF                 45 future fixtures\n 33980  Bolivia             Division Profesional        48 future fixtures\n   325  Brazil              Brasileiro Serie A          70 future fixtures\n   384  International Clubs CONMEBOL Libertadores        2 future fixtures\n   480  International Clubs CONMEBOL Sudamericana        2 future fixtures\n 27665  Chile               Primera Division            50 future fixtures\n 27070  Colombia            Liga DIMAYOR                54 future fixtures\n   240  Ecuador             LigaPro Primera A           48 future fixtures\n 27098  Paraguay            Division de Honor           42 future fixtures\n   406  Peru                Liga 1                      45 future fixtures\n   278  Uruguay             Primera Division             8 future fixtures\n 19282  Venezuela           Copa Venezuela               8 future fixtures<\/code><\/pre>\n<p>Each <code>tournamentId<\/code> is the filter you pass to <code>\/v4\/fixtures<\/code>. The endpoint docs leave it out, but it works and lets you pull a whole month in one call. Venezuela shows its cup because the catalogue had no Venezuelan league fixtures loaded on the day we ran this.<\/p>\n<h2>Step 2: rank every book on the next board in each tournament<\/h2>\n<p>This step reads the next open board in each tournament and scores every book on the 1X2. A book counts only when the book itself is open and all three legs are active. The script prints four numbers per board: books in the payload, books with a full 1X2, distinct price sets, and the median margin. It then prints the margin and rank of three books that you can use as a reference.<\/p>\n<pre class=\"wp-block-code\"><code># Reuses get(), top and the imports from Step 1.\nWATCH = [&quot;pinnacle&quot;, &quot;betplay&quot;, &quot;apuestatotal&quot;]\n\ndef margin_1x2(book):\n    &quot;&quot;&quot;1X2 margin in %, or None unless the book is open and all three legs are active.&quot;&quot;&quot;\n    if book.get(&quot;suspended&quot;) or book.get(&quot;bookmakerIsActive&quot;) is False:\n        return None\n    m = book[&quot;markets&quot;].get(&quot;101&quot;)                     # Full Time Result\n    if not m:\n        return None\n    legs = [m[&quot;outcomes&quot;].get(o, {}).get(&quot;players&quot;, {}).get(&quot;0&quot;) for o in (&quot;101&quot;, &quot;102&quot;, &quot;103&quot;)]\n    if not all(l and l.get(&quot;active&quot;) and l.get(&quot;price&quot;) for l in legs):\n        return None\n    return (sum(1 \/ l[&quot;price&quot;] for l in legs) - 1) * 100, tuple(l[&quot;price&quot;] for l in legs)\n\nnow = datetime.now(timezone.utc)\nwindow = {&quot;from&quot;: now.strftime(&quot;%Y-%m-%d&quot;),\n          &quot;to&quot;: (now + timedelta(days=5)).strftime(&quot;%Y-%m-%d&quot;)}\nfor key, t in sorted(top.items()):\n    fixtures = get(&quot;fixtures&quot;, tournamentId=t[&quot;tournamentId&quot;], **window) or []\n    time.sleep(1)\n    for f in sorted(fixtures, key=lambda f: f[&quot;startTime&quot;]):\n        if (f[&quot;statusName&quot;] != &quot;Pre-Game&quot; or not f[&quot;hasOdds&quot;]\n                or f[&quot;startTime&quot;] &lt;= now.isoformat()):\n            continue\n        board = (get(&quot;odds&quot;, fixtureId=f[&quot;fixtureId&quot;]) or {}).get(&quot;bookmakerOdds&quot;, {})\n        time.sleep(1)\n        board = {s: b for s, b in board.items() if &quot;+&quot; not in s and s != &quot;demo&quot;}\n        quotes = {s: q for s, b in board.items() if (q := margin_1x2(b)) and q[0] &gt; 0}\n        if len(quotes) &gt;= 20:                          # first board with an open 1X2\n            break\n    else:\n        print(f&quot;{key:&lt;22} no open board in the next 5 days&quot;)\n        continue\n    order = sorted(quotes, key=lambda s: quotes[s][0])\n    rank = lambda s: f&quot;{quotes[s][0]:.2f}% #{order.index(s) + 1}&quot; if s in quotes else &quot;-&quot;\n    print(f&#x27;{key:&lt;22} {len(board):&gt;3} books  {len(quotes):&gt;3} full 1X2  &#x27;\n          f&#x27;{len({q[1] for q in quotes.values()}):&gt;3} distinct  &#x27;\n          f&#x27;median {median(q[0] for q in quotes.values()):.2f}%&#x27;)\n    print(&quot;    &quot; + &quot;   &quot;.join(f&quot;{s} {rank(s)}&quot; for s in WATCH))<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>Argentina              274 books  240 full 1X2   91 distinct  median 7.52%\n    pinnacle 3.50% #18   betplay 3.67% #26   apuestatotal 5.86% #64\nBolivia                no open board in the next 5 days\nBrazil                 275 books  251 full 1X2   99 distinct  median 6.99%\n    pinnacle 3.12% #20   betplay 5.81% #62   apuestatotal 4.90% #42\nCONMEBOL Libertadores  258 books  244 full 1X2   90 distinct  median 7.59%\n    pinnacle 5.82% #55   betplay 2.54% #8   apuestatotal 4.89% #18\nCONMEBOL Sudamericana  260 books  238 full 1X2   82 distinct  median 7.72%\n    pinnacle 5.44% #43   betplay 3.96% #15   apuestatotal 4.99% #20\nChile                  240 books  223 full 1X2   64 distinct  median 8.96%\n    pinnacle 5.53% #8   betplay 6.84% #27   apuestatotal 6.83% #22\nColombia               253 books  235 full 1X2   86 distinct  median 8.80%\n    pinnacle 4.89% #21   betplay 3.77% #13   apuestatotal 6.55% #31\nEcuador                204 books  188 full 1X2   65 distinct  median 8.97%\n    pinnacle 5.33% #16   betplay -   apuestatotal 6.51% #20\nParaguay               no open board in the next 5 days\nPeru                   207 books  203 full 1X2   60 distinct  median 9.31%\n    pinnacle 7.82% #43   betplay -   apuestatotal 7.23% #28\nUruguay                252 books  231 full 1X2   77 distinct  median 9.84%\n    pinnacle 4.61% #16   betplay 10.07% #157   apuestatotal 5.60% #22\nVenezuela              no open board in the next 5 days<\/code><\/pre>\n<p>We ran this on 19 October 2026 at 13:35 UTC. Two numbers matter. First, the board is wide: 204 to 275 books per fixture. Second, the price sets collapse. Argentina&#8217;s 240 full quotes came from 91 distinct price sets, because many books run on one platform and copy its prices. Dedupe before you average, as our <a href=\"https:\/\/oddspapi.io\/blog\/consensus-odds-fair-odds-calculator-python\/\">consensus odds guide<\/a> shows.<\/p>\n<p>Pinnacle ranks 8th to 55th on these boards. Exchanges, prediction markets and a few low-margin sportsbooks sit above it, and the median book charges 7% to 10%. Paraguay printed no board because its next round was four days out and the books had not opened it yet. Bolivia and Venezuela had no fixture loaded in the window. Step 3 reads Paraguay and Bolivia on played fixtures instead.<\/p>\n<p>The local books split three ways. <code>apuestatotal<\/code> shares its event ID with 23 other slugs (among them <code>lottoland<\/code>, <code>wazamba<\/code>, <code>estrelabet<\/code> and <code>winpot.mx<\/code>) on all 26 boards of our census, but its 1X2 matched another book&#8217;s prices on one board only. Treat it as its own price. <code>betplay<\/code> and <code>rushbet.co<\/code> carry the Kambi event ID with 36 other slugs, which our <a href=\"https:\/\/oddspapi.io\/blog\/unibet-api-odds-access\/\">Unibet API guide<\/a> maps. On five of eight Colombian boards, <code>rushbet.co<\/code> quoted <code>betplay<\/code>&#8216;s exact 1X2. On the Argentine boards it charged about 13%. <code>betano.pe<\/code> quoted the same prices as the global <code>betano<\/code> book on every board, so it adds no independent price. Our <a href=\"https:\/\/oddspapi.io\/blog\/betano-api-odds-access\/\">Betano API guide<\/a> covers that family.<\/p>\n<h2>Step 3: check the closing line on played fixtures<\/h2>\n<p>A live board shows you the price days before kickoff. The close shows where each book settled after the full market cycle. This step pulls the played Colombian round of 17 to 19 October from <code>\/v4\/historical-odds<\/code> and takes the last active price before kickoff on each leg. One call per outcome keeps the payload small. Use <code>startTime<\/code> as the cutoff, because <code>trueStartTime<\/code> can sit a few minutes after kickoff and let in-play prices in.<\/p>\n<pre class=\"wp-block-code\"><code># Reuses get() and the imports from Step 1.\nBOOKS = &quot;pinnacle,betplay,apuestatotal&quot;\nCOLOMBIA, RESULT = 27070, [&quot;101&quot;, &quot;102&quot;, &quot;103&quot;]   # Full Time Result: home, draw, away\n\ndef closing_prices(fixture_id, kickoff, outcome_id):\n    &quot;&quot;&quot;Last active price before kickoff, per book, for one outcome.&quot;&quot;&quot;\n    hist = get(&quot;historical-odds&quot;, fixtureId=fixture_id,\n               bookmakers=BOOKS, outcomeId=outcome_id)\n    time.sleep(4.6)                    # \/historical-odds needs a longer gap\n    close = {}\n    for slug, book in (hist or {}).get(&quot;bookmakers&quot;, {}).items():\n        for market in book[&quot;markets&quot;].values():\n            for o in market[&quot;outcomes&quot;].values():\n                snaps = [s for s in o[&quot;players&quot;].get(&quot;0&quot;, [])\n                         if s[&quot;active&quot;] and s[&quot;createdAt&quot;] &lt; kickoff]\n                if snaps:\n                    close[slug] = snaps[-1][&quot;price&quot;]\n    return close\n\nplayed = get(&quot;fixtures&quot;, tournamentId=COLOMBIA,\n             **{&quot;from&quot;: &quot;2026-10-17&quot;, &quot;to&quot;: &quot;2026-10-20&quot;}) or []\nplayed = [f for f in played if f[&quot;statusName&quot;] == &quot;Finished&quot;]\n\nmargins = {s: [] for s in BOOKS.split(&quot;,&quot;)}\nfor f in sorted(played, key=lambda f: f[&quot;startTime&quot;]):\n    kickoff = f[&quot;startTime&quot;]           # scheduled kickoff, not trueStartTime\n    legs = [closing_prices(f[&quot;fixtureId&quot;], kickoff, oid) for oid in RESULT]\n    row = {}\n    for slug in margins:\n        if all(slug in leg for leg in legs):\n            row[slug] = (sum(1 \/ leg[slug] for leg in legs) - 1) * 100\n            margins[slug].append(row[slug])\n    name = f&#x27;{f[&quot;participant1Name&quot;]} v {f[&quot;participant2Name&quot;]}&#x27;[:34]\n    print(f&quot;{name:&lt;34}&quot;, &quot;  &quot;.join(f&quot;{s} {v:.2f}%&quot; for s, v in row.items()))\n\nprint(f&quot;\\n{len(played)} played Liga DIMAYOR fixtures, closing 1X2:&quot;)\nfor slug, vals in margins.items():\n    print(f&quot;  {slug:&lt;12} median {median(vals):.2f}%  ({len(vals)} fixtures)&quot;)<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>Boyaca Chico FC v Atletico Naciona pinnacle 4.90%  betplay 6.86%  apuestatotal 6.48%\nMillonarios FC v Jaguares de Cordo pinnacle 5.27%  betplay 2.94%\nIndependiente Medellin v CD Once C pinnacle 4.56%  betplay 5.89%  apuestatotal 6.55%\nAguilas Doradas Rionegro v CD Toli pinnacle 7.38%  betplay 7.30%  apuestatotal 6.46%\nCA Bucaramanga v America de Cali   pinnacle 4.47%  betplay 4.71%  apuestatotal 6.46%\nLlaneros FC v Independiente Santa  pinnacle 7.41%  betplay 10.45%  apuestatotal 6.42%\nDeportivo Cali v CD Junior FC      pinnacle 7.33%  betplay 3.48%  apuestatotal 6.53%\n\n7 played Liga DIMAYOR fixtures, closing 1X2:\n  pinnacle     median 5.27%  (7 fixtures)\n  betplay      median 5.89%  (7 fixtures)\n  apuestatotal median 6.47%  (6 fixtures)<\/code><\/pre>\n<p>Colombia is the split tournament. <code>betplay<\/code> closed under Pinnacle on three of these seven fixtures, and Pinnacle took the median by 0.6 points. We ran the same check on 62 played fixtures from 10 to 19 October, across all eleven tournaments:<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<thead>\n<tr>\n<th>Tournament (played, 10 to 19 Oct 2026)<\/th>\n<th>Fixtures<\/th>\n<th>Median close, <code>pinnacle<\/code><\/th>\n<th>Median close, <code>betplay<\/code><\/th>\n<th>Median close, <code>apuestatotal<\/code><\/th>\n<th>Tightest close of the three<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Brazil, Brasileiro Serie A<\/td>\n<td>6<\/td>\n<td>2.87%<\/td>\n<td>7.19%<\/td>\n<td>5.03%<\/td>\n<td>pinnacle 6 of 6<\/td>\n<\/tr>\n<tr>\n<td>Argentina, Primera LPF<\/td>\n<td>8<\/td>\n<td>3.54%<\/td>\n<td>5.17%<\/td>\n<td>6.01%<\/td>\n<td>pinnacle 6 of 8<\/td>\n<\/tr>\n<tr>\n<td>Chile, Primera Division<\/td>\n<td>6<\/td>\n<td>4.24%<\/td>\n<td>7.21%<\/td>\n<td>5.52%<\/td>\n<td>pinnacle 6 of 6<\/td>\n<\/tr>\n<tr>\n<td>Uruguay, Primera Division<\/td>\n<td>6<\/td>\n<td>4.48%<\/td>\n<td>10.56%<\/td>\n<td>5.49%<\/td>\n<td>pinnacle 6 of 6<\/td>\n<\/tr>\n<tr>\n<td>Ecuador, LigaPro<\/td>\n<td>6<\/td>\n<td>5.08%<\/td>\n<td>7.08%<\/td>\n<td>6.64%<\/td>\n<td>pinnacle 6 of 6<\/td>\n<\/tr>\n<tr>\n<td>Paraguay, Division de Honor<\/td>\n<td>6<\/td>\n<td>5.14%<\/td>\n<td>8.84%<\/td>\n<td>5.98%<\/td>\n<td>pinnacle 6 of 6<\/td>\n<\/tr>\n<tr>\n<td>Colombia, Liga DIMAYOR<\/td>\n<td>8<\/td>\n<td>5.21%<\/td>\n<td>5.30%<\/td>\n<td>6.46%<\/td>\n<td>betplay 3, pinnacle 3, apuestatotal 2<\/td>\n<\/tr>\n<tr>\n<td>Peru, Liga 1<\/td>\n<td>6<\/td>\n<td>6.48%<\/td>\n<td>6.48%<\/td>\n<td>5.49%<\/td>\n<td>apuestatotal 6 of 6<\/td>\n<\/tr>\n<tr>\n<td>Bolivia, Division Profesional<\/td>\n<td>6<\/td>\n<td>9.24%<\/td>\n<td>13.10%<\/td>\n<td>6.53%<\/td>\n<td>apuestatotal 6 of 6<\/td>\n<\/tr>\n<tr>\n<td>CONMEBOL Libertadores (semi-final first legs)<\/td>\n<td>2<\/td>\n<td>3.82%<\/td>\n<td>2.97%<\/td>\n<td>5.04%<\/td>\n<td>betplay 2 of 2<\/td>\n<\/tr>\n<tr>\n<td>CONMEBOL Sudamericana (semi-final first legs)<\/td>\n<td>2<\/td>\n<td>4.16%<\/td>\n<td>2.76%<\/td>\n<td>5.00%<\/td>\n<td>betplay 2 of 2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>Pinnacle closed tightest on 39 of the 62 fixtures. Its median close climbs as you move down the table: 2.87% in Brazil, over 5% in Ecuador, Paraguay and Colombia, and 9.24% in Bolivia. Apuesta Total&#8217;s median close stays between 5.0% and 6.6% in every tournament. In Peru it closed at 5.49% against Pinnacle&#8217;s 6.48%, and in Bolivia at 6.53% against 9.24%. It closed tighter than Pinnacle on 12 of those 12 fixtures. <code>betplay<\/code> closed the four CONMEBOL semi-final first legs at 2.35% to 3.39%. Four fixtures is a small sample, so treat the cups as a lead and re-run the check after the second legs.<\/p>\n<p>Take the fair price from the deduplicated board, de-vigged, and use the table to pick the reference close per tournament. Pinnacle is the tightest of the three in Brazil, Argentina, Chile, Uruguay, Ecuador and Paraguay. In Peru and Bolivia, compare against <code>apuestatotal<\/code>. In Colombia, read <code>pinnacle<\/code> and <code>betplay<\/code> side by side. Our <a href=\"https:\/\/oddspapi.io\/blog\/backtest-betting-model-free-historical-odds\/\">backtesting guide<\/a> turns closes like these into a full strategy test, and our <a href=\"https:\/\/oddspapi.io\/blog\/african-football-odds-api\/\">African football odds API guide<\/a> runs the same local-book check on a different region.<\/p>\n<p>Snapshots record polling, so collapse identical consecutive prices before you count line moves. To read these boards live without a polling loop, use the <a href=\"https:\/\/oddspapi.io\/blog\/websocket-odds-api-real-time-betting-data\/\">WebSocket feed<\/a>. For a one-page view of the Brazilian top flight, see the <a href=\"https:\/\/oddspapi.io\/sports\/football\/brasileirao\">Brasileir\u00e3o league page<\/a>.<\/p>\n<h2>South America sports betting API FAQ<\/h2>\n<h3>Is there a sports betting API for South American soccer?<\/h3>\n<p>Yes. OddsPapi carries 68 South American soccer tournaments with fixtures loaded, among them Argentina&#8217;s Primera LPF, Colombia&#8217;s Liga DIMAYOR, Peru&#8217;s Liga 1, the Brasileiro Serie A and both CONMEBOL club cups. Call \/v4\/odds with a fixtureId and your apiKey.<\/p>\n<h3>How many bookmakers price South American soccer?<\/h3>\n<p>On 26 open top-flight boards read on 19 October 2026, the median fixture carried 247 bookmakers, and the deepest Argentine board carried 276. They include Pinnacle, exchanges, US books, crypto and offshore sportsbooks and local books.<\/p>\n<h3>Which South American bookmakers can I read through the API?<\/h3>\n<p>The local slugs include apuestatotal (Peru), betplay and rushbet.co (Colombia), betano.pe, and Brazilian licensees such as betano.bet.br, estrelabet.bet.br and kto.bet.br. Check the live \/v4\/bookmakers catalogue for the current list.<\/p>\n<h3>Which bookmaker closes South American soccer tightest?<\/h3>\n<p>Across 62 played fixtures from 10 to 19 October 2026, Pinnacle closed the 1X2 tightest of three books on 39. Apuesta Total closed under Pinnacle on 12 of 12 Peru and Bolivia fixtures, and betplay closed the four CONMEBOL semi-final first legs at 2.35% to 3.39%.<\/p>\n<h3>Can I get historical odds for Copa Libertadores fixtures?<\/h3>\n<p>Yes. \/v4\/historical-odds returns snapshots on played fixtures, on the free tier. Pass the fixtureId, up to three bookmaker slugs and one outcomeId to keep the payload small, then take the last active snapshot before startTime as the close.<\/p>\n<h2>Read 247 books per fixture from one key<\/h2>\n<p>Every call in this guide runs on the free key: 350+ bookmakers in the catalogue, free historical odds for the closing-line check, and a WebSocket feed when polling gets too slow. <a href=\"https:\/\/oddspapi.io\/en\/sign-up\">Get a free API key<\/a> and run Step 2 on the next round in your tournament.<\/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 a sports betting API for South American soccer?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes. OddsPapi carries 68 South American soccer tournaments with fixtures loaded, among them Argentina's Primera LPF, Colombia's Liga DIMAYOR, Peru's Liga 1, the Brasileiro Serie A and both CONMEBOL club cups. Call \/v4\/odds with a fixtureId and your apiKey.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"How many bookmakers price South American soccer?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"On 26 open top-flight boards read on 19 October 2026, the median fixture carried 247 bookmakers, and the deepest Argentine board carried 276. They include Pinnacle, exchanges, US books, crypto and offshore sportsbooks and local books.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Which South American bookmakers can I read through the API?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"The local slugs include apuestatotal (Peru), betplay and rushbet.co (Colombia), betano.pe, and Brazilian licensees such as betano.bet.br, estrelabet.bet.br and kto.bet.br. Check the live \/v4\/bookmakers catalogue for the current list.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Which bookmaker closes South American soccer tightest?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Across 62 played fixtures from 10 to 19 October 2026, Pinnacle closed the 1X2 tightest of three books on 39. Apuesta Total closed under Pinnacle on 12 of 12 Peru and Bolivia fixtures, and betplay closed the four CONMEBOL semi-final first legs at 2.35% to 3.39%.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Can I get historical odds for Copa Libertadores fixtures?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes. \/v4\/historical-odds returns snapshots on played fixtures, on the free tier. Pass the fixtureId, up to three bookmaker slugs and one outcomeId to keep the payload small, then take the last active snapshot before startTime as the close.\"\n      }\n    }\n  ]\n}\n<\/script><\/p>\n<p><!--\nFocus Keyphrase: south america sports betting api\nSEO Title: South America Sports Betting API: Rank 247 Books per Fixture\nMeta Description: Pull 1X2 odds for 11 South American tournaments with one sports betting API. Apuesta Total closed under Pinnacle on 12 of 12 Peru and Bolivia fixtures.\nSlug: south-america-sports-betting-api\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pull 1X2 odds for 11 South American tournaments with one sports betting API. Apuesta Total closed under Pinnacle on 12 of 12 Peru and Bolivia fixtures.<\/p>\n","protected":false},"author":2,"featured_media":5210,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[4,9,11,15,10],"class_list":["post-5209","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to-guides","tag-historical-odds","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>South America Sports Betting API: Rank 247 Books per Fixture | 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\/south-america-sports-betting-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"South America Sports Betting API: Rank 247 Books per Fixture | OddsPapi Blog\" \/>\n<meta property=\"og:description\" content=\"Pull 1X2 odds for 11 South American tournaments with one sports betting API. Apuesta Total closed under Pinnacle on 12 of 12 Peru and Bolivia fixtures.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/\" \/>\n<meta property=\"og:site_name\" content=\"OddsPapi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-26T10:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Odds API Writer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/oddspapi.io\/logo-v2.webp\" \/>\n<meta name=\"twitter:creator\" content=\"@oddspapiapi\" \/>\n<meta name=\"twitter:site\" content=\"@oddspapiapi\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Odds API Writer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/\"},\"author\":{\"name\":\"Odds API Writer\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\"},\"headline\":\"South America Sports Betting API: Rank 247 Books per Fixture\",\"datePublished\":\"2026-10-26T10:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/\"},\"wordCount\":1427,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp\",\"keywords\":[\"historical odds\",\"Odds API\",\"Python\",\"Soccer\",\"Sports Betting API\"],\"articleSection\":[\"How To Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/\",\"name\":\"South America Sports Betting API: Rank 247 Books per Fixture | OddsPapi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp\",\"datePublished\":\"2026-10-26T10:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp\",\"width\":1200,\"height\":675,\"caption\":\"South America Sports Betting API\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oddspapi.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"South America Sports Betting API: Rank 247 Books per Fixture\"}]},{\"@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":"South America Sports Betting API: Rank 247 Books per Fixture | 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\/south-america-sports-betting-api\/","og_locale":"en_US","og_type":"article","og_title":"South America Sports Betting API: Rank 247 Books per Fixture | OddsPapi Blog","og_description":"Pull 1X2 odds for 11 South American tournaments with one sports betting API. Apuesta Total closed under Pinnacle on 12 of 12 Peru and Bolivia fixtures.","og_url":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/","og_site_name":"OddsPapi Blog","article_published_time":"2026-10-26T10:00:00+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp","type":"image\/webp"}],"author":"Odds API Writer","twitter_card":"summary_large_image","twitter_image":"https:\/\/oddspapi.io\/logo-v2.webp","twitter_creator":"@oddspapiapi","twitter_site":"@oddspapiapi","twitter_misc":{"Written by":"Odds API Writer","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#article","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/"},"author":{"name":"Odds API Writer","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13"},"headline":"South America Sports Betting API: Rank 247 Books per Fixture","datePublished":"2026-10-26T10:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/"},"wordCount":1427,"commentCount":0,"publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp","keywords":["historical odds","Odds API","Python","Soccer","Sports Betting API"],"articleSection":["How To Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/","url":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/","name":"South America Sports Betting API: Rank 247 Books per Fixture | OddsPapi Blog","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp","datePublished":"2026-10-26T10:00:00+00:00","breadcrumb":{"@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#primaryimage","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/10\/south-america-sports-betting-api.webp","width":1200,"height":675,"caption":"South America Sports Betting API"},{"@type":"BreadcrumbList","@id":"https:\/\/oddspapi.io\/blog\/south-america-sports-betting-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oddspapi.io\/blog\/"},{"@type":"ListItem","position":2,"name":"South America Sports Betting API: Rank 247 Books per Fixture"}]},{"@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\/5209","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=5209"}],"version-history":[{"count":1,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/5209\/revisions"}],"predecessor-version":[{"id":5211,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/5209\/revisions\/5211"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media\/5210"}],"wp:attachment":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media?parent=5209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/categories?post=5209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/tags?post=5209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}