Skip to content
OddsHouse.io

41 sportsbooks · 17 leagues · one key

Every line. Every book. The moment it moves.

A normalized real-time odds API across 40+ sportsbooks: main lines, player props and alternate ladders, with deep links back to the bet slip. REST for the board, WebSocket for every change.

  • 7-day trial, no card
  • Decimal and American
  • Resume-safe stream
  • OpenAPI and llms.txt
Live
frames 7
  • DKJ. Brunson · points o27.5NBA · BOS @ NYK1.911.87
  • FDTotal o47.5NFL · KC @ BUF1.911.95
  • PINMoneyline LADMLB · NYY @ LAD1.751.72
  • B3653-way · ARSEPL · ARS v CHE2.052.10
  • MGMN. Jokic · rebounds o12.5NBA · LAL @ DEN1.831.91
  • BRPuck line TOR +1.5NHL · TOR @ BOS1.571.53
  • STKMap 2 winner · FaZeCS2 · Vitality v FaZe2.352.20
cursor 1788567055386-1
NBABOS @ NYKNYK +3.5-108DK
NFLKC @ BUFo47.5-110FD
MLBNYY @ LADLAD ML-139PIN
EPLARS v CHEARS2.10B365
NBALAL @ DENJokic reb o12.5-110MGM
NHLTOR @ BOSTOR +1.5-189BR
CS2Vitality v FaZeMap 2 FaZe2.20STK
NFLKC @ BUFMahomes pass o274.5-110HRB
LaLigaRMA v BARo2.51.83BETANO
MLBNYY @ LADOhtani TB o1.51.67CLB
UCLBAY v PSGDraw3.50SKY
NFLDAL @ PHILamb rec o6.5-125UD
NCAAFOSU @ MICHOSU -6.5-105ESPN
Dota 2Spirit v LiquidSpirit1.601X
NBABOS @ NYKNYK +3.5-108DK
NFLKC @ BUFo47.5-110FD
MLBNYY @ LADLAD ML-139PIN
EPLARS v CHEARS2.10B365
NBALAL @ DENJokic reb o12.5-110MGM
NHLTOR @ BOSTOR +1.5-189BR
CS2Vitality v FaZeMap 2 FaZe2.20STK
NFLKC @ BUFMahomes pass o274.5-110HRB
LaLigaRMA v BARo2.51.83BETANO
MLBNYY @ LADOhtani TB o1.51.67CLB
UCLBAY v PSGDraw3.50SKY
NFLDAL @ PHILamb rec o6.5-125UD
NCAAFOSU @ MICHOSU -6.5-105ESPN
Dota 2Spirit v LiquidSpirit1.601X

Priced from 41 sportsbooks with one key. No per-book setup.

Full coverage
DraftKingsFanDuelBetMGMBetRiversHard Rock BetESPN BettheScore BetBally BetbetPARXPrizePicksUnderdogProphetXbet365William HillLadbrokesCoralSky BetBetfredBetwayBetVictorUnibetDraftKingsFanDuelBetMGMBetRiversHard Rock BetESPN BettheScore BetBally BetbetPARXPrizePicksUnderdogProphetXbet365William HillLadbrokesCoralSky BetBetfredBetwayBetVictorUnibet
888sportbwinBetfair ExchangeMatchbookBetanoDAZN BetInterwetten20BetMelbet1xBetPinnaclePS3838SBOBETBetUSBet105StakeCloudbetThunderpickBC.GameGG.BET888sportbwinBetfair ExchangeMatchbookBetanoDAZN BetInterwetten20BetMelbet1xBetPinnaclePS3838SBOBETBetUSBet105StakeCloudbetThunderpickBC.GameGG.BET
40+
sportsbooks

US, UK, EU, sharps, exchanges, crypto

17
leagues

NFL to CS2, prematch and live

< 0.25 s
book to you

median on live markets

99.9%
uptime

trailing 90 days

What you get

Built for products that live on fresh prices.

Props screeners, EV tools, line-shopping apps and trading desks all need the same three things: one identity across books, the book's own line, and a stream that never silently drops a change.

One id across every book

Events, teams and players resolve to canonical ids. points-all-game-ou-over is the same odd on DraftKings, bet365 and Stake, so a consensus or a best-price is a lookup, not a matching project.

Props and ladders, per book

Player props as one row per player and stat. Each book keeps its own line in its own cell, with the alternate ladder beside it. Two books on different totals never get blended into a number that matches neither.

