Prediction markets · 7 September 2026 · updated 26 October 2026

Kalshi and Polymarket Prices Next to Australian Bookmakers

Kalshi and Polymarket sit beside the sportsbooks in the same response, on the same markets and outcomes.

Prediction markets price sports outcomes too. In SockOdds API v1, Kalshi and Polymarket are delivered the same way as any bookmaker: each has a bookmaker key (kalshi and polymarket), and their prices land on the same markets and outcomes as the sportsbooks' prices. One request returns a Polymarket price and a TAB price on the same team, side by side in that outcome's prices.

How they are described

GET /v1/bookmakers gives every source a kind: sportsbook, exchange or prediction_market. Kalshi and Polymarket are prediction_market, and Betfair Exchange is an exchange. Use kind if your app needs to show or treat them differently.

Prices are decimal, like everyone else's

A prediction market quotes a contract, but v1 returns every price as decimal_odds, with implied_probability beside it (one divided by the decimal price), the source's key in bookmaker and the time SockOdds saw it in observed_at. You read a Kalshi price with exactly the same code as a Sportsbet price:

curl -sS "https://api.sockodds.com/v1/events/ev_000ckk0nc1tg/odds?bookmakers=kalshi&markets=winner" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/events/ev_000ckk0nc1tg/odds?bookmakers=kalshi&markets=winner", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/events/ev_000ckk0nc1tg/odds?bookmakers=kalshi&markets=winner",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    print(json.dumps(json.load(response), indent=2))

Response from a local copy of the API with invented test prices

{
  "data": {
    "id": "ev_000ckk0nc1tg",
    "name": "Abilene Christian Wildcats v Air Force Falcons",
    "league": {
      "key": "ncaaf",
      "name": "College football"
    },
    "scheduled_start": "2026-10-16T19:00:00.000Z",
    "status": "scheduled",
    "participants": [
      {
        "role": "away",
        "identity": {
          "key": "air_force_falcons",
          "name": "Air Force Falcons"
        }
      },
      {
        "role": "home",
        "identity": {
          "key": "abilene_christian_wildcats",
          "name": "Abilene Christian Wildcats"
        }
      }
    ],
    "markets": [
      {
        "id": "mk_qpcfjj74vm67qng3",
        "key": "winner",
        "name": "Winner",
        "period": "full",
        "subject": null,
        "alternate": false,
        "outcomes": [
          {
            "id": "oc_2eq7ejh9tvepckre",
            "name": "Abilene Christian Wildcats",
            "side": "home",
            "line": null,
            "prices": [
              {
                "bookmaker": "kalshi",
                "decimal_odds": 1.69,
                "implied_probability": 0.591716,
                "available": true,
                "observed_at": "2026-10-15T07:58:00.000Z"
              }
            ]
          },
          {
            "id": "oc_43ctd7dv6hy4dqjz",
            "name": "Air Force Falcons",
            "side": "away",
            "line": null,
            "prices": [
              {
                "bookmaker": "kalshi",
                "decimal_odds": 2.08,
                "implied_probability": 0.480769,
                "available": true,
                "observed_at": "2026-10-15T07:58:00.000Z"
              }
            ]
          }
        ]
      }
    ]
  },
  "meta": {
    "count": 1,
    "cursor": null
  },
  "links": {
    "next": null
  }
}

Compare a prediction market with sportsbooks

Because every source shares one market and outcome scheme, each outcome lists every source's price, and a comparison is a loop. This program asks for the three-way result on a Bundesliga game from Polymarket, Betfair Exchange and TAB, regroups the prices by source key, and prints each source's prices with its margin: the amount by which its implied probabilities add up to more than 100%.

const response = await fetch("https://api.sockodds.com/v1/events/ev_000ckk0p5g0q/odds?bookmakers=polymarket,betfair_exchange,tab&markets=result", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
const event = (await response.json()).data;
console.log(event.name);
// Regroup the market's prices by source: each source's own price on every outcome.
const sources = new Map();
for (const outcome of event.markets[0].outcomes) {
  for (const price of outcome.prices) {
    if (!sources.has(price.bookmaker)) sources.set(price.bookmaker, []);
    sources.get(price.bookmaker).push({ name: outcome.name, decimal_odds: price.decimal_odds });
  }
}
for (const [bookmaker, outcomes] of sources) {
  const total = outcomes.reduce((sum, o) => sum + 1 / o.decimal_odds, 0);
  const prices = outcomes.map((o) => `${o.name} ${o.decimal_odds.toFixed(2)}`).join(", ");
  console.log(`${bookmaker}: ${prices} (margin ${((total - 1) * 100).toFixed(1)}%)`);
}
import json, os, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/events/ev_000ckk0p5g0q/odds?bookmakers=polymarket,betfair_exchange,tab&markets=result",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
with urllib.request.urlopen(request) as response:
    event = json.load(response)["data"]
print(event["name"])
# Regroup the market's prices by source: each source's own price on every outcome.
sources = {}
for outcome in event["markets"][0]["outcomes"]:
    for price in outcome["prices"]:
        sources.setdefault(price["bookmaker"], []).append({"name": outcome["name"], "decimal_odds": price["decimal_odds"]})
for bookmaker, outcomes in sources.items():
    total = sum(1 / o["decimal_odds"] for o in outcomes)
    prices = ", ".join(f"{o['name']} {o['decimal_odds']:.2f}" for o in outcomes)
    print(f"{bookmaker}: {prices} (margin {(total - 1) * 100:.1f}%)")

Output from a local copy of the API with invented test prices

Bayer Leverkusen v Bayern Munich
tab: Bayer Leverkusen 2.05, Draw 3.40, Bayern Munich 3.60 (margin 6.0%)
betfair_exchange: Bayer Leverkusen 2.01, Draw 3.33, Bayern Munich 3.53 (margin 8.1%)
polymarket: Bayer Leverkusen 1.97, Draw 3.26, Bayern Munich 3.46 (margin 10.3%)

The prices above come from a local copy of the API with invented numbers, so do not read anything into which source looks cheaper. On real data, a gap between a prediction market and a bookmaker is a signal to look closer, not a sure thing: prices move, liquidity on a contract can be thin, and bookmakers may limit accounts.

Where they price

As of 30 October 2026, Kalshi delivered prices for bundesliga, epl, la_liga, ligue_1, mlb, mls, nba, ncaaf, nfl, nhl and serie_a, and Polymarket for bundesliga, epl, la_liga, ligue_1, mlb, mls, nba, ncaaf, nfl and nhl. The Kalshi and Polymarket pages show the current list, and the prediction market API page has more on using them.

Prediction markets are included on the Pro plan; pricing lists the bookmakers on each plan. SockOdds is independent and is not affiliated with Kalshi or Polymarket.

Search across the SockOdds documentation and catalogue.