Sports Odds vs Kalshi & Polymarket — 5 sources, same line
Pricing
from $2.00 / 1,000 odds rows
Sports Odds vs Kalshi & Polymarket — 5 sources, same line
Every game's moneyline, spread and total from DraftKings, BetRivers and Bovada next to Kalshi and Polymarket, on one row at the same line, with the no-vig consensus, best price and edge of each.
Pricing
from $2.00 / 1,000 odds rows
Rating
0.0
(0)
Developer
Cowboi Bebot
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 hours ago
Last modified
Categories
Share
The moneyline, spread and total of every game from three sportsbooks (DraftKings, BetRivers, Bovada) and two prediction markets (Kalshi, Polymarket) on one row, at the same line, with the books' no-vig consensus, the best price, each price's edge against the consensus, and the exchange prices with their trading fee included. NFL, college football, NBA, WNBA, MLB, NHL and seven soccer leagues.
Versión en español más abajo.
Quick facts
- What it does: Moneyline, spread and total of every game from DraftKings (via ESPN), BetRivers (Kambi), Bovada, Kalshi and Polymarket on one row at the same line, with the books' no-vig consensus, the best price, each price's edge, and the exchanges' taker fees applied.
- Use it for: comparing sportsbooks with prediction markets; line shopping; no-vig probabilities; monitoring price changes before games (13 leagues: NFL, NCAAF, NBA, WNBA, MLB, NHL, EPL, LaLiga, Serie A, Bundesliga, Ligue 1, UCL, MLS).
- Not for: live (in-game) odds, player props, futures, golf/UFC, NCAAB, FanDuel (not in this version); placing bets. This is data, not betting advice.
- Input:
leagues(default NFL); optionalsources,markets(moneyline, spread, total),lines(mainorall),daysAhead(0-14, default 7),onlyChanged+stateName,maxRows(0 = no limit). - Output: one dataset row per game, market, line and selection, and one
SUMMARYrecord with the per-league, per-source check. Every field with its type is under Output reference below. - Charged events (pay per event):
odds-rowUSD 0.002 per row delivered (USD 2.00 per 1,000); plus Apify's standard start eventapify-actor-start. - Never charged: the SUMMARY record, rows left out because their price did not change (
onlyChanged), leagues that fail. - Limits: pre-game prices only; stops at
maxRowsor at your maximum charge per run; settlement rules of the exchanges can differ from the books' (each row carries the market id). - Run it from: Apify Console, the Apify API or an AI agent through the Apify MCP server (Actor
pampadata/sports-odds-vs-prediction-markets), with schedules and integrations.
Minimal input
A small input that works, taken from this Actor's own tests; every other field is optional:
{"leagues": ["NFL","EPL"],"maxRows": 5}
Why this one
- Sportsbooks and prediction markets side by side. Kalshi and Polymarket now price the same games as the books. Here they sit on the same row, at the same line: a Kalshi "Jacksonville wins by over 7.5 points" contract, a Polymarket "Spread: Jaguars (-7.5)" share and DraftKings' JAX −7.5 are one row, not three.
- Five sources, no key, no proxy to pay. All five are read from their public feeds. Test on 2026-10-09, from Apify's servers: all 13 leagues, 1,904 rows in 110 seconds, 0 requests refused.
- Every source matched to the same game. The schedule is ESPN's; every source's event is matched to it by both team names and the start time (city, nickname and short-code variants: "JAC Jaguars", "Jacksonville", "Jaguars", "Ole Miss" / "Mississippi", "LAFC" / "Los Angeles F"). When two games fit equally (a playoff series on consecutive days without a time) the Actor refuses rather than guesses, and names the event in the SUMMARY. On 2026-10-09: 0 unmatched events in 12 of 13 leagues (in college football, 2 games ESPN does not list); 762 rows with a book and an exchange, 0 with a team on the wrong side.
- The same line, exactly. A row is one game, one market, one line, one selection. A price is only placed on a row when it is for that exact line. Choose
lines: "main"(the lines that are a sportsbook's main line) or"all"(every line two sources share: BetRivers' alternate lines next to Kalshi's and Polymarket's line ladders; 318 shared spread lines on 15 NFL games). - Numbers you would otherwise compute. Per row: the books' no-vig probability (each book's margin removed, then averaged), the best price and its source, the edge of every price against that consensus, and the margin of the market at the best prices (negative = the best prices together pay more than they cost).
- Exchange fees included. Kalshi's taker fee (M × 0.07 × P × (1 − P), Kalshi fee schedule effective July 7, 2026, with each series' multiplier from Kalshi's API) and Polymarket's (its market's own fee rate × P × (1 − P), Polymarket docs) are applied to the ask:
askWithFee,decimalWithFee, and a best price and market margin with fees. In one run of four leagues (618 rows), 24 rows looked like an arbitrage before fees and 6 after. - Line movement and price age. DraftKings' opening line and price next to the current one; Bovada's and Polymarket's own last-update time on every price (a competitor measured a Bovada coupon 26.6 hours old).
- Only changed prices, for monitoring. Turn on
onlyChangedand each run delivers, and charges, only the rows whose price moved at any source since the last run with the same state name. A source that could not be read in a run does not count as a change. - Empty or near-empty exchange books are left out. A Kalshi or Polymarket side with no buyer, or more than 15 cents between buy and sell, is not a price (seen: a college game at 99 cents on every side).
Input
| Field | What it does |
|---|---|
leagues | NFL, NCAAF (FBS and FCS), NBA, WNBA, MLB, NHL, EPL, LALIGA, SERIEA, BUNDESLIGA, LIGUE1, UCL, MLS. |
sources | draftkings, betrivers, bovada, kalshi, polymarket (all by default). |
markets | moneyline, spread, total (full game; soccer: win/draw/win, x.5 goal lines, total goals). |
lines | main (default) or all (every spread/total line at least two of your sources quote). |
daysAhead | Games from now to the end of this many US Eastern days ahead (0–14, default 7). Pre-game prices only. |
onlyChanged, stateName | Monitoring: only rows whose price changed since the last run with the same state name. |
maxRows | Stop after this many rows (0 = no limit). |
What you get for each row
league, gameId (ESPN's id), startTime (UTC), homeTeam, awayTeam, game, market, line (from the selection's own side: −7.5 for the favourite; the total for over/under), selection, side (home / away / draw / over / under), sourcesQuoting; one column per source with its American odds (draftkings, betrivers, bovada, kalshi, polymarket; for the exchanges, the price to buy now converted to odds, before fees); bestSource, bestAmerican, bestDecimal, consensusNoVigProbability, booksInConsensus, bestEdgeVsConsensus, marketHoldAtBestPrices, bestSourceWithFees, bestDecimalWithFees, bestEdgeWithFeesVsConsensus, marketHoldAtBestPricesWithFees; and prices, with every source's detail: decimal and implied probability; for the books, main line or not, their own no-vig probability and (DraftKings) the opening line; for the exchanges, ask, bid, last, market id, volume, open interest or liquidity, the fee per share and the price with the fee.
Example (one row of 134 for the NFL, 2026-10-09)
{"game": "Philadelphia Eagles @ Jacksonville Jaguars","startTime": "2026-10-11T13:30:00Z","market": "spread", "line": -7.5, "selection": "Jacksonville Jaguars", "side": "home","sourcesQuoting": 5,"draftkings": -108, "betrivers": -110, "bovada": -110, "kalshi": 100, "polymarket": 100,"bestSource": "kalshi", "bestAmerican": 100,"consensusNoVigProbability": 0.4986,"bestEdgeVsConsensus": -0.0029,"bestSourceWithFees": "polymarket", "bestDecimalWithFees": 1.9704,"marketHoldAtBestPricesWithFees": 0.025,"prices": {"kalshi": {"ask": 0.5, "bid": 0.49, "marketId": "KXNFLSPREAD-26OCT11PHIJAC-JAC8", "takerFeePerShare": 0.0175, "askWithFee": 0.5175},"polymarket": {"ask": 0.5, "bid": 0.49, "takerFeeRate": 0.03, "takerFeePerShare": 0.0075, "askWithFee": 0.5075},"draftkings": {"american": -108, "noVigProbability": 0.4957, "opening": {"line": 2.5, "american": -115}}}}
The check per league (SUMMARY record)
Games in the window, and per source: events read, matched, outside the window (already started, or after your days), not matched (with the teams and the reason), errors, and the number of requests. complete: true only when every source was read.
Price
You pay per row delivered: USD 2.00 per 1,000 rows (USD 0.002 each; a row is one game, one market, one line, one selection, with every source's price on it). No charge per run beyond Apify's standard start event, and nothing for the SUMMARY records, for rows left out because their price did not change (onlyChanged), or for leagues that fail. Set a maximum charge per run in Apify, or maxRows, and the Actor stops there.
How long it takes
One league in about 5 seconds; all 13 leagues (1,904 rows) in about 2 minutes.
Good to know
- Pre-game only. Games already under way are left out (counted as
outsideWindow). - DraftKings is read as ESPN publishes it (current and opening line), so it shows the main line only. BetRivers comes from Kambi, the odds feed behind it (New Jersey; New York's list if New Jersey's does not answer).
- Bovada sometimes hides a league from data-centre computers: on 2026-10-09 its MLB list came back empty in 3 runs in a row (once also from a US residential address) and normally in a later one; NFL, NHL and soccer always came normally. The Actor asks again from a residential address, and if the list is still empty the SUMMARY marks Bovada as failed for that league.
- Kalshi's fee is rounded up per order (to a centicent, or a cent for some accounts), so a very small order pays slightly more than
takerFeePerShare(1 contract at 50 cents: 2 cents in Kalshi's table). Polymarket rounds each trade's fee to 5 decimals. - Settlement rules can differ. The books' markets used here are the full-game ones (overtime included in US sports; regulation time in soccer). Kalshi's and Polymarket's rules are their own (each row carries the market id): read them before acting on a difference.
- Kalshi and Polymarket may not be available where you live; this Actor only reads public prices.
Not affiliated
Not affiliated with, endorsed by or sponsored by ESPN, DraftKings, Rush Street Interactive (BetRivers), Kambi, Bovada, Kalshi or Polymarket. Names are used only to say where the public prices come from. This is data, not betting advice.
Output reference
Dataset: one row per game, market, line and selection
| Field | Type | What it is |
|---|---|---|
league | string | League name. |
leagueCode | string | League code used in the input (NFL, EPL…). |
gameId | string | ESPN's game ID. |
startTime | string | Start time (ISO 8601, UTC). |
homeTeam | string | Home team. |
awayTeam | string | Away team. |
game | string | "Away @ Home". |
market | string | moneyline, spread or total. |
line | number or null | The line from the selection's own side (-7.5 for the favourite; the total for over/under); null on moneyline. |
selection | string | The team, the draw, or over/under. |
side | string | home, away, draw, over or under. |
sourcesQuoting | integer | How many sources have a price on this row. |
draftkings | integer or null | American odds at DraftKings (as published on ESPN). |
betrivers | integer or null | American odds at BetRivers (Kambi feed). |
bovada | integer or null | American odds at Bovada. |
kalshi | integer or null | Kalshi's price to buy now, as American odds, before fees. |
polymarket | integer or null | Polymarket's price to buy now, as American odds, before fees. |
bestSource | string | Source with the best price before fees. |
bestAmerican | integer | Best price, American odds. |
bestDecimal | number | Best price, decimal odds. |
consensusNoVigProbability | number or null | The books' no-vig probability (each book's margin removed, then averaged). |
booksInConsensus | array of string | Books used in the consensus. |
bestEdgeVsConsensus | number or null | Edge of the best price against the consensus. |
marketHoldAtBestPrices | number or null | Market margin at the best prices (negative = the best prices together pay more than they cost). |
bestSourceWithFees | string | Source with the best price after the exchanges' taker fees. |
bestDecimalWithFees | number | Best decimal price after fees. |
bestEdgeWithFeesVsConsensus | number or null | Edge of the best price after fees. |
marketHoldAtBestPricesWithFees | number or null | Market margin at the best prices after fees. |
prices | object | Per source. Books: american, decimal, impliedProbability, noVigProbability, edgeVsConsensus, mainLine, updatedAt (Bovada), opening (DraftKings: line, american). Exchanges: ask, bid, last, american, decimal, impliedProbability, edgeVsConsensus, marketId, volume, openInterest (Kalshi) or liquidity (Polymarket), feeType/feeMultiplier/contractSide (Kalshi), takerFeeRate (Polymarket), takerFeePerShare, askWithFee, americanWithFee, decimalWithFee, edgeWithFeeVsConsensus, updatedAt (Polymarket). |
scrapedAt | string | When the row was built (ISO 8601, UTC). |
SUMMARY record (run's key-value store, never charged)
| Field | Type | What it is |
|---|---|---|
leagues | array of object | One item per league (fields below). |
rowsDelivered | integer | Rows delivered (charged) in the run. |
requests | object | Request counters per source. |
window | object | from / to of the games window (UTC). |
settings | object | The settings the run used. |
note | string | Reminder: kalshi/polymarket columns are before fees; *WithFee(s) fields include them. |
Each item of leagues:
| Field | Type | What it is |
|---|---|---|
league | string | League code. |
games, gamesWithRows | integer | Games in the window, and games with at least one row. |
rowsDelivered | integer | Rows delivered for the league. |
rowsUnchangedSkipped | integer | onlyChanged: rows left out because no price moved (not charged). |
sources | object | Per source: events, matched, outsideWindow, unmatched (teams, id, why), error. |
complete | boolean | true only when every source was read. |
stoppedBy | string or null | Why it stopped early (maxRows or your maximum charge). |
warnings | array of string | Warnings. |
More Actors by this developer
- Google Ads Transparency Scraper
- SEEK Jobs Scraper (Seek, JobStreet, Jobsdb)
- Career Site Jobs Scraper (Workday, Greenhouse, Lever and 6 more)
- AliExpress Search Scraper
- Google News Scraper
- Google Trends Scraper
- YouTube Transcripts in Bulk (whole channels, playlists)
Versión en español
La línea de dinero (ganador), el hándicap (spread) y el total de cada partido de tres casas de apuestas (DraftKings, BetRivers, Bovada) y dos mercados de predicción (Kalshi, Polymarket) en una sola fila, a la misma línea, con el consenso sin margen de las casas, el mejor precio, la ventaja de cada precio contra ese consenso, y el precio de los mercados de predicción con su comisión incluida. NFL, fútbol americano universitario, NBA, WNBA, MLB, NHL y siete ligas de fútbol.
De un vistazo
- Qué hace: Ganador, hándicap y total de cada partido de DraftKings (vía ESPN), BetRivers (Kambi), Bovada, Kalshi y Polymarket en una fila a la misma línea, con el consenso sin margen, el mejor precio, la ventaja de cada precio y las comisiones de los mercados de predicción aplicadas.
- Sirve para: comparar casas de apuestas con mercados de predicción; buscar el mejor precio; probabilidades sin margen; monitorear cambios antes de los partidos (13 ligas).
- No sirve para: cuotas en vivo, props de jugadores, futuros, golf/UFC, NCAAB, FanDuel (no están en esta versión); apostar. Son datos, no consejos de apuestas.
- Entrada:
leagues(NFL por defecto); opcionalessources,markets,lines,daysAhead,onlyChanged+stateName,maxRows. Ejemplo mínimo en JSON: sección Minimal input de la parte en inglés. - Salida: una fila por partido, mercado, línea y opción, y un registro
SUMMARYpor liga y fuente. - Eventos que se cobran:
odds-rowUSD 0,002 por fila entregada (USD 2,00 cada 1.000); másapify-actor-start. - Nunca se cobra: el SUMMARY, las filas sin cambio de precio (
onlyChanged), las ligas que fallan. - Límites: solo antes del partido; se detiene en
maxRowso en tu costo máximo por corrida.
Por qué este
- Casas de apuestas y mercados de predicción lado a lado, en la misma fila y la misma línea.
- Cinco fuentes, sin clave ni proxy pago. Prueba del 2026-10-09 desde los servidores de Apify: 13 ligas, 1.904 filas en 110 segundos, ningún pedido rechazado.
- Cada fuente emparejada con el mismo partido (calendario de ESPN; equipos por nombre, apodo y sigla, y hora de inicio). Si dos partidos encajan igual, no adivina: lo informa.
- La misma línea, exacta.
lines: "main"(líneas principales de las casas) o"all"(toda línea que comparten dos fuentes). - Cálculos hechos: probabilidad sin margen, mejor precio, ventaja de cada precio, margen del mercado a los mejores precios.
- Comisiones incluidas de Kalshi (tabla oficial vigente desde el 7 de julio de 2026) y de Polymarket (tasa propia de cada mercado, según su documentación).
- Movimiento de línea y antigüedad del precio: línea de apertura de DraftKings; hora de la última actualización de Bovada y Polymarket.
- Solo precios que cambiaron, para monitoreo; una fuente que no se pudo leer no cuenta como cambio.
Precio
Pagás por fila entregada: USD 2,00 cada 1.000 filas (USD 0,002 cada una; una fila es un partido, un mercado, una línea y una opción, con el precio de cada fuente). No hay cargo por corrida aparte del evento de inicio estándar de Apify, y no se cobran los registros SUMMARY, las filas que no se entregan porque su precio no cambió (onlyChanged) ni las ligas que fallan. Poné un cargo máximo por corrida en Apify, o maxRows, y el Actor se detiene ahí.
No afiliado
Sin relación con ESPN, DraftKings, Rush Street Interactive (BetRivers), Kambi, Bovada, Kalshi ni Polymarket. Son datos, no consejos de apuestas.