A stream you can resume

Every frame carries a cursor. Reconnect with resume_from and receive exactly what you missed, or a resync_required telling you to snapshot again. No gaps you find out about later.

Prices you can trust downstream

Decimal and American on every cell. null when a book has no usable price, never 0. A tri-state status, and lastSeenAt so you can tell an unchanged price from a book that stopped talking.

Deep links into the slip

Selection-level links where the book supports them, event-level elsewhere, on every REST cell and every stream frame. A “bet now” button that never needs a second lookup.

Live and prematch, one socket

In-play markets flow on the same connection as the prematch board. Each event carries its phase and the freshest score, period and clock any book has sent.

Normalized, not blended

One id, every book. The line stays with the book.

points
statID
the stat, or the market
-
all
statEntityID
home · away · all · a player id
-
game
periodID
full game, a half, a map
-
ou
betTypeID
ml · ml3way · sp · ou · yn
-
over
sideID
home · away · draw · over · under

The same id on every book. The line is deliberately not part of it: it lives in each book's cell as overUnder or spread, because two books can sit on different lines for the same odd, and the ladder beneath a main line belongs to that book alone.

Two surfaces, one contract

Snapshot over REST. Follow over WebSocket.

Same key, same ids. Every snapshot is stamped with the stream cursor it reflects, so a client applies frames from exactly that point and never double-counts a move.

REST, for the board

  • /v1/events one row per event: phase, score, the best moneyline and which books price it.
  • /v1/events/:id the flat odds map: every odd, every book's cell with its main line and ladder.
  • /v1/props the screener: one row per player and stat, sorted by the widest gap between books.
  • /v1/changes the change log over HTTP, for clients that would rather poll than hold a socket.
# The NBA board: one summary row per event,
# stamped with the stream cursor it reflects
curl "https://api.oddshouse.io/v1/events?league=nba&limit=50" \
  -H "x-api-key: $ODDSHOUSE_KEY"

# One event: the flat odds map keyed by oddID,
# every book inside each odd
curl "https://api.oddshouse.io/v1/events/evt_2f9c1e" \
  -H "x-api-key: $ODDSHOUSE_KEY"

# The player-prop screener: one row per (player, stat),
# widest gap between books first
curl "https://api.oddshouse.io/v1/props?league=nba&shared=1&sort=gap" \
  -H "x-api-key: $ODDSHOUSE_KEY"
import WebSocket from "ws";

const URL = "wss://api.oddshouse.io/v1/updates";
const ws = new WebSocket(`${URL}?key=${process.env.ODDSHOUSE_KEY}`);
let epoch = null, cursor = null;

ws.on("open", () => ws.send(JSON.stringify({
  action: "subscribe",
  filters: {
    leagues: ["nba"],
    books: ["draftkings", "fanduel"],
    market_groups: ["player_props"],
  },
})));

ws.on("message", (raw) => {
  const frame = JSON.parse(raw);
  if (frame.action === "hello") epoch = frame.data.epoch;
  if (frame.cursor) cursor = frame.cursor; // for resume_from on reconnect
  if (frame.action === "line_update") {
    const { book, player, market, prev, price, dir } = frame.data;
    console.log(book, player ?? market.type, prev, "->", price, dir);
  }
  if (frame.action === "resync_required") snapshotAgain();
});

WebSocket, for the changes

  • hello opens with your plan, the schema version, the stream epoch and the current cursor.
  • subscribe narrows to leagues, books, market groups or events; the reply names anything it dropped.
  • line_update one frame per change with prev, dir, the deep link and both timestamps.
  • resume_from on reconnect replays exactly what you missed, or says resync_required when it can't.

Coverage

40+ sportsbooks. 17 leagues. One schema.

Regulated US books, the UK high street, European leaders, the sharps, both exchanges and the crypto books, on the leagues your users actually bet.

Leagues

Full boards, prematch and live.

Football
NFLNCAAF
Basketball
NBANCAABWNBA
Baseball
MLB
Hockey
NHL
Soccer
EPLLaLigaSerie ABuLiLigue 1UCLMLS
Esports
CS2LoLDota 2

Sportsbooks

Regulated, sharp, exchange and crypto, by region.

United States
DraftKings, FanDuel, BetMGM, BetRivers, Hard Rock Bet, ESPN Bet +6 more
UK & Ireland
bet365, William Hill, Ladbrokes, Coral, Sky Bet, Betfred +7 more
Europe
Betano, DAZN Bet, Interwetten, 20Bet, Melbet, 1xBet
Sharp & offshore
Pinnacle, PS3838, SBOBET, BetUS, Bet105
Crypto
Stake, Cloudbet, Thunderpick, BC.Game, GG.BET
Every book, league and market

Reliability

Measured and published, per book.

Latency and uptime are numbers we report, not adjectives. Every frame carries the book's timestamp and ours, and every book has its own line on the status page.

Latency, measured

book change → our broadcast

Every frame carries the book's timestamp and ours. These are the medians we see on live markets.

  • Pinnacle0.14 s
  • Stake0.16 s
  • DraftKings0.19 s
  • FanDuel0.21 s
  • BetMGM0.23 s
  • bet3650.26 s
  • BetRivers0.28 s

seconds · solid: median · faint: 95th percentile

Uptime, per book

trailing 90 days

A book going quiet is an incident we report, not a stale board you discover.

  • DraftKings99.96%
  • FanDuel99.91%
  • bet36599.89%
  • Pinnacle100%
  • Stake99.98%
  • Operational
  • Degraded
  • Outage

Pricing

Plans that are just entitlements.

Every plan is the same feed with different limits: leagues, books, props, ladder depth, requests and sockets. Change them whenever your product does.

Trial

Try the feed on one league: every book, main lines, no card.

Free

7 days, no card

Start free
  • 1 league, every sportsbook
  • Main lines only
  • 60 requests / min
  • 1 WebSocket connection
  • 15-minute resume window
  • Upgrade any time, the key keeps working

Starter

A first product on a few leagues.

$99/ mo

billed monthly

Start with Starter
  • 3 leagues, every sportsbook
  • Player props
  • 3 alternate lines per cell
  • 300 requests / min
  • 2 WebSocket connections
  • Email support
Most popular

Pro

The whole board, full ladders, room to grow.

$299/ mo

billed monthly

Start with Pro
  • Every league, every sportsbook
  • Player props
  • Full alternate ladders
  • 1,200 requests / min
  • 10 WebSocket connections
  • 24-hour resume window
  • 7 days of odds history
  • Priority email support

Enterprise

Custom entitlements, private books, an edge near you.

Custom

annual agreement

Talk to us
  • Everything in Pro
  • Custom leagues, books and limits
  • Additional or private sportsbooks
  • Dedicated edge in your region
  • Historical archive access
  • SLA with service credits
  • Invoicing, DPA, security review

Prices in USD, excluding tax. Every plan includes every sportsbook and the live markets.

Compare every limit side by side

FAQ

What integrators ask first.

How fresh is the data?

Live markets are read from each book's own push feed where it has one and polled where it doesn't. A change is published as one frame the moment the book confirms it, stamped with ts_received and ts_broadcast so you can measure us rather than take our word for it. Prematch boards re-poll on a slower cadence, because prematch prices crawl.

What exactly is normalized?

Events, teams and players get one canonical id across every book, and every odd gets a five-part id: stat, entity, period, bet type, side. A book's own line stays with the book. Two books can price the same odd at different lines and you see both, each with its own ladder, instead of a blended number that matches neither.

Do you have player props and alternate lines?

Yes. Player props come as one row per player and stat with each book's own line and ladder. Starter includes 3 alternate lines per cell, Pro and above the full ladder. Milestone props (a book quoting 'over 24.5' as '25+') are marked so your under side does not go missing.

REST or WebSocket?

Both, with the same key. Snapshot the board over REST (every snapshot is stamped with the stream cursor it reflects), open the socket, and apply the frames whose cursor is after that stamp. If the socket drops, reconnect with resume_from and the epoch from the hello frame and you receive exactly what you missed, or a resync_required frame telling you to snapshot again.

What happens when I exceed my rate limit?

Each key has a token bucket that refills at your plan's per-minute rate. Over the limit you get a 429 with the reset time; nothing is queued or silently dropped. /v1/account/usage shows the bucket, today's request count by endpoint and your open sockets, so you can watch it live.

How does the trial work?

7 days, no card. You pick one league, get every sportsbook on it with main lines, 60 requests a minute and one socket. Upgrade from the portal whenever you want and the key keeps working; nothing needs re-issuing.

All questions

Start on the trial. Upgrade when your users do.

One league, every sportsbook, 7 days, no card. The key you get today is the key you scale with.