{"id":97,"date":"2026-01-02T15:50:05","date_gmt":"2026-01-02T15:50:05","guid":{"rendered":"https:\/\/oddspapi.io\/blog\/?p=97"},"modified":"2026-10-13T13:23:51","modified_gmt":"2026-10-13T13:23:51","slug":"polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide","status":"publish","type":"post","link":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/","title":{"rendered":"Polymarket API &#038; Kalshi API: Compare 1% Markets to Pinnacle"},"content":{"rendered":"<p>You want Polymarket and Kalshi prices in Python, next to a sportsbook line you trust. Polymarket gives you two read APIs (Gamma for the catalogue, CLOB for the order book) that quote share prices. Kalshi gives you a third API that quotes cents. Neither one tells you what Pinnacle or bet365 says about the same fixture.<\/p>\n<p>OddsPapi carries both venues as bookmakers. One key and one <code>\/v4\/odds<\/code> call return <code>polymarket<\/code>, <code>polymarket.us<\/code>, <code>kalshi<\/code>, Pinnacle and 350+ sportsbooks in decimal odds, with the order book attached. This guide measures what that gets you, then shows the code.<\/p>\n<p>We measured 88 upcoming fixtures on 13 October 2026 (13:11 to 13:20 UTC): 10 random fixtures each from soccer, basketball, tennis, baseball, ice hockey and CS2, 9 college football games, 5 MMA bouts and all 14 NFL Week 6 games. On the winner market, the two prediction markets ran a median margin near 1%. Pinnacle ran 4.02%.<\/p>\n<h2>Polymarket and Kalshi Next to the Sportsbooks: 88 Fixtures<\/h2>\n<figure class=\"wp-block-table\">\n<table style=\"border-collapse: collapse; width: 100%;\">\n<thead>\n<tr style=\"background-color: #f4f4f4; text-align: left;\">\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Venue (slug)<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Two-way winner prices<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Median margin<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Thinner side, top <code>limit<\/code> (all \/ NFL)<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">De-vigged gap to Pinnacle<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><code>polymarket<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">54<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">1.00%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">$221 \/ $1,830<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">0.59 pts<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><code>polymarket.us<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">55<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">0.99%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">$0 \/ $0<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">0.59 pts<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><code>kalshi<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">57<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">1.02%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">$501 \/ $13,067<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">0.75 pts<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><code>pinnacle<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">60<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">4.02%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">758 \/ 6,000<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">reference<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><code>bet365<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">46<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">6.70%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">not published<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">0.83 pts<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>Read the table in three passes:<\/p>\n<ul>\n<li><strong>Margin.<\/strong> Polymarket and Kalshi quote the winner market at about a quarter of Pinnacle&#8217;s overround. That holds sport by sport on NFL (1.00% vs 3.22%), MMA (1.01% vs 3.88%) and baseball (1.00-1.01% vs 3.14%).<\/li>\n<li><strong>Depth.<\/strong> On the NFL, Kalshi&#8217;s thinner side held a median $13,067 at the top of the book, and Polymarket held $1,830. Across all 88 fixtures those medians fall to $501 and $221. <code>polymarket.us<\/code> quotes the tightest NFL prices (0.26% median margin) and ships <code>limit: 0<\/code>, so treat it as a price signal, not a fill.<\/li>\n<li><strong>Agreement.<\/strong> Strip the margin out of each venue and compare the fair probabilities. Polymarket sat a median 0.59 points from Pinnacle, Kalshi 0.75 and bet365 0.83. The prediction markets price the same fixture the sharp book does, at a lower margin.<\/li>\n<\/ul>\n<p>The NFL Week 6 board had all five venues on 13 of 14 games and four venues on the fourteenth. On the other sports the mix changes fixture by fixture, so the code below checks for each venue before it reads a price.<\/p>\n<h2>Direct APIs vs One OddsPapi Call<\/h2>\n<figure class=\"wp-block-table\">\n<table style=\"border-collapse: collapse; width: 100%;\">\n<thead>\n<tr style=\"background-color: #f4f4f4; text-align: left;\">\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Feature<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Polymarket direct<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Kalshi direct<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">OddsPapi<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Sources<\/strong><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Polymarket<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Kalshi<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong><code>polymarket<\/code>, <code>polymarket.us<\/code>, <code>kalshi<\/code> + 350+ sportsbooks<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Price format<\/strong><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">$0.00-$1.00 shares<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">1-99 cent contracts<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Decimal odds, with the native <code>cents<\/code> kept<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Read auth<\/strong><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">None for Gamma and CLOB reads<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">None for public market reads<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>One API key<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Fixture matching<\/strong><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Map event slugs yourself<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Map tickers yourself<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>One <code>fixtureId<\/code> across every venue<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Order book<\/strong><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">CLOB <code>\/book<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><code>\/markets\/{ticker}\/orderbook<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>3 levels per side in <code>exchangeMeta<\/code><\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Sportsbook benchmark<\/strong><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Second API<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Second API<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Same response<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong>Price history<\/strong><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">CLOB <code>\/prices-history<\/code><\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Per-market candlesticks<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\"><strong><code>\/v4\/historical-odds<\/code>, free tier<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>If you need Polymarket&#8217;s raw JSON, the <a href=\"https:\/\/oddspapi.io\/blog\/polymarket-api-gamma-clob-json-format\/\">Gamma vs CLOB field guide<\/a> walks through both payloads. For a feature-by-feature read of the two venues&#8217; own APIs, see <a href=\"https:\/\/oddspapi.io\/blog\/kalshi-vs-polymarket-api\/\">Kalshi API vs Polymarket API<\/a>.<\/p>\n<h2>Step 1: Authenticate and Discover Fixtures<\/h2>\n<p>The key goes in the query string as <code>apiKey<\/code>, never in a header. The helper below honours the <code>retryMs<\/code> hint that a 429 response carries, so a rate limit does not read as &#8220;no data&#8221;.<\/p>\n<pre class=\"wp-block-code\"><code>import os, time, requests\n\nAPI_KEY = os.environ[\"ODDSPAPI_API_KEY\"]\nBASE_URL = \"https:\/\/api.oddspapi.io\/v4\"\n\ndef get(path, **params):\n    params[\"apiKey\"] = API_KEY\n    for _ in range(5):\n        r = requests.get(f\"{BASE_URL}\/{path}\", params=params, timeout=60)\n        if r.status_code == 429:  # honour the retry hint in the body\n            time.sleep(r.json()[\"error\"].get(\"retryMs\", 1500) \/ 1000 + 0.2)\n            continue\n        r.raise_for_status()\n        time.sleep(1.0)\n        return r.json()\n    raise RuntimeError(f\"rate limited on {path}\")\n\n# NFL is sportId 14, tournamentId 31. \"to\" is the day AFTER the last day you want.\nfixtures = get(\"fixtures\", sportId=14, tournamentId=31,\n               **{\"from\": \"2026-10-18\", \"to\": \"2026-10-19\"})\nfor f in fixtures[:4]:\n    print(f[\"fixtureId\"], f[\"participant1Name\"], \"v\", f[\"participant2Name\"], f[\"startTime\"])<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>id1400003171488626 Jacksonville Jaguars v Houston Texans 2026-10-18T13:30:00.000Z\nid1400003171515902 Atlanta Falcons v Chicago Bears 2026-10-18T17:00:00.000Z\nid1400003171515904 Cleveland Browns v Baltimore Ravens 2026-10-18T17:00:00.000Z\nid1400003171515906 Indianapolis Colts v Tennessee Titans 2026-10-18T17:00:00.000Z<\/code><\/pre>\n<h2>Step 2: Fetch Polymarket, Kalshi, Pinnacle and bet365 in One Call<\/h2>\n<p>Pass the venues you want in <code>bookmakers<\/code>. Every price arrives as decimal odds. Market <code>141<\/code> is the NFL winner including overtime; outcome <code>141<\/code> is participant 1 (the home side, Kansas City here) and <code>142<\/code> is participant 2.<\/p>\n<pre class=\"wp-block-code\"><code># get() is the helper from Step 1\n\nFIXTURE = \"id1400003171515918\"  # Kansas City Chiefs v Los Angeles Chargers\nVENUES = [\"polymarket\", \"kalshi\", \"pinnacle\", \"bet365\"]\nWINNER = \"141\"  # NFL Winner (incl. overtime): outcome 141 = participant 1, 142 = participant 2\n\ndata = get(\"odds\", fixtureId=FIXTURE, bookmakers=\",\".join(VENUES))\n\ndef winner_prices(book):\n    market = data[\"bookmakerOdds\"].get(book, {}).get(\"markets\", {}).get(WINNER)\n    if not market:\n        return None\n    out = {}\n    for oid, outcome in market[\"outcomes\"].items():\n        p = outcome[\"players\"].get(\"0\")\n        if not p or not p.get(\"active\"):\n            return None  # one side suspended: no two-way price\n        out[oid] = (p[\"price\"], p.get(\"limit\"))\n    return out\n\nfor book in VENUES:\n    w = winner_prices(book)\n    if not w:\n        print(f\"{book:11s} no active two-way price\")\n        continue\n    margin = (sum(1 \/ price for price, _ in w.values()) - 1) * 100\n    legs = \"  \".join(f\"{oid}: {price:.3f} (limit {limit})\" for oid, (price, limit) in sorted(w.items()))\n    print(f\"{book:11s} {legs}  margin {margin:.2f}%\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>polymarket  141: 1.266 (limit 3436.5)  142: 4.545 (limit 3592.25)  margin 0.99%\nkalshi      141: 1.266 (limit 90776.47)  142: 4.762 (limit 106.41)  margin -0.01%\npinnacle    141: 1.239 (limit 18828.0)  142: 4.340 (limit 4500.0)  margin 3.75%\nbet365      141: 1.200 (limit None)  142: 4.350 (limit None)  margin 6.32%<\/code><\/pre>\n<p>Kalshi&#8217;s margin reads -0.01%. Its two sides cost 79 and 21 cents, 100 cents together, so the margin rounds to zero before any trading fee. The thin side holds about $106. Size a near-zero margin before you call it an arbitrage.<\/p>\n<h2>Step 3: Read the Order Book in exchangeMeta<\/h2>\n<p>Each prediction-market price carries a 3-level <code>back<\/code> and <code>lay<\/code> ladder. Sportsbooks ship <code>exchangeMeta: null<\/code>, so guard with <code>or {}<\/code>.<\/p>\n<pre class=\"wp-block-code\"><code># get() is the helper from Step 1\n\nFIXTURE = \"id1400003171515918\"\ndata = get(\"odds\", fixtureId=FIXTURE, bookmakers=\"polymarket,kalshi\")\n\nfor book in (\"polymarket\", \"kalshi\"):\n    outcome = data[\"bookmakerOdds\"][book][\"markets\"][\"141\"][\"outcomes\"][\"141\"]\n    meta = outcome[\"players\"][\"0\"].get(\"exchangeMeta\") or {}\n    print(book)\n    for side in (\"back\", \"lay\"):\n        for lvl in meta.get(side, []):\n            check = lvl[\"size\"] * lvl[\"cents\"]  # stake = payout x share price\n            print(f\"  {side:4s} price {lvl['price']:.3f}  cents {lvl['cents']:.3f}  \"\n                  f\"size {lvl['size']:&gt;10,.2f}  limit {lvl['limit']:&gt;10,.2f}  size*cents {check:&gt;10,.2f}\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>polymarket\n  back price 1.266  cents 0.790  size   4,350.00  limit   3,436.50  size*cents   3,436.50\n  back price 1.250  cents 0.800  size  37,076.40  limit  29,661.12  size*cents  29,661.12\n  back price 1.235  cents 0.810  size   9,739.27  limit   7,888.81  size*cents   7,888.81\n  lay  price 4.545  cents 0.220  size  16,328.42  limit   3,592.25  size*cents   3,592.25\n  lay  price 4.348  cents 0.230  size  12,492.24  limit   2,873.22  size*cents   2,873.22\n  lay  price 4.167  cents 0.240  size   7,718.00  limit   1,852.32  size*cents   1,852.32\nkalshi\n  back price 1.266  cents 0.790  size 114,906.92  limit  90,776.47  size*cents  90,776.47\n  back price 1.250  cents 0.800  size 349,245.85  limit 279,396.68  size*cents 279,396.68\n  back price 1.235  cents 0.810  size 515,317.73  limit 417,407.36  size*cents 417,407.36\n  lay  price 4.545  cents 0.220  size 333,559.99  limit  73,383.20  size*cents  73,383.20\n  lay  price 4.348  cents 0.230  size  43,800.53  limit  10,074.12  size*cents  10,074.12\n  lay  price 4.167  cents 0.240  size   2,733.16  limit     655.96  size*cents     655.96<\/code><\/pre>\n<ul>\n<li><strong><code>price<\/code><\/strong>: decimal odds for that level.<\/li>\n<li><strong><code>cents<\/code><\/strong>: the native share price, 0.79 = 79% implied.<\/li>\n<li><strong><code>size<\/code><\/strong>: the payout available at that level.<\/li>\n<li><strong><code>limit<\/code><\/strong>: the stake that takes it. <code>limit = size \u00d7 cents<\/code> held on all 12 levels above.<\/li>\n<\/ul>\n<p>The headline price is not always the deep one. Kalshi held $90,776 at 1.266 on Kansas City, while Polymarket held $3,437 at the same price and $29,661 one tick worse at 1.250. The <a href=\"https:\/\/oddspapi.io\/blog\/nfl-prediction-market-liquidity\/\">NFL depth-ladder study<\/a> ranks seven venues on this.<\/p>\n<h2>Step 4: De-Vig Both Venues Before You Compare<\/h2>\n<p>A raw price comparison flags every Polymarket quote as an edge, because Polymarket runs about 1% margin and Pinnacle about 4%. Take the margin out of Pinnacle first, then price each venue against that fair line. The function below also drops suspended sides and prices older than 24 hours.<\/p>\n<pre class=\"wp-block-code\"><code>from datetime import datetime, timezone\n# get() is the helper from Step 1\n\nFIXTURE = \"id1400003171515918\"\nVENUES = [\"polymarket\", \"polymarket.us\", \"kalshi\", \"pinnacle\", \"bet365\"]\nWINNER = \"141\"\ndata = get(\"odds\", fixtureId=FIXTURE, bookmakers=\",\".join(VENUES))\nnow = datetime.now(timezone.utc)\n\ndef two_way(book, max_age_h=24):\n    \"\"\"Active, fresh, two-sided winner prices for one venue, or None.\"\"\"\n    market = data[\"bookmakerOdds\"].get(book, {}).get(\"markets\", {}).get(WINNER)\n    if not market:\n        return None\n    legs = {}\n    for oid, outcome in market[\"outcomes\"].items():\n        p = outcome[\"players\"].get(\"0\")\n        if not p or not p.get(\"active\") or p[\"price\"] &lt;= 1:\n            return None\n        age = now - datetime.fromisoformat(p[\"changedAt\"].replace(\"Z\", \"+00:00\"))\n        if age.total_seconds() &gt; max_age_h * 3600:\n            return None  # a withdrawn market keeps its last price\n        legs[oid] = p\n    return legs if len(legs) == 2 else None\n\ndef no_vig(legs):\n    z = sum(1 \/ p[\"price\"] for p in legs.values())\n    return {oid: (1 \/ p[\"price\"]) \/ z for oid, p in legs.items()}\n\npin = two_way(\"pinnacle\")\nfair = no_vig(pin)\nprint(\"Pinnacle no-vig: \" + \"  \".join(f\"{o} {q:.4f}\" for o, q in sorted(fair.items())))\n\nfor book in VENUES:\n    legs = two_way(book)\n    if not legs:\n        print(f\"{book:13s} skipped (no active two-way price)\")\n        continue\n    gap = max(abs(no_vig(legs)[o] - fair[o]) for o in fair) * 100\n    for oid, p in sorted(legs.items()):\n        ev = (p[\"price\"] * fair[oid] - 1) * 100  # expected value against Pinnacle's fair line\n        stake = p.get(\"limit\")\n        flag = \"  &lt;-- beats Pinnacle fair\" if ev &gt; 0 and (stake is None or stake &gt; 0) else \"\"\n        print(f\"{book:13s} {oid} {p['price']:.3f}  EV {ev:+.2f}%  limit {stake}{flag}\")\n    print(f\"{'':13s} de-vigged gap to Pinnacle {gap:.2f} pts\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>Pinnacle no-vig: 141 0.7779  142 0.2221\npolymarket    141 1.266  EV -1.52%  limit 3436.5\npolymarket    142 4.545  EV +0.94%  limit 3592.25  &lt;-- beats Pinnacle fair\n              de-vigged gap to Pinnacle 0.42 pts\npolymarket.us 141 1.262  EV -1.83%  limit 0.0\npolymarket.us 142 4.706  EV +4.51%  limit 0.0\n              de-vigged gap to Pinnacle 1.06 pts\nkalshi        141 1.266  EV -1.52%  limit 90776.47\nkalshi        142 4.762  EV +5.76%  limit 106.41  &lt;-- beats Pinnacle fair\n              de-vigged gap to Pinnacle 1.21 pts\npinnacle      141 1.239  EV -3.62%  limit 18828.0\npinnacle      142 4.340  EV -3.62%  limit 4500.0\n              de-vigged gap to Pinnacle 0.00 pts\nbet365        141 1.200  EV -6.65%  limit None\nbet365        142 4.350  EV -3.39%  limit None\n              de-vigged gap to Pinnacle 0.59 pts<\/code><\/pre>\n<p>Three quotes beat Pinnacle&#8217;s fair price on the Chargers. Only two of them count:<\/p>\n<ul>\n<li><strong><code>kalshi<\/code> +5.76%<\/strong> on $106 of stake. Real, but small.<\/li>\n<li><strong><code>polymarket<\/code> +0.94%<\/strong> on $3,592. Smaller edge, about 34 times the room.<\/li>\n<li><strong><code>polymarket.us<\/code> +4.51%<\/strong> on <code>limit 0.0<\/code>. The script skips it, because nothing stands behind the price.<\/li>\n<\/ul>\n<p>For a cross-book version that dedupes sportsbook feeds and screens out stale quotes across full boards, see the <a href=\"https:\/\/oddspapi.io\/blog\/polymarket-arbitrage-local-bookmakers\/\">Polymarket arbitrage census<\/a>.<\/p>\n<h2>Step 5: Watch Polymarket Move<\/h2>\n<p>Polymarket re-stamps <code>changedAt<\/code> on prices that did not move. Compare the price, not the timestamp, or you count noise as movement.<\/p>\n<pre class=\"wp-block-code\"><code>import time\n# get() is the helper from Step 1\n\nFIXTURE = \"id1400003171515918\"\n\ndef snapshot(book):\n    data = get(\"odds\", fixtureId=FIXTURE, bookmakers=book)\n    snap = {}\n    for mid, market in data[\"bookmakerOdds\"].get(book, {}).get(\"markets\", {}).items():\n        for oid, outcome in market[\"outcomes\"].items():\n            for pid, p in outcome[\"players\"].items():  # props key players by ID, not \"0\"\n                if p.get(\"active\"):\n                    snap[(mid, oid, pid)] = (p[\"price\"], p[\"changedAt\"])\n    return snap\n\ndef poll(book=\"polymarket\", polls=4, interval=30):\n    \"\"\"A bounded poll. Each call costs one request: use the WebSocket for a live loop.\"\"\"\n    prev = snapshot(book)\n    print(f\"{book}: {len(prev)} active prices\")\n    for i in range(1, polls):\n        time.sleep(interval)\n        cur = snapshot(book)\n        moved = [k for k in cur if k in prev and cur[k][0] != prev[k][0]]\n        stamped = [k for k in cur if k in prev and cur[k][0] == prev[k][0] and cur[k][1] != prev[k][1]]\n        print(f\"poll {i}: {len(moved)} prices moved, {len(stamped)} re-stamped at the same price\")\n        for k in moved[:3]:\n            print(f\"  market {k[0]} outcome {k[1]}: {prev[k][0]:.3f} -&gt; {cur[k][0]:.3f}\")\n        prev = cur\n\npoll()<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>polymarket: 504 active prices\npoll 1: 1 prices moved, 17 re-stamped at the same price\n  market 14344 outcome 14345: 23.256 -&gt; 20.833\npoll 2: 1 prices moved, 14 re-stamped at the same price\n  market 14344 outcome 14345: 20.833 -&gt; 19.231\npoll 3: 3 prices moved, 9 re-stamped at the same price\n  market 14344 outcome 14345: 19.231 -&gt; 17.857\n  market 144100 outcome 144100: 1.010 -&gt; 1.020\n  market 14284 outcome 14285: 1.695 -&gt; 1.724<\/code><\/pre>\n<p>Each poll is one request. The free plan gives you 250 requests a month, so a 30-second loop spends it in about two hours. For a live monitor, subscribe to the stream: the <a href=\"https:\/\/oddspapi.io\/blog\/websocket-odds-api-real-time-betting-data\/\">WebSocket guide<\/a> counts what a poll misses between calls.<\/p>\n<h2>Kalshi&#8217;s Own API for Elections, Economics and Weather<\/h2>\n<p>This guide covers sports. Kalshi also lists contracts on the economy, politics and the weather, and its public read endpoint returns them without a key:<\/p>\n<pre class=\"wp-block-code\"><code>import requests\n\n# Kalshi's public read endpoint: no key, no signature\nr = requests.get(\"https:\/\/api.elections.kalshi.com\/trade-api\/v2\/events\",\n                 params={\"status\": \"open\", \"limit\": 200}, timeout=30)\nr.raise_for_status()\nevents = r.json()[\"events\"]\nfor e in events:\n    if e[\"category\"] in (\"Economics\", \"Climate and Weather\"):\n        print(e[\"category\"], \"|\", e[\"event_ticker\"], \"|\", e[\"title\"])\n        break\nprint(len(events), \"open events on this page; categories:\",\n      sorted({e[\"category\"] for e in events}))<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>Climate and Weather | KXWARMING-50 | Will the world pass 2 degrees Celsius over pre-industrial levels before 2050?\n200 open events on this page; categories: ['Climate and Weather', 'Companies', 'Economics', 'Elections', 'Entertainment', 'Financials', 'Health', 'Politics', 'Science and Technology', 'Social', 'Sports', 'World']<\/code><\/pre>\n<h2>Conversion Reference<\/h2>\n<p>OddsPapi hands you decimal odds and keeps the native <code>cents<\/code> field on prediction-market ladders. If you read Polymarket or Kalshi directly, these three lines convert their formats:<\/p>\n<pre class=\"wp-block-code\"><code>def share_to_decimal(share_price):\n    \"\"\"Polymarket $0.56 share -&gt; 1.786 decimal odds\"\"\"\n    return 1 \/ share_price\n\ndef cents_to_decimal(cents):\n    \"\"\"Kalshi 56 cents -&gt; 1.786 decimal odds\"\"\"\n    return 1 \/ (cents \/ 100)\n\ndef american_to_decimal(american):\n    \"\"\"-127 -&gt; 1.787 decimal odds\"\"\"\n    return american \/ 100 + 1 if american &gt; 0 else 100 \/ abs(american) + 1\n\nprint(f\"{share_to_decimal(0.56):.3f} {cents_to_decimal(56):.3f} {american_to_decimal(-127):.3f}\")<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>1.786 1.786 1.787<\/code><\/pre>\n<figure class=\"wp-block-table\">\n<table style=\"border-collapse: collapse; width: 100%;\">\n<thead>\n<tr style=\"background-color: #f4f4f4; text-align: left;\">\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Source format<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Example<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Implied probability<\/th>\n<th style=\"padding: 10px; border: 1px solid #ddd;\">Decimal odds<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Polymarket share<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">$0.56<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">56%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">1.786<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">Kalshi contract<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">56 cents<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">56%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">1.786<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">American odds<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">-127<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">56%<\/td>\n<td style=\"padding: 10px; border: 1px solid #ddd;\">1.787<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>The <a href=\"https:\/\/oddspapi.io\/blog\/polymarket-odds-converter-python\/\">odds converter post<\/a> adds fractional odds and the de-vig maths.<\/p>\n<h2>What You Get From One Key<\/h2>\n<ul>\n<li><strong>350+ bookmakers in one response<\/strong>, including <code>polymarket<\/code>, <code>polymarket.us<\/code>, <code>kalshi<\/code>, Pinnacle and bet365, on one <code>fixtureId<\/code>.<\/li>\n<li><strong>The order book<\/strong>: three levels a side in <code>exchangeMeta<\/code>, with <code>limit<\/code> as the stake you can place.<\/li>\n<li><strong>Free historical odds<\/strong>: <code>\/v4\/historical-odds<\/code> replays the line. For <code>polymarket<\/code>, pass one bookmaker and one <code>outcomeId<\/code> per call; the history carries <code>limit<\/code>, and the ladder is live-only. The <a href=\"https:\/\/oddspapi.io\/blog\/backtest-betting-model-free-historical-odds\/\">backtesting guide<\/a> shows the full loop.<\/li>\n<li><strong>WebSockets<\/strong> for the moves a poll misses.<\/li>\n<\/ul>\n<h2>Frequently Asked Questions<\/h2>\n<p><script type=\"application\/ld+json\">\n{\"@context\":\"https:\/\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[\n{\"@type\":\"Question\",\"name\":\"Do I need a Polymarket wallet to get Polymarket data?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"No. Polymarket's Gamma and CLOB read endpoints need no wallet, and OddsPapi returns the polymarket and polymarket.us slugs with one API key. You need a wallet only to place orders on Polymarket.\"}},\n{\"@type\":\"Question\",\"name\":\"How do Polymarket and Kalshi margins compare to sportsbooks?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"On 88 fixtures measured on 13 October 2026, the median winner-market margin was 1.00% on polymarket, 1.02% on kalshi, 4.02% on Pinnacle and 6.70% on bet365. De-vigged, Polymarket sat a median 0.59 points from Pinnacle's fair probability and Kalshi 0.75.\"}},\n{\"@type\":\"Question\",\"name\":\"What do size and limit mean in exchangeMeta?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"size is the payout available at a ladder level and limit is the stake that takes it. limit equals size times cents, where cents is the native share price. Check limit before you treat a price as fillable.\"}},\n{\"@type\":\"Question\",\"name\":\"Which venue holds more NFL depth, Kalshi or Polymarket?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"On the 14 NFL Week 6 games measured on 13 October 2026, Kalshi's thinner side held a median $13,067 at the top of the book and Polymarket's held $1,830. Pinnacle's thinner side carried a median limit of 6,000.\"}},\n{\"@type\":\"Question\",\"name\":\"Can I get Polymarket price history through OddsPapi?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes. Call \/v4\/historical-odds with bookmakers=polymarket and one outcomeId. Each snapshot carries the price and the top-of-book limit. The three-level ladder is in live responses.\"}}\n]}\n<\/script><\/p>\n<div>\n<h4>Do I need a Polymarket wallet to get Polymarket data?<\/h4>\n<p>No. Polymarket&#8217;s Gamma and CLOB read endpoints need no wallet, and OddsPapi returns the <code>polymarket<\/code> and <code>polymarket.us<\/code> slugs with one API key. You need a wallet only to place orders on Polymarket.<\/p>\n<h4>How do Polymarket and Kalshi margins compare to sportsbooks?<\/h4>\n<p>On 88 fixtures measured on 13 October 2026, the median winner-market margin was 1.00% on <code>polymarket<\/code>, 1.02% on <code>kalshi<\/code>, 4.02% on Pinnacle and 6.70% on bet365. De-vigged, Polymarket sat a median 0.59 points from Pinnacle&#8217;s fair probability and Kalshi 0.75.<\/p>\n<h4>What do size and limit mean in exchangeMeta?<\/h4>\n<p><code>size<\/code> is the payout available at a ladder level and <code>limit<\/code> is the stake that takes it. <code>limit<\/code> equals <code>size \u00d7 cents<\/code>, where <code>cents<\/code> is the native share price. Check <code>limit<\/code> before you treat a price as fillable.<\/p>\n<h4>Which venue holds more NFL depth, Kalshi or Polymarket?<\/h4>\n<p>On the 14 NFL Week 6 games measured on 13 October 2026, Kalshi&#8217;s thinner side held a median $13,067 at the top of the book and Polymarket&#8217;s held $1,830. Pinnacle&#8217;s thinner side carried a median limit of 6,000.<\/p>\n<h4>Can I get Polymarket price history through OddsPapi?<\/h4>\n<p>Yes. Call <code>\/v4\/historical-odds<\/code> with <code>bookmakers=polymarket<\/code> and one <code>outcomeId<\/code>. Each snapshot carries the price and the top-of-book <code>limit<\/code>. The three-level ladder is in live responses.<\/p>\n<\/div>\n<h2>Start With Your Own Fixture<\/h2>\n<p>Swap the fixture ID in Step 2 for any game on your slate. If <code>polymarket<\/code> or <code>kalshi<\/code> is missing from the response, that venue has not listed the fixture yet; the code skips it and keeps the rest.<\/p>\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link\" href=\"https:\/\/oddspapi.io\/en\/sign-up\">Get your free OddsPapi API key<\/a><\/div>\n<p><!--\nFocus Keyphrase: polymarket api\nSEO Title: Polymarket API & Kalshi API: Compare 1% Markets to Pinnacle\nMeta Description: Polymarket API and Kalshi prices in one OddsPapi call. On NFL Week 6, Kalshi's thinner side held a median $13,067 at the top of the book, Polymarket $1,830.\nSlug: polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Polymarket API and Kalshi prices in one OddsPapi call. On NFL Week 6, Kalshi&#8217;s thinner side held a median $13,067 at the top of the book, Polymarket $1,830.<\/p>\n","protected":false},"author":2,"featured_media":98,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[108,52,9,14,34,11],"class_list":["post-97","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to-guides","tag-kalshi","tag-nfl","tag-odds-api","tag-polymarket","tag-prediction-markets","tag-python"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Polymarket API &amp; Kalshi API: Compare 1% Markets to Pinnacle | 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\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Polymarket API &amp; Kalshi API: Compare 1% Markets to Pinnacle | OddsPapi Blog\" \/>\n<meta property=\"og:description\" content=\"Polymarket API and Kalshi prices in one OddsPapi call. On NFL Week 6, Kalshi&#039;s thinner side held a median $13,067 at the top of the book, Polymarket $1,830.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"OddsPapi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-02T15:50:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-13T13:23:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"1408\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\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=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/\"},\"author\":{\"name\":\"Odds API Writer\",\"@id\":\"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13\"},\"headline\":\"Polymarket API &#038; Kalshi API: Compare 1% Markets to Pinnacle\",\"datePublished\":\"2026-01-02T15:50:05+00:00\",\"dateModified\":\"2026-10-13T13:23:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/\"},\"wordCount\":1217,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg\",\"keywords\":[\"Kalshi\",\"NFL\",\"Odds API\",\"Polymarket\",\"Prediction Markets\",\"Python\"],\"articleSection\":[\"How To Guides\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/\",\"url\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/\",\"name\":\"Polymarket API & Kalshi API: Compare 1% Markets to Pinnacle | OddsPapi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg\",\"datePublished\":\"2026-01-02T15:50:05+00:00\",\"dateModified\":\"2026-10-13T13:23:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage\",\"url\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg\",\"contentUrl\":\"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg\",\"width\":1408,\"height\":768},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oddspapi.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Polymarket API &#038; Kalshi API: Compare 1% Markets to Pinnacle\"}]},{\"@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":"Polymarket API & Kalshi API: Compare 1% Markets to Pinnacle | 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\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/","og_locale":"en_US","og_type":"article","og_title":"Polymarket API & Kalshi API: Compare 1% Markets to Pinnacle | OddsPapi Blog","og_description":"Polymarket API and Kalshi prices in one OddsPapi call. On NFL Week 6, Kalshi's thinner side held a median $13,067 at the top of the book, Polymarket $1,830.","og_url":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/","og_site_name":"OddsPapi Blog","article_published_time":"2026-01-02T15:50:05+00:00","article_modified_time":"2026-10-13T13:23:51+00:00","og_image":[{"width":1408,"height":768,"url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg","type":"image\/jpeg"}],"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":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#article","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/"},"author":{"name":"Odds API Writer","@id":"https:\/\/oddspapi.io\/blog\/#\/schema\/person\/b6f21e649c4f556f0a95c23a0f1efa13"},"headline":"Polymarket API &#038; Kalshi API: Compare 1% Markets to Pinnacle","datePublished":"2026-01-02T15:50:05+00:00","dateModified":"2026-10-13T13:23:51+00:00","mainEntityOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/"},"wordCount":1217,"commentCount":0,"publisher":{"@id":"https:\/\/oddspapi.io\/blog\/#organization"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg","keywords":["Kalshi","NFL","Odds API","Polymarket","Prediction Markets","Python"],"articleSection":["How To Guides"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/","url":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/","name":"Polymarket API & Kalshi API: Compare 1% Markets to Pinnacle | OddsPapi Blog","isPartOf":{"@id":"https:\/\/oddspapi.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage"},"image":{"@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage"},"thumbnailUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg","datePublished":"2026-01-02T15:50:05+00:00","dateModified":"2026-10-13T13:23:51+00:00","breadcrumb":{"@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#primaryimage","url":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg","contentUrl":"https:\/\/oddspapi.io\/blog\/wp-content\/uploads\/2026\/01\/prediction-market-apis-vs-sportsbooks.jpeg","width":1408,"height":768},{"@type":"BreadcrumbList","@id":"https:\/\/oddspapi.io\/blog\/polymarket-api-kalshi-api-vs-sportsbooks-the-developers-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oddspapi.io\/blog\/"},{"@type":"ListItem","position":2,"name":"Polymarket API &#038; Kalshi API: Compare 1% Markets to Pinnacle"}]},{"@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\/97","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=97"}],"version-history":[{"count":9,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/97\/revisions"}],"predecessor-version":[{"id":5024,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/posts\/97\/revisions\/5024"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media\/98"}],"wp:attachment":[{"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/media?parent=97"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/categories?post=97"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oddspapi.io\/blog\/wp-json\/wp\/v2\/tags?post=97"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}