Every book's price. One API.

Sportsbooks, exchanges and prediction markets on one fixture, in one JSON shape, each price stamped with when its book last confirmed it.

Sample prices

Moneyline

Eagles @ Bears

NFL

BookEaglesBears
FanDuel-200+168
DraftKings-192+160
BetOnline-195+170
Kalshi-186+178
Novig-182+176

29 more books price this game

Panthers @ Hurricanes

NHL

BookPanthersHurricanes
Pinnacle+109-122
DraftKings+105-125
BetOnline+106-120
Polymarket+108-113
Novig+115-120

26 more books price this game

Arsenal v Chelsea

Soccer

BookArsenalDrawChelsea
Pinnacle-118+290+320
FanDuel-125+280+330
DraftKings-120+285+310
BetOnline-115+288+318
Kalshi-112+300+305

24 more books price this game

How it works

Flat monthly plans

A free plan, then flat plans from $24 to $199 a month. Each one is a set number of requests; the price never moves with what you use.

  1. $0Free1,000 requests a month
  2. $24Starter20,000 requests a month
  3. $49Growth100,000 requests a month
  4. $99Scale500,000 requests a month
  5. $199Business5,000,000 requests a month

Every book, every plan

The free plan sees the same 46 books as the top plan. What grows is how much you can ask for, not what you're allowed to see.

Plain, nested JSON

Fixture, then books, then markets, then outcomes: each outcome a price, and a point where the market has one. American or decimal odds, chosen per call.

One id per fixture

Every fixture keeps one stable id across all 46 books, so you never match team names from one book to the next.

Timestamped, never guessed

last_update tells you when a book last confirmed a price. It is null when that value is unavailable, never an estimate.

Only price and history calls count

Listing sports and upcoming fixtures is free. One odds call is one request, whatever comes back. Refused when spent, never a surprise bill.

46 books, one response shape

Sportsbooks, exchanges and prediction markets, all priced through the same fields.

  • DraftKings, Sportsbook
  • FanDuel, Sportsbook
  • Caesars, Sportsbook
  • bet365, Sportsbook
  • BetMGM, Sportsbook
  • BetRivers, Sportsbook
  • Kalshi, Prediction Market
  • Polymarket, Prediction Market
  • 1xBet, Sportsbook
  • 4Casters, Exchange
  • 888sport, Sportsbook
  • Bally Bet, Sportsbook
  • bet105, Sportsbook
  • Betano, Sportsbook
  • Betfair, Exchange
  • BetOnline, Sportsbook
  • Betr, Sportsbook
  • BetUS, Sportsbook
  • Betway, Sportsbook
  • Bovada, Sportsbook
  • bwin, Sportsbook
  • Circa, Sportsbook
  • Cloudbet, Sportsbook
  • Fanatics, Sportsbook
  • Fanatics Markets, Prediction Market
  • Fliff, Sportsbook
  • Hard Rock, Sportsbook
  • Ladbrokes, Sportsbook
  • LowVig, Sportsbook
  • Matchbook, Exchange
  • Novig, Exchange
  • Pinnacle, Sportsbook
  • PrizePicks, Sportsbook
  • ProphetX, Exchange
  • ReBet, Sportsbook
  • SBOBET, Sportsbook
  • Shuffle, Sportsbook
  • Sky Bet, Sportsbook
  • SportBet, Sportsbook
  • Stake, Sportsbook
  • sx.bet, Exchange
  • theScore Bet, Sportsbook
  • Thunderpick, Sportsbook
  • Underdog, Sportsbook
  • Unibet, Sportsbook
  • William Hill, Sportsbook
  • Sportsbook
  • Exchange
  • Prediction Market

What people build on it

The same feed, four kinds of customer. None of them writes a scraper.

Betting tools

Fair prices from the no-vig line, +EV screens, arbitrage and middles scanners, closing-line-value tracking: every price with the book that posted it and when.

No-vigMiddlesHedgeAll tools

Odds screens and comparison sites

A best-price grid across 46 books from one call per sport, with last_update beside every number.

Book coverageOdds guide

Trading models and prediction-market bots

Kalshi and Polymarket contracts in the same shape as a sportsbook line, with sizes typed as dollars of depth, so a model compares venues without special cases.

Bookmaker keysHistory

AI agents and research

An MCP server so an agent quotes a real book at a real time instead of a memory, and openers, closers and full series for backtests.

Build with AIWhat is an odds API?

Every sport, every market shape we carry

One set of markets, applied the same way whichever sport you ask about.

Sports

  • NFL
  • NCAAF
  • NBA
  • NCAAB
  • WNBA
  • MLB
  • NHL
  • Soccer
  • MMA
  • Tennis

Markets

  • Moneyline
  • Spreads
  • Totals
  • Period markets (1st half, F5, ...)
  • Alternate lines
  • Team totals

25 endpoints, nothing else to learn

The whole surface, plus account endpoints for your keys and usage. Only calls that return prices count against your plan; looking around is free.

  • GET/v1/tryit/runfreeRun a public read request as a guest
  • GET/v1/sportsfreeList sports
  • GET/v1/bookmakersfreeList bookmakers
  • GET/v1/pickem/payoutsfreeList published pick'em entry payouts
  • GET/v1/marketsfreeList markets
  • GET/v1/sports/{sport}/eventsfreeList a sport's fixtures, no prices
  • GET/v1/sports/{sport}/events/livefreeList fixtures in play, no pricesGrowth (100K requests a month) and up
  • GET/v1/sports/{sport}/odds1 requestList a sport's fixtures with prices
  • GET/v1/sports/{sport}/odds/live1 requestList fixtures in play with pricesGrowth (100K requests a month) and up
  • GET/v1/sports/{sport}/events/{id}/odds1 requestOne fixture's prices, including periods and full-game ladders
  • GET/v1/public/board/sportsfreeBoard sports with fixture counts
  • GET/v1/public/board/{sport}freeThe public board for one sport
  • GET/v1/public/featuredfreeThe homepage's featured games
  • GET/v1/sports/{sport}/props1 requestPlayer props across a sport's fixturesGrowth (100K requests a month) and up
  • GET/v1/sports/{sport}/props/live1 requestPlayer props for fixtures in playGrowth (100K requests a month) and up
  • GET/v1/sports/{sport}/events/{id}/props1 requestPlayer props for one fixtureGrowth (100K requests a month) and up
  • GET/v1/historical/sports/{sport}/eventsfreeDiscover archived fixture IDsScale (500K requests a month) and up
  • GET/v1/historical/sports/{sport}/events/{id}/odds1 requestThe full recorded price series for one fixtureScale (500K requests a month) and up
  • GET/v1/historical/sports/{sport}/events/{id}/openers1 requestEach book's opening line for one fixtureScale (500K requests a month) and up
  • GET/v1/historical/sports/{sport}/events/{id}/closing1 requestEach book's closing line for one fixtureScale (500K requests a month) and up
  • GET/v1/historical/sports/{sport}/events/{id}/props1 requestRecorded full-game prop checkpoints for one fixtureScale (500K requests a month) and up
  • GET/v1/historical/sports/{sport}/events/{id}/props/movement1 requestRecorded full-game prop price changes for one fixtureScale (500K requests a month) and up
  • GET/v1/historical/sports/{sport}/events/{id}/props/openers1 requestEach prop selection first observed by each bookScale (500K requests a month) and up
  • GET/v1/historical/sports/{sport}/events/{id}/props/closing1 requestEach prop selection last observed before kickoffScale (500K requests a month) and up
  • GET/v1/billing/subscriptionfreeThis account's subscription

Copy, paste, run

Three common calls in five languages. The key always travels in the X-API-Key header.

GET/v1/sports/soccer/odds?league=epl&markets=h2h,spreads
curl --request GET \
  --url "https://oddslink.app/v1/sports/soccer/odds?league=epl&markets=h2h,spreads" \
  --header "X-API-Key: ok_live_..." \
  --compressed
200 OKresponse.json
[
  {
    "id": "soccer:crystalpalace-nottinghamforest:2026-10-11",
    "sport_key": "soccer",
    "sport_title": "Soccer",
    "commence_time": "2026-10-11T13:00:00.000Z",
    "is_live": false,
    "status": "scheduled",
    "home_team": "Crystal Palace",
    "away_team": "Nottingham Forest",
    "bookmakers": [
      {
        "key": "betmgm",
        "title": "BetMGM",
        "link": "https://sports.nj.betmgm.com/en/sports/events/crystal-palace-nottingham-forest-2:7865814",
        "last_update": "2026-10-10T22:06:51.003Z",
        "markets": [
          {
            "key": "spreads",
            "last_update": "2026-10-10T22:06:51.003Z",
            "outcomes": [
              {
                "name": "Nottingham Forest",
                "price": 145,
                "point": -0.5,
                "main": true
              },
              {
                "name": "Crystal Palace",
                "price": -210,
                "point": 0.5,
                "main": true
              }
            ]
          }
        ]
      }
    ],
    "unmatched_bookmakers": []
  }
]

Three fields worth knowing

They sit beside the prices, so code that doesn't read them can skip them.

When each price was confirmed

last_update

On every book and market: when the book last confirmed its prices, or null when it is unavailable. We do not estimate it.

{ "key": "totals", "period": "f5",
  "last_update": "2026-09-21T16:42:07Z" }

Size carries its kind

size.kind

A posted limit, a resting exchange depth and a contract count aren't the same number. Each outcome says which one it's giving you, and says nothing when the book publishes none.

{ "kind": "resting_depth",
  "amount": 1200 }

Missing books are named

unmatched_bookmakers

A book that reached us but couldn't be matched to this fixture is listed in the response instead of silently missing. Ask for books by name with bookmakers= and every one that returned nothing is listed too.

"unmatched_bookmakers": ["betano"]

Start reading odds in one request.

Free plan: 1,000 requests a month, every book.