Betting Exchange

Polymarket Odds API

Polymarket prices through the SportsGameOdds API, keyed to the same oddID as every sportsbook we carry. Comparing a prediction market contract against 85+ books is one request rather than an integration project.

Polymarket runs on order flow rather than a bookmaker's opinion. A price moves because someone took the other side of it, which makes the number a running poll of people with money at stake instead of a line a trading desk decided to publish.

That is useful precisely because it is produced differently from everything else in the feed.

You can get this data yourself, and that is the point

Polymarket runs a public order book API. Anyone can query it, for free, without asking us. So the honest question for this page is not whether the data is available. It is what you sign up for by going direct.

Three things, roughly. Polymarket contracts are not shaped like sportsbook markets, so you have to map a contract onto the event and market it corresponds to. Prices arrive as probabilities rather than American odds, so you convert before you can compare. And a contract that resolves on a slightly different condition than the sportsbook market you are comparing it against is not the same bet, so outcome matching is a real problem rather than a string join.

Then you do it again for Kalshi. Then again for every book you want on the other side of the comparison, each with its own market naming.

What this API sells is that work already done. Polymarket arrives keyed to the same oddID as DraftKings and Pinnacle, inside the same byBookmaker object, in the same odds format.

What Polymarket coverage looks like

Polymarket prices are returned under polymarket in byBookmaker, alongside the sportsbooks pricing the same market. Coverage concentrates on outcomes with enough liquidity to hold a market: game winners in the major US leagues, and the higher-profile player markets such as anytime touchdown scorers.

An exchange only has a price where someone is willing to trade, so coverage is thinner and less predictable than a sportsbook's. Read byBookmaker on each odd rather than assuming Polymarket is on a given market, and treat its absence as normal rather than as an error.

Polymarket is included on the Rookie plan and above. The free Amateur tier carries a shorter book list that does not include it, so a request filtered to polymarket on that plan returns an empty result rather than failing. Pricing lists the books on each tier.

Requesting Polymarket prices

Filter to Polymarket alone with bookmakerID=polymarket:

curl "https://api.sportsgameodds.com/v2/events?leagueID=NFL&bookmakerID=polymarket&oddsAvailable=true" \
  -H "x-api-key: YOUR_API_KEY"

In practice you almost always want something to compare against, which is the same request with more books:

curl "https://api.sportsgameodds.com/v2/events?leagueID=NFL&bookmakerID=polymarket,kalshi,pinnacle,draftkings&oddsAvailable=true" \
  -H "x-api-key: YOUR_API_KEY"

One call, one schema, both prediction markets and two sportsbooks on the same oddID.

What a Polymarket price looks like

{
  "eventID": "...",
  "leagueID": "NFL",
  "odds": {
    "points-home-game-ml-home": {
      "oddID": "points-home-game-ml-home",
      "marketName": "Moneyline",
      "statID": "points",
      "statEntityID": "home",
      "periodID": "game",
      "betTypeID": "ml",
      "sideID": "home",
      "fairOdds": "-142",
      "bookOdds": "-148",
      "byBookmaker": {
        "polymarket": { "odds": "-138", "available": true },
        "kalshi": { "odds": "-144", "available": true },
        "draftkings": { "odds": "-155", "available": true }
      }
    }
  }
}

Odds are strings, so -138 arrives as "-138" and the plus sign survives on an underdog. fairOdds is the vig-free consensus across every book on that market and bookOdds keeps the margin in, so you have a benchmark without computing one.

The spread in that example is the whole reason to carry an exchange. DraftKings is at -155 and Polymarket at -138 on the same outcome, and neither number is wrong. They are two mechanisms disagreeing.

Polymarket and Kalshi

Both are exchanges and both arrive in the same shape, so the temptation is to treat them as one source. They are not. Liquidity and participants differ, which means they can price the same outcome differently, and the gap between two exchanges is its own signal separate from the gap between an exchange and a book.

If you are building anything that arbitrages or benchmarks against prediction markets, carry both. The Kalshi Odds API page covers what that feed returns, and the prediction market API page covers how we handle the category as a whole.

Use cases for Polymarket data

Prediction market arbitrage is the direct one. When an exchange contract and a sportsbook line on the same outcome imply different probabilities, that difference is actionable, and finding it needs both prices in one schema on the same oddID. See prediction market arbitrage.

For positive EV work, an exchange price is a useful second opinion on your own fair number, because it is not derived from the same book consensus your model is probably already trained on.

Odds comparison tools can show a prediction market price next to sportsbook prices for the same outcome, which is a genuinely different product from comparing eight books that mostly agree with each other.

Polymarket API technical specifications

Polymarket comes through the standard /v2/events endpoint with no separate call, credential or schema. Billing is per event object rather than per book, so adding Polymarket to a request you were making anyway costs response size and nothing more.

Odds refresh sub-minute on Pro, with longer intervals on Rookie. The API documentation covers authentication, pagination and the full parameter list, and handling odds covers reading byBookmaker in code.

Frequently asked questions

What is the bookmakerID for Polymarket?
polymarket, in lowercase. Pass bookmakerID=polymarket to /v2/events and read the price from byBookmaker.polymarket on each odd. Build against the ID rather than the display name, since the two do not always match across books.
Which plans include Polymarket?
Rookie and above. The free Amateur tier carries a shorter book list that does not include Polymarket, so filtering a request to bookmakerID=polymarket on that plan returns an empty result rather than an error.
Why use this API when Polymarket has a public one?
Because the raw feed is the easy part. Going direct means mapping Polymarket contracts onto the events and markets they correspond to, converting probabilities into the odds format the rest of your data uses, and confirming a contract resolves on the same condition as the sportsbook market you are comparing it with. Then repeating that for every other source you want alongside it. Here Polymarket arrives under the same oddID as every sportsbook, already converted.
Which markets does Polymarket price?
Coverage concentrates where there is enough liquidity to hold a market, mainly game winners in the major US leagues and higher-profile player markets such as anytime touchdown scorers. An exchange only has a price where someone will trade, so coverage is thinner and less predictable than a sportsbook's. Check byBookmaker on each odd rather than assuming a market is there.
How do Polymarket and Kalshi differ in the API?
They do not differ structurally. Both are exchanges, both arrive under byBookmaker keyed by their bookmakerID, and both use the same odds format as the sportsbooks. What differs is the price, because liquidity and participants are not the same, so the two can disagree on the same outcome. That disagreement is worth carrying rather than collapsing into one source.
Are Polymarket prices returned as probabilities or as odds?
As odds, in the same format and the same string type as every sportsbook in the response. The conversion happens before the data reaches you, so a prediction market price and a sportsbook price on the same oddID are directly comparable without a normalisation step in your code.

Put an exchange price next to the book price

Polymarket, Kalshi and every sportsbook we carry on the same oddID, in one request.