Developer Documentation
Oddpool API
Prediction market data across Kalshi, Polymarket, and Opinion.
Overview
The Oddpool API provides programmatic access to prediction market data across Kalshi, Polymarket, and Opinion — including whale trades, cross-venue arbitrage, price spreads, and full-text search.
All API requests should be made to:
Quick start
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/arbitrage/current?min_net_cents=0.5"For AI agents
A machine-readable version of these docs is available at /llms.txt — fetch it to get the full API reference as structured markdown.
Authentication
Authenticate requests by including your API key in the X-API-Key header. Generate API keys from your account settings.
| Endpoint Group | Required Plan | Price |
|---|---|---|
| Whale Tracking | Pro | $30/mo |
| Arbitrage | Premium | $100/mo |
| Price Spreads | Premium | $100/mo |
| Search | Premium | $100/mo |
Security: Keep your API key confidential. Do not expose it in client-side code or public repositories.
Requests with invalid or expired credentials will receive a 401 or 403 response.
Rate Limits
API requests are rate limited to ensure platform stability.
| Limit | Rate |
|---|---|
| Burst | 10 requests/second |
| Sustained | 1,000 requests/minute |
Error Handling
The API uses standard HTTP response codes to indicate success or failure.
| Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad request — Invalid parameters |
| 401 | Unauthorized — Invalid API key |
| 403 | Forbidden — No active subscription or insufficient tier |
| 404 | Not found — Resource does not exist |
| 429 | Rate limit exceeded |
| 500 | Server error |
Error response format:
{"detail": "Error message"}Whale Tracking
ProProgrammatic access to Whale Tracker. Build trading signals, power automated agents, or integrate whale alerts into your own workflows however you want to use them.
/whales/user/eventsList all events you are currently tracking.
Example
curl -H "X-API-Key: your_api_key" \
https://api.oddpool.com/whales/user/eventsResponse
{
"tracked_events": [
{
"id": 65,
"event_id": 65,
"event_ticker": "KXBUNDESLIGAGAME-26JAN14KOEBMU",
"event_title": "1. FC Cologne vs Bayern Munich",
"platform": "kalshi",
"whale_threshold_usd": 1000,
"notify_on_whale_trade": true,
"whale_count_24h": 12
}
]
}/whales/user/feedGet whale trades for all your tracked events.
Parameters
| Name | Type | Description |
|---|---|---|
limit | integer | Max results (1-500)(default: 50) |
offset | integer | Pagination offset(default: 0) |
start_date | datetime | Filter by start date (ISO 8601) |
end_date | datetime | Filter by end date (ISO 8601) |
min_trade_size | float | Minimum trade size in USD |
platform | string | Filter by platform: kalshi, polymarket |
event_id | integer | Filter to specific event |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/whales/user/feed?limit=10&platform=kalshi"Response
{
"trades": [
{
"id": 12345,
"platform": "kalshi",
"event_title": "1. FC Cologne vs Bayern Munich",
"market_title": "Winner: Bayern Munich",
"market_ticker": "KXBUNDESLIGAGAME-26JAN14KOEBMU-BMU",
"outcome": "Bayern Munich",
"timestamp": "2026-01-14T21:24:25Z",
"taker_side": "yes",
"trade_size_usd": 15000.00,
"price": 0.78,
"count": 1
}
],
"stats": {
"total_volume_24h": 185195.0,
"total_trades_24h": 151,
"avg_trade_size": 1226.46
},
"pagination": {"limit": 10, "offset": 0, "total": 151}
}/whales/user/statsGet aggregated statistics for all tracked events.
Parameters
| Name | Type | Description |
|---|---|---|
period | string | Time period: 24h, 7d, all(default: 24h) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/whales/user/stats?period=7d"Response
{
"period": "7d",
"events": [
{
"event_id": 65,
"event_ticker": "KXBUNDESLIGAGAME-26JAN14KOEBMU",
"event_title": "1. FC Cologne vs Bayern Munich",
"platform": "kalshi",
"stats": {
"trade_count": 151,
"total_volume": 185195.0,
"avg_trade_size": 1226.46,
"market_count": 3
},
"markets": [...]
}
]
}/whales/user/event/{event_id}Get whale trades for a specific tracked event.
Parameters
| Name | Type | Description |
|---|---|---|
event_idrequired | integer | Event ID (path) |
limit | integer | Max results (1-500)(default: 50) |
offset | integer | Pagination offset(default: 0) |
min_trade_size | float | Minimum trade size in USD |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/whales/user/event/65?limit=20"/whales/user/event/{event_id}/statsGet statistics for a specific tracked event.
Parameters
| Name | Type | Description |
|---|---|---|
event_idrequired | integer | Event ID (path) |
period | string | Time period: 24h, 7d, all(default: 24h) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/whales/user/event/65/stats?period=all"Response
{
"event_id": 65,
"event_ticker": "KXBUNDESLIGAGAME-26JAN14KOEBMU",
"event_title": "1. FC Cologne vs Bayern Munich",
"platform": "kalshi",
"period": "all",
"stats": {
"trade_count": 151,
"total_volume": 185195.0,
"avg_trade_size": 1226.46,
"market_count": 3,
"first_trade_at": "2026-01-14T19:51:59Z",
"last_trade_at": "2026-01-14T21:24:25Z"
},
"markets": [
{
"market_ticker": "KXBUNDESLIGAGAME-26JAN14KOEBMU-BMU",
"platform": "kalshi",
"trade_count": 124,
"total_volume": 156445.15,
"avg_trade_size": 1261.65
}
]
}/whales/user/marketsList all markets for your tracked events.
Example
curl -H "X-API-Key: your_api_key" \
https://api.oddpool.com/whales/user/marketsResponse
{
"markets": [
{
"market_id": 370,
"market_ticker": "KXBUNDESLIGAGAME-26JAN14KOEBMU-BMU",
"market_title": "Winner: Bayern Munich",
"event_id": 65,
"event_title": "1. FC Cologne vs Bayern Munich",
"platform": "kalshi",
"whale_count_24h": 45
}
],
"total_markets": 3
}/whales/user/market/{market_id}/statsGet statistics for a specific market.
Parameters
| Name | Type | Description |
|---|---|---|
market_idrequired | integer | Market ID (path) |
period | string | Time period: 24h, 7d, all(default: 24h) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/whales/user/market/370/stats?period=all"Response
{
"market_id": 370,
"market_ticker": "KXBUNDESLIGAGAME-26JAN14KOEBMU-BMU",
"market_title": "Winner: Bayern Munich",
"platform": "kalshi",
"period": "all",
"stats": {
"period": "all",
"trade_count": 124,
"total_volume": 156445.15,
"avg_trade_size": 1261.65,
"first_trade_at": "2026-01-14T19:51:59Z",
"last_trade_at": "2026-01-14T21:24:25Z"
}
}/whales/user/market/{market_id}/tradesGet whale trades for a specific market.
Parameters
| Name | Type | Description |
|---|---|---|
market_idrequired | integer | Market ID (path) |
limit | integer | Max results (1-500)(default: 50) |
offset | integer | Pagination offset(default: 0) |
min_trade_size | float | Minimum trade size in USD |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/whales/user/market/370/trades?limit=10"Arbitrage
PremiumProgrammatic access to Arbitrage Dashboard and Price Spreads. Two types of cross-venue signals, updated in real time.
What you can build
- Arb bot: poll for risk-free cross-venue opportunities and execute automatically
- Spread alerts: get notified when venue disagreement exceeds your threshold
- Price dashboard: track how the same outcome is priced across Kalshi, Polymarket, and Opinion
/arbitrage/currentFind markets where buying YES on one venue and NO on another costs less than $1 combined. The gap is risk-free profit.
Parameters
| Name | Type | Description |
|---|---|---|
min_net_cents | float | Minimum net profit after fees, in cents(default: 0) |
minutes | integer | Lookback window in minutes(default: 10000) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/arbitrage/current?min_net_cents=0.5&minutes=10"Response
net_cents is your per-contract profit after all fees.
[
{
"event_id": 42,
"event_title": "Fed rate decision March",
"kalshi_event_ticker": "KXFEDDECISION-26MAR",
"polymarket_event_slug": "fed-rate-march",
"opinion_market_id": null,
"market_type": "binary",
"outcome_key": "yes",
"label": "25bps cut",
"timestamp": "2026-03-11T14:30:00",
"resolution_time": "2026-03-19T18:00:00",
"kalshi": {
"yes_ask": 0.42, "no_ask": 0.60,
"volume": 150000, "volume_24h": 12000,
"open_interest": 80000
},
"polymarket": {
"yes_ask": 0.39, "no_ask": 0.63,
"volume": 200000.0, "volume_24h": 15000.0,
"liquidity": 50000.0
},
"opinion": {
"yes_ask": null, "no_ask": null,
"volume": null, "volume_24h": null,
"liquidity": null
},
"buy_yes_market": "polymarket",
"buy_no_market": "kalshi",
"gross_cents": 1.0,
"fee_cents": 0,
"net_cents": 1.0
}
]/arbitrage/current/differenceFind where venues disagree on the same outcome's price. A large spread signals potential mispricing.
Parameters
| Name | Type | Description |
|---|---|---|
minutes | integer | Lookback window in minutes(default: 10000) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/arbitrage/current/difference?minutes=10"Response
[
{
"event_id": 42,
"event_title": "Fed rate decision March",
"kalshi_event_ticker": "KXFEDDECISION-26MAR",
"polymarket_event_slug": "fed-rate-march",
"opinion_market_id": null,
"market_type": "binary",
"outcome_key": "yes",
"label": "25bps cut",
"timestamp": "2026-03-11T14:30:00",
"resolution_time": "2026-03-19T18:00:00",
"side": "YES",
"side1": "Kalshi",
"side2": "Polymarket",
"side1_price": 0.42,
"side2_price": 0.39,
"diff": 0.03
}
]Search
PremiumProgrammatic access to Market Search. Query, filter, and discover prediction markets across Kalshi and Polymarket.
What you can build
- Alert bot: poll for new markets matching keywords using
discovered_after - Custom screener: filter by volume, liquidity, exchange, category
- Market monitor: track all markets under a specific event
/search/marketsFull-text search across all prediction markets with filtering and sorting.
Parameters
| Name | Type | Description |
|---|---|---|
qrequired | string | Search query |
exchange | string | Filter: kalshi or polymarket |
status | string | Filter: active or closed(default: active) |
category | string | Filter by category |
min_volume | integer | Minimum volume |
min_liquidity | integer | Minimum liquidity |
sort_by | string | relevance, newest, volume, or liquidity(default: relevance) |
discovered_after | string | ISO timestamp filter. Tip: use this to poll for new market listings. |
limit | integer | Max results (1-100)(default: 20) |
offset | integer | Pagination offset(default: 0) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/search/markets?q=fed+rate&exchange=kalshi&sort_by=volume"Response
[
{
"market_id": "KXFEDDECISION-26MAR-T4.75",
"exchange": "kalshi",
"question": "Will the Fed cut rates by 25bps in March?",
"category": "economics",
"status": "active",
"volume": 150000,
"liquidity": 80000,
"last_yes_price": "0.42",
"last_no_price": "0.60",
"has_orderbook": true,
"event_id": "KXFEDDECISION-26MAR",
"event_title": "Fed Rate Decision March 2026",
"slug": null,
"discovered_at": "2026-02-15T10:00:00"
}
]/search/eventsSearch across prediction market events. An event like 'Fed Rate Decision March' contains markets for each possible outcome.
Parameters
| Name | Type | Description |
|---|---|---|
qrequired | string | Search query |
exchange | string | Filter: kalshi or polymarket |
status | string | Filter: active or closed(default: active) |
category | string | Filter by category |
sort_by | string | relevance, newest, markets, volume, or liquidity(default: relevance) |
discovered_after | string | ISO timestamp filter |
limit | integer | Max results (1-100)(default: 20) |
offset | integer | Pagination offset(default: 0) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/search/events?q=election&sort_by=volume"Response
[
{
"event_id": "KXPRESIDENTIAL-28NOV",
"exchange": "kalshi",
"title": "2028 Presidential Election",
"category": "politics",
"status": "active",
"discovered_at": "2026-01-10T08:00:00",
"market_count": 12,
"total_volume": 5000000,
"total_liquidity": 1200000,
"market_questions": [
"Will the Democratic nominee win?",
"Will the Republican nominee win?"
]
}
]/search/recent/marketsLatest market listings. Useful for new-listing alerts without a search query.
Parameters
| Name | Type | Description |
|---|---|---|
exchange | string | Filter: kalshi or polymarket |
limit | integer | Max results (1-100)(default: 30) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/search/recent/markets?limit=10"/search/recent/eventsLatest event listings. Useful for new-listing alerts without a search query.
Parameters
| Name | Type | Description |
|---|---|---|
exchange | string | Filter: kalshi or polymarket |
limit | integer | Max results (1-100)(default: 30) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/search/recent/events?exchange=polymarket"/search/events/{event_id}/marketsList all markets under one event. Use after finding an event via search to see every tradeable outcome.
Parameters
| Name | Type | Description |
|---|---|---|
event_idrequired | string | Event ID (path) |
Example
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/search/events/KXFEDDECISION-26MAR/markets"Support
Questions about the API? Contact us at avi@oddpool.com