Kalshi Sports API (2026): Markets, Odds and Live Data

The Short Answer
Kalshi's sports markets run on the same public Trade API as every other market, organized as series, events and markets. A series is one market type for one league, such as KXNFLGAME for NFL game winners. An event is one game, such as KXNFLGAME-26OCT04INDWAS, and each market is one outcome with its own ticker. One keyless call, GET /events?series_ticker=KXNFLGAME&status=open&with_nested_markets=true&with_milestones=true, returns every open game with its prices and milestone. Prices read as probabilities: a 35-cent ask is 35%, decimal odds of 2.86 or American +186, before fees. Live scores come from GET /live_data/milestone/{milestone_id}, and play-by-play from its game_stats path, also without a key.
Key Takeaways
- Sports markets nest three levels deep: a series per league and market type, an event per game, and a market per outcome.
GET /search/filters_by_sportlists every sport with its competitions and scopes, and each event carries a matchingproduct_metadata.competition.- A yes ask is an implied probability. Across 30 open NFL games on 3 October 2026, the two teams' asks summed to between $1.00 and $1.04, before fees.
- Milestones link a game to all its events, 70 of them for one NFL game we checked, and their IDs key the live data endpoints.
- Live scores, batch live data for up to 100 games and play-by-play are all public reads.
How are Kalshi sports markets organized?
Kalshi uses the same three levels for sports as for everything else:
| Level | Example | What it is |
|---|---|---|
| Series | KXNFLGAME | One market type for one league: NFL game winners |
| Event | KXNFLGAME-26OCT04INDWAS | One game: IND Colts vs WAS Commanders on 4 October |
| Market | KXNFLGAME-26OCT04INDWAS-WAS | One outcome: "Washington wins" |
Each bet type gets its own series, so one NFL game appears in KXNFLGAME, KXNFLSPREAD, KXNFLTOTAL and dozens of quarter, half and player series, all sharing the game's suffix. An NFL winner event holds two markets, one per team, while a Premier League game in KXEPLGAME holds three: one per team plus a tie.
The rules sit on each market. For the Colts and Commanders, "If the game ends in a tie, the market will resolve to $0.50 for each team", and a game not started within 48 hours of its scheduled time resolves to a fair price. The series names "the Governing League" as its settlement source. Note the shard too: NFL games trade on exchange index 0, while NBA and MLB game series sit on shard 3, which matters when you fund an account for trading.
How do you find a league's games through the API?
Start with the sport. GET /search/filters_by_sport returns 20 sport groups, from basketball and soccer to darts and chess, each with its competitions and scopes. Soccer alone listed 78 competitions on 3 October 2026. Events echo those labels in product_metadata: the Colts game carries "competition": "Pro Football" and "competition_scope": "Game".
Then go to the series. GET /series?category=Sports&tags=Football returned 584 football series, so most integrations hardcode the handful they need, such as KXNFLGAME, KXNBAGAME, KXMLBGAME, KXNHLGAME or KXEPLGAME. With a series ticker, one call returns every open game, its markets and its milestone. This runs on Node 18 or newer with no key:
const BASE = 'https://external-api.kalshi.com/trade-api/v2';
const url = `${BASE}/events?series_ticker=KXNFLGAME&status=open&with_nested_markets=true&with_milestones=true&limit=200`;
const { events, milestones } = await (await fetch(url)).json();
const american = (p) => (p >= 0.5 ? `-${Math.round((100 * p) / (1 - p))}` : `+${Math.round((100 * (1 - p)) / p)}`);
for (const event of events) {
const milestone = milestones.find((m) => m.primary_event_tickers.includes(event.event_ticker));
console.log(event.title, '| starts', milestone?.start_date, '| milestone', milestone?.id);
for (const m of event.markets) {
const ask = Number(m.yes_ask_dollars);
if (!(ask > 0 && ask < 1)) continue;
console.log(` ${m.yes_sub_title}: ask ${ask.toFixed(2)} | ${(ask * 100).toFixed(0)}% | decimal ${(1 / ask).toFixed(2)} | American ${american(ask)}`);
}
}
with_nested_markets=true puts each game's markets inside its event, and with_milestones=true adds a top-level milestones array. Match the two through primary_event_tickers. On 3 October 2026 this returned 30 open NFL games, the first being Washington at 35 cents and Indianapolis at 65.
Milestones can also be searched directly. GET /milestones filters by type, such as football_game, and by competition, which matched the league name in our checks: competition=NFL returned NFL games, while the documented example value, Pro Football, returned none.
How do Kalshi prices convert to odds?
A Kalshi contract pays $1 if its outcome happens, so its price is an implied probability. Buying at a 35-cent ask means paying 35 cents for a $1 payout if that team wins:
| Format | Formula from the ask p | At 35 cents | At 65 cents |
|---|---|---|---|
| Implied probability | p | 35% | 65% |
| Decimal odds | 1 / p | 2.86 | 1.54 |
| American odds | +100(1 - p) / p below 50 cents, -100p / (1 - p) at or above | +186 | -186 |
Adding the asks across an event shows the margin built into the book. In the 30 open NFL games we pulled on 3 October 2026, the two teams' asks summed to between $1.00 and $1.04, with a median of $1.01. Premier League games, with three outcomes, had a median of $1.02. Those figures are before Kalshi's trading fees, which Kalshi fees explained breaks down, so a true cost comparison with a sportsbook has to add them. The wider comparison is in the best prediction market for sports betting.
How do you get live scores from the Kalshi API?
Through milestones. A milestone links a real-world occurrence to its events, and Kalshi's docs say the same milestone ID "is also the key used by the live data API". The milestone for the Colts game listed 5 primary events (winner, spread, total, team total and tie) and 70 related events in all, plus team IDs and the season and week in its details.
| Endpoint | What it returns |
|---|---|
GET /milestones?related_event_ticker= | The milestone behind an event, with its ID, type, start date and linked events |
GET /live_data/milestone/{milestone_id} | Live state: score, clock or match time, status and the last play |
GET /live_data/batch?milestone_ids= | Live data for up to 100 milestones, with the parameter repeated per ID |
GET /live_data/milestone/{milestone_id}/game_stats | Play-by-play by period, for supported sports |
const BASE = 'https://external-api.kalshi.com/trade-api/v2';
const eventTicker = 'KXUEFANLGAME-26OCT02FRAITA';
const { milestones } = await (await fetch(`${BASE}/milestones?limit=1&related_event_ticker=${eventTicker}`)).json();
const milestone = milestones[0];
console.log(milestone.title, '|', milestone.type, '|', milestone.start_date);
const { live_data: live } = await (await fetch(`${BASE}/live_data/milestone/${milestone.id}`)).json();
const d = live.details;
console.log(d.status, d.time ?? d.clock, `${d.home_same_game_score ?? d.home_points}-${d.away_same_game_score ?? d.away_points}`, d.last_play?.description);
The type field names the schema of details, so fields differ by sport. A football game reports quarter, clock, home_points and the down and yard line, while a soccer match reports time, half and home_same_game_score. We ran this at halftime of France vs Italy in the Nations League and got live 45' 0-0. For a game that has not started, the NFL endpoint returned a scheduled status with the clock at 15:00.
Play-by-play comes from game_stats, which Kalshi supports for pro and college football, pro and college basketball, the WNBA, soccer, pro hockey and pro baseball. It returned events such as shots and free kicks for the live soccer match, and an empty object for the NFL game before kickoff. For Pro Football, Pro Basketball and College Men's Basketball, include_player_stats=true adds player-level statistics where Kalshi has player mappings. For streaming prices rather than polling them, see the Kalshi WebSocket API guide, and for the rest of the Trade API, the Kalshi API guide.
How do you compare Kalshi sports prices with other venues?
The same game often trades on several venues, and the useful question is which one offers the best price for the exact bet you want. The Predictefy API has a sports screen for this, live since 29 September 2026. It lines up each game by bet type, period, line and selection, with one cell per venue. Each cell shows the venue's ask, plus its price after known fees. A venue without that exact line gets an empty cell rather than its nearest line, so a spread of -2.5 is never compared with -3.
Prices move quickly around kickoff and every trade carries risk, so treat any cross-venue gap as a prompt to check the live book before you act.
Frequently Asked Questions
Does Kalshi have a sports API?
Yes. Sports markets use Kalshi's standard Trade API, and reading them needs no key. Series, events and markets give prices, the search endpoint lists sports and competitions, and the live data endpoints return scores and play-by-play keyed by milestone ID.
How do I get NFL odds from Kalshi?
Call GET /events with series_ticker=KXNFLGAME, status=open and with_nested_markets=true. Each game is an event with one market per team, and each market's yes_ask_dollars is the price to back that team, which converts directly to an implied probability.
How do Kalshi prices convert to American odds?
For a price p below 50 cents, American odds are +100 times (1 - p) divided by p, so 35 cents is +186. At 50 cents or above they are -100 times p divided by (1 - p), so 65 cents is -186. Decimal odds are 1 divided by p. Fees are not included.
Does Kalshi provide live sports scores through its API?
Yes. GET /live_data/milestone/{milestone_id} returns the live state of a game, such as score, clock and last play, and GET /live_data/batch returns up to 100 games at once. Find the milestone ID with GET /milestones and a related_event_ticker.
What sports can you trade on Kalshi?
On 3 October 2026, Kalshi's sports filter endpoint listed basketball, baseball, tennis, soccer, hockey, golf, MMA, cricket, football, esports, motorsport, boxing, lacrosse, rugby, darts, chess, table tennis, volleyball and more, each with its own competitions.