Kalshi sports event contracts account for 75-90% of the platform’s total trading volume, with weekly notional regularly exceeding $2.3 billion and peaking at $3.4 billion during March Madness 2026. This guide covers every sports contract type available — moneylines, spreads, totals, player props, and combos — with API examples, odds conversion formulas, and strategies for building sports trading agents.
How Sports Contracts Work on Kalshi
Every Kalshi sports contract is a binary yes/no question that settles at $1.00 (yes) or $0.00 (no). The price you pay in cents equals the market’s implied probability of that outcome. Buy “Will the Chiefs win?” at $0.65, and you’re paying 65 cents for a contract the market prices at 65% likely. If correct, you receive $1.00 — a profit of $0.35 per contract. If wrong, you lose your $0.65.
The spread between yes and no prices reflects the market’s built-in margin. If yes trades at $0.65 and no trades at $0.37, the $0.02 gap is the effective spread — analogous to the vig in traditional sports betting, but set by supply and demand rather than a bookmaker.
Settlement uses official data sources. Kalshi partnered with STATSCORE in September 2025 to provide live score updates and settlement data across sports markets.
The structural differences from traditional sportsbooks matter for agents:
- Peer-to-peer exchange: No house setting lines. Every trade has a counterparty on the other side. This is the fundamental difference compared to Polymarket and traditional books alike.
- CFTC regulated: Operates as a Designated Contract Market, not under state gaming commissions. This creates the state-by-state legal complexity that agents must account for.
- 18+ age requirement: Not 21+ like most sportsbooks.
- No account restrictions for winning: Sportsbooks limit sharp bettors. Kalshi cannot — every trade clears through the central order book.
Contract Types
Kalshi offers five primary sports contract types. Each maps to a familiar sportsbook product but trades as a binary contract.
| Contract Type | Kalshi Format | Sportsbook Equivalent | Example |
|---|---|---|---|
| Game outcome | “Will Team A win?” | Moneyline | Chiefs to beat Ravens: Yes $0.65 |
| Spread | “Will Team A win by 7+?” | Point spread | Chiefs -6.5: Yes $0.48 |
| Total | “Will combined score exceed 47?” | Over/under | Over 47.5: Yes $0.52 |
| Player prop | “Will Player X score 2+ TDs?” | Player prop | Mahomes 2+ TDs: Yes $0.35 |
| Combo | Multiple contracts combined | Parlay | Chiefs win + Over 47.5: Yes $0.34 |
Player props expanded significantly in 2025, covering touchdowns, points, yards, strikeouts, assists, and other stat lines. Kalshi added NBA props as sportsbooks pulled back from prop markets following prop betting integrity concerns.
Combos launched in September 2025 as a beta for select NFL games, then expanded to all users for pro football and pro basketball. Each combo is a unique market with its own dedicated order book. Unlike sportsbook parlays where the house compounds vig across every leg (reaching ~13% effective edge on a three-leg parlay), Kalshi combos use a Request For Quote (RFQ) system — when you request a combo, other traders provide liquidity by quoting prices. This eliminates the compounding vig problem.
Combo volume grew from under 5% of sports trading volume at launch to over 20% during March Madness 2026.
Converting Between Kalshi Prices and Sportsbook Odds
Kalshi prices are implied probabilities expressed in cents. Converting to and from traditional odds formats is essential for cross-market arbitrage and for agents that compare prices across platforms.
Conversion Formulas
# kalshi_odds.py — Bidirectional odds conversion
def kalshi_to_american(cents: float) -> str:
"""Convert Kalshi price (0.01-0.99) to American odds string."""
if cents >= 1.0 or cents <= 0.0:
raise ValueError("Price must be between 0.01 and 0.99")
if cents >= 0.50:
odds = -(cents / (1 - cents)) * 100
return f"{int(round(odds))}"
else:
odds = ((1 - cents) / cents) * 100
return f"+{int(round(odds))}"
def american_to_kalshi(american: int) -> float:
"""Convert American odds to Kalshi price (decimal)."""
if american < 0:
return round(abs(american) / (abs(american) + 100), 2)
else:
return round(100 / (american + 100), 2)
def kalshi_to_decimal(cents: float) -> float:
"""Convert Kalshi price to decimal (European) odds."""
return round(1 / cents, 3)
def implied_probability(cents: float) -> float:
"""Kalshi price IS the implied probability."""
return cents
# Combo pricing: multiply individual contract prices
def combo_price(legs: list[float]) -> float:
"""Calculate combo price from individual leg prices."""
price = 1.0
for leg in legs:
price *= leg
return round(price, 4)
# Example usage
print(kalshi_to_american(0.65)) # -186
print(kalshi_to_american(0.35)) # +186
print(american_to_kalshi(-150)) # 0.6
print(combo_price([0.65, 0.52])) # 0.338
Odds Conversion Reference Table
| Kalshi Price | Implied Prob | American Odds | Decimal Odds | $100 Profit if Yes |
|---|---|---|---|---|
| $0.10 | 10% | +900 | 10.000 | $900 |
| $0.20 | 20% | +400 | 5.000 | $400 |
| $0.25 | 25% | +300 | 4.000 | $300 |
| $0.33 | 33% | +203 | 3.030 | $203 |
| $0.40 | 40% | +150 | 2.500 | $150 |
| $0.50 | 50% | +100 / -100 | 2.000 | $100 |
| $0.60 | 60% | -150 | 1.667 | $67 |
| $0.65 | 65% | -186 | 1.538 | $54 |
| $0.75 | 75% | -300 | 1.333 | $33 |
| $0.80 | 80% | -400 | 1.250 | $25 |
| $0.90 | 90% | -900 | 1.111 | $11 |
| $0.95 | 95% | -1900 | 1.053 | $5 |
For agent-ready conversion utilities, see the OpenClaw Odds Converter Skill.
Available Sports and Liquidity
Sports dominate Kalshi’s volume — 86-91% of total weekly notional as of early 2026. Robinhood routes more than 50% of retail sports volume through Kalshi, making it the primary discovery channel for new users.
| Sport | Contract Types | Liquidity Depth | Season / Availability |
|---|---|---|---|
| NFL | Outcomes, spreads, totals, props, combos | Institutional-grade | Sep–Feb (incl. playoffs, Super Bowl) |
| NBA | Outcomes, spreads, totals, props, combos | Institutional-grade | Oct–Jun (incl. playoffs) |
| MLB | Outcomes, totals, props | Moderate | Apr–Oct |
| NHL | Outcomes, totals | Moderate | Oct–Jun |
| NCAAF | Outcomes, spreads, totals | Strong during season | Sep–Jan (bowl season peak) |
| NCAAB | Outcomes, spreads, totals, combos | Strong (March Madness peak) | Nov–Apr |
| Soccer | Outcomes | Light | Year-round (major leagues) |
| Golf | Tournament outcomes | Light | Year-round (majors peak) |
| Tennis | Match outcomes | Light | Year-round (Grand Slams peak) |
| UFC/MMA | Fight outcomes | Light | Event-based |
NFL and NBA game outcomes carry the deepest order books. During their respective seasons, these markets absorb institutional-sized orders with minimal slippage. Kalshi captured roughly 1.5% of the total U.S. sports betting market in 2025, rising to approximately 3% during NFL season.
Player props and smaller sports have thinner books. Agent builders should factor liquidity depth into position sizing — the Kelly Criterion fraction should scale with available depth to avoid moving the market against your own orders.
API Access for Sports Markets
Kalshi’s unified REST API handles market data, order management, and portfolio tracking through a single base URL. The WebSocket API provides real-time streaming for live trading.
Base URLs:
- REST:
https://api.elections.kalshi.com/trade-api/v2 - WebSocket:
wss://api.elections.kalshi.com/trade-api/ws/v2 - Demo (paper trading):
https://demo-api.kalshi.co/trade-api/v2
Despite the elections subdomain, the REST API serves all market categories including sports.
As of March 12, 2026, Kalshi removed legacy integer-cent price fields. Use yes_price_dollars (decimal, e.g., 0.45) instead of the deprecated yes_price (integer cents). See the Kalshi API guide for full authentication setup with RSA keys and the Python SDK.
Fetching Sports Markets
# fetch_sports_markets.py — Get open sports markets from Kalshi REST API v2
import requests
BASE_URL = "https://api.elections.kalshi.com/trade-api/v2"
def get_sports_filters() -> dict:
"""Retrieve available sports filter hierarchy."""
resp = requests.get(f"{BASE_URL}/search/filters_by_sport")
resp.raise_for_status()
return resp.json()
def get_markets_by_series(series_ticker: str, status: str = "open") -> list:
"""
Fetch markets filtered by series ticker.
Sports series tickers follow patterns like:
KXNFL — NFL game markets
KXNBA — NBA game markets
KXMLB — MLB game markets
KXNHL — NHL game markets
"""
params = {
"series_ticker": series_ticker,
"status": status,
"limit": 200,
}
markets = []
cursor = None
while True:
if cursor:
params["cursor"] = cursor
resp = requests.get(f"{BASE_URL}/markets", params=params)
resp.raise_for_status()
data = resp.json()
markets.extend(data.get("markets", []))
cursor = data.get("cursor")
if not cursor:
break
return markets
def extract_market_data(market: dict) -> dict:
"""Pull the fields an agent needs from a market response."""
return {
"ticker": market["ticker"],
"event_ticker": market["event_ticker"],
"title": market["title"],
"yes_price": market.get("yes_price_dollars", 0),
"no_price": market.get("no_price_dollars", 0),
"volume": market.get("volume", 0),
"open_interest": market.get("open_interest", 0),
"close_time": market.get("close_time"),
"status": market["status"],
}
# Example: fetch all open NFL markets
nfl_markets = get_markets_by_series("KXNFL")
for m in nfl_markets[:5]:
data = extract_market_data(m)
print(f"{data['ticker']}: {data['title']} | Yes: ${data['yes_price']}")
Streaming Live Price Updates
# stream_sports.py — WebSocket live price streaming for sports markets
import json
import websocket
WS_URL = "wss://api.elections.kalshi.com/trade-api/ws/v2"
def on_open(ws):
"""Subscribe to orderbook and ticker channels for a sports market."""
subscribe_msg = {
"id": 1,
"cmd": "subscribe",
"params": {
"channels": ["orderbook_delta", "ticker"],
"market_tickers": ["KXNFL-26MAR28-KC-BUF"]
}
}
ws.send(json.dumps(subscribe_msg))
print("Subscribed to live updates")
def on_message(ws, message):
"""Handle incoming price updates."""
data = json.loads(message)
msg_type = data.get("type")
if msg_type == "ticker":
ticker = data["msg"]["market_ticker"]
yes_price = data["msg"].get("yes_price_dollars", "N/A")
print(f"[TICKER] {ticker}: Yes ${yes_price}")
elif msg_type == "orderbook_delta":
ticker = data["msg"]["market_ticker"]
print(f"[BOOK] {ticker}: depth update received")
def on_error(ws, error):
print(f"WebSocket error: {error}")
def on_close(ws, close_status_code, close_msg):
print("Connection closed")
# Note: production use requires authentication headers
# See /guides/kalshi-api-guide/ for RSA auth setup
ws = websocket.WebSocketApp(
WS_URL,
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close,
)
ws.run_forever()
The WebSocket API handles data streaming only — order placement goes through REST endpoints. This separation of concerns is standard for exchange APIs and means your agent architecture should use separate threads or async tasks for market data ingestion and order execution. For the full API reference across platforms, see the Prediction Market API Reference.
Cross-Market Arbitrage with Sportsbooks
Kalshi sports contracts map directly to sportsbook products, creating opportunities for cross-market arbitrage. When the implied probabilities across platforms sum to less than 100% after fees, a risk-free profit exists.
The cross-market arbitrage guide covers the full theory. Here we focus on the Kalshi-specific implementation.
The Odds API as the Data Bridge
The Odds API provides real-time odds from 40+ sportsbooks in a single normalized format. Your agent fetches Kalshi prices via the REST API and sportsbook odds via The Odds API, then scans for discrepancies.
Fee-Adjusted Arbitrage Threshold
Raw price differences must exceed the combined fees on both sides. Kalshi charges a maximum of $0.02 per contract in taker fees (formula-based, often lower). See the Kalshi fees guide for exact calculations. Sportsbook vig is embedded in the odds — typically 4-5% on moneylines, higher on props.
For an arbitrage to be real after fees:
kalshi_yes_price + sportsbook_implied_no_price < 1.00 - total_fees
Worked Example
An NFL game: Kalshi prices Chiefs to win at $0.65 (Yes). A sportsbook offers Ravens at +175 (implied 36.4% = $0.364 equivalent). The sum of implied probabilities: 0.65 + 0.364 = 1.014. No arbitrage — the market is efficient here. But when a sportsbook offers Ravens at +200 (implied 33.3%), the sum drops to 0.983. After Kalshi’s ~$0.02 fee and the sportsbook vig, this edge may or may not survive. Agents must compute net-of-fees returns on both legs before executing.
For cross-platform arbitrage bot architectures, the execution speed matters — stale prices kill arbs.
Agent Strategies for Kalshi Sports
Sports contracts offer the deepest liquidity on Kalshi and the most direct mapping to traditional sportsbook products. Here are five agent strategies ranked by complexity.
Live Arbitrage Scanning
Compare Kalshi prices against The Odds API or offshore book data in real time. Use the WebSocket feed for Kalshi-side updates and poll The Odds API at its rate limit (varies by plan). When a spread exceeds your fee-adjusted threshold, place both legs simultaneously. Execution latency is the binding constraint — see the Kalshi API guide for connection optimization.
Momentum Trading on In-Game Contracts
During live events, Kalshi contract prices shift with game flow. An agent can track momentum — consecutive scores, possession changes, clock state — and trade contracts before the order book fully adjusts. This requires the WebSocket stream plus an external live data feed (STATSCORE, ESPN API, or similar). The Vig Index can help identify markets where the spread widens during live events.
News-Driven Prop Trading
Injury reports, lineup changes, and weather updates directly affect player props. An agent monitoring news feeds (Twitter/X, team RSS, beat reporter alerts) can trade props before the market prices in new information. The Kalshi News Bot provides a starting framework. Combine with the prediction market math fundamentals for Bayesian updating of prop probabilities.
Combo Construction
Automate multi-leg combo building based on correlation analysis. If two outcomes are positively correlated (e.g., a high-scoring team wins AND the total goes over), the combo price may underestimate the joint probability. Your agent can estimate true correlations from historical data and identify mispriced combos. Currently combos are available for pro football, pro basketball, and select other markets.
Volume-Weighted Market Making
On thinner markets (MLB props, college games, smaller sports), an agent can provide liquidity by placing both yes and no limit orders around a fair-value estimate. Profit comes from the spread between your bid and ask. This strategy requires robust position sizing and inventory management — you need to flatten exposure before settlement. The Kalshi tracker skill can monitor your open positions across markets.
For a deeper look at sharp betting strategies and the analytical tools available, explore the Kalshi API tools page.
