# Polymarket API for sports: player over/unders as odds

Polymarket publishes free official APIs for market data and trading. GetOdds reads Polymarket's NBA player over/under markets from its live market feed, converts each side's best ask to implied probability, American and decimal odds, and lines it up against BetRivers sportsbook prices for the same player, stat and line, with 14 days of price changes and an MCP tool, at /api/v1/prediction-markets?source=polymarket.

Canonical page: https://getoddsapi.com/polymarket-api

**Price.** Free development allowance: 1,000 requests per UTC day and 60 per minute per account, with no payment step. Paid: the Developer Bundle at $149 per month, with 10,000 monthly requests or credits on each of four sources. Prediction-market reads count against the same allowance and need no extra grant.

## Free API key

Get a free GetOdds API key: **1,000 requests per UTC day and 60 per minute, no card**. One key covers REST and the hosted MCP server.

Sign up: https://getoddsapi.com/sign-up?ref=ai-claudebot

## Quickstart

1. Create an account at https://getoddsapi.com/sign-up?ref=ai-claudebot, open https://getoddsapi.com/dashboard and issue a key with the sources you need (draftkings, fanduel, betrivers, prizepicks or underdog). Keep it in a server environment variable named GETODDS_API_KEY.
2. Read current DraftKings NBA spreads with curl:

```bash
curl --fail-with-body "https://getoddsapi.com/api/v1/odds?sport=NBA&market=spread&fresh_only=true&limit=50" \
  -H "Authorization: Bearer $GETODDS_API_KEY"
```

3. The same request in Python (standard library only):

```python
import json, os, urllib.request

req = urllib.request.Request(
    "https://getoddsapi.com/api/v1/odds?sport=NBA&market=spread&fresh_only=true&limit=50",
    headers={"Authorization": "Bearer " + os.environ["GETODDS_API_KEY"]},
)
with urllib.request.urlopen(req) as res:
    rows = json.load(res)["data"]
for row in rows:
    print(row["away"], "at", row["home"], row["side"], row["line"], row["american"], row["observed_at"])
```

4. Check `observed_at`, `age_seconds` and `stale` on every row before using a price. Full reference: https://getoddsapi.com/docs

## Use with Claude (MCP)

```bash
claude mcp add --transport http getodds https://getoddsapi.com/api/mcp \
  --header "Authorization: Bearer $GETODDS_API_KEY"
```

The MCP tools follow the key's source grants and share its allowance. Setup guide: https://getoddsapi.com/use-with-claude

## Pricing

| Plan | Allowance | Price |
| --- | --- | --- |
| Free key | 1,000 requests a day, 60 a minute | $0, no card |
| Developer Bundle | 10,000 requests or credits a month on each of four sources | $149 a month |

Free development allowance: 1,000 requests per UTC day and 60 per minute per account, with no payment step. Paid: the Developer Bundle at $149 per month, with 10,000 monthly requests or credits on each of four sources.
Details: https://getoddsapi.com/bundle

## Facts

- **Endpoint:** /api/v1/prediction-markets
- **Markets:** Player over/under
- **Price basis:** Best ask per $1 share
- **History:** 14 days of changes

## Read Polymarket player props

Create an account at /sign-up and issue a key in /dashboard. Prediction-market reads work on every key, with no extra source grant. Keep the key in a server environment variable named GETODDS_API_KEY and send it as a bearer token, never in a URL or browser code.

Polymarket rows use Polymarket's own event IDs and event titles. Only markets whose question states a single player and an explicit over/under line are stored, so every row maps cleanly to a sportsbook-style prop.

```bash
curl --fail-with-body "https://getoddsapi.com/api/v1/prediction-markets?source=polymarket&league=NBA&limit=100" \
  -H "Authorization: Bearer $GETODDS_API_KEY"

curl --fail-with-body "https://getoddsapi.com/api/v1/prediction-markets?source=polymarket&stat=Rebounds&limit=50" \
  -H "Authorization: Bearer $GETODDS_API_KEY"
```

## How Polymarket prices are read

Prices come from Polymarket's public market WebSocket, as the best ask per outcome. Cached prices from Polymarket's market listing API are never used as a live quote. A share pays $1 if its side wins, so the ask reads directly as an implied probability. GetOdds adds American and decimal conversions and the venue no-vig probability when both sides are stored.

| Field | Meaning |
| --- | --- |
| source, venue | kalshi or polymarket |
| event.id, event.name, event.starts_at | Venue event ID (a Kalshi ticker or a Polymarket event ID), the matchup and the scheduled start when known |
| player, stat, line, side | For example Devin Booker, Points, 24.5, over |
| price.probability, price.american, price.decimal | The best ask for that side, in dollars per $1 contract, and the same price as American and decimal odds |
| market_no_vig_probability | This side divided by both sides at the venue, when both are stored |
| sportsbook | BetRivers (Pennsylvania) over and under prices for the same player, stat and line, with implied and no-vig probability |
| edge_vs_sportsbook_no_vig | Sportsbook no-vig probability minus the contract price. Positive means the contract is cheaper than the book implies |
| observed_at, changed_at | Last capture of the venue scope, and last time this price changed |

## Compare Polymarket with a sportsbook in Python

The same response carries the matched BetRivers prices, so a comparison needs no second request.

```python
import json, os
from urllib.request import Request, urlopen

H = {"Authorization": "Bearer " + os.environ["GETODDS_API_KEY"]}
url = "https://getoddsapi.com/api/v1/prediction-markets?source=polymarket&league=NBA&limit=200"
with urlopen(Request(url, headers=H), timeout=20) as r:
    rows = json.load(r)["data"]

# Contracts priced below the sportsbook's no-vig probability for the same side
edges = [x for x in rows if x["edge_vs_sportsbook_no_vig"] is not None]
for x in sorted(edges, key=lambda x: -x["edge_vs_sportsbook_no_vig"])[:10]:
    print(x["player"], x["stat"], x["line"], x["side"],
          "polymarket", x["price"]["probability"],
          "book fair", x["sportsbook"]["no_vig_probability"],
          "edge", x["edge_vs_sportsbook_no_vig"])
```

## FAQ

### Does Polymarket have a free API?

Yes. Polymarket's market data APIs are free. GetOdds is an independent service that normalizes Polymarket sports props and compares them with sportsbook prices.

### Which Polymarket sports markets does GetOdds cover?

Single-player over/under markets, mainly NBA points, rebounds and assists, plus NFL when Polymarket lists them.

### Is the Polymarket price the last trade?

No. It is the best ask for each outcome from the live market feed, the price to buy that side now.

### Is GetOdds affiliated with Polymarket?

No. GetOdds is an independent data product.

---

GetOdds is an independent developer product and is not affiliated with any sportsbook or pick’em operator. Prices describe data, not betting advice.
