Polymarket is the world's largest prediction market, and all of its data is freely accessible through their Gamma API. No API key. No authentication. No rate limit (within reason).
Here's how to use it.
Setup
pip install requests
That's it. One dependency.
Fetch All Active Events
import requests
GAMMA_API = "https://gamma-api.polymarket.com"
resp = requests.get(f"{GAMMA_API}/events", params={
"closed": "false",
"limit": 50,
"order": "volume24hr",
"ascending": "false",
})
events = resp.json()
print(f"Got {len(events)} events")
for event in events[:5]:
print(f" {event['title']}: {len(event.get('markets', []))} markets")
Output:
Got 50 events
US Presidential Election Winner 2028: 24 markets
Fed Interest Rate Decision March 2026: 8 markets
Bitcoin Price on April 1: 12 markets
...
Get Market Prices
Each event contains markets with outcomePrices — a JSON string with [yes_price, no_price]:
import json
for event in events[:3]:
print(f"\n{event['title']}")
for market in event.get("markets", [])[:3]:
prices = json.loads(market.get("outcomePrices", "[]"))
if len(prices) >= 2:
yes_price = float(prices[0])
no_price = float(prices[1])
liquidity = float(market.get("liquidity", 0) or 0)
print(f" {market['question'][:50]}")
print(f" Yes: {yes_price:.1%}, No: {no_price:.1%}, Liq: ${liquidity:,.0f}")
Pagination
The API returns max 50 events per request. Use offset to paginate:
def get_all_events(max_pages=15):
all_events = []
offset = 0
for _ in range(max_pages):
resp = requests.get(f"{GAMMA_API}/events", params={
"closed": "false",
"limit": 50,
"offset": offset,
"order": "volume24hr",
"ascending": "false",
})
events = resp.json()
if not events:
break
all_events.extend(events)
offset += 50
return all_events
events = get_all_events()
total_markets = sum(len(e.get("markets", [])) for e in events)
print(f"{len(events)} events, {total_markets} markets")
# → 750 events, 12210 markets
Useful Endpoints
| Endpoint | Description |
|---|---|
GET /events |
List events with nested markets |
GET /events?slug=xyz |
Get specific event by slug |
GET /markets |
List markets (without event nesting) |
GET /markets?condition_id=xyz |
Get specific market |
Query Parameters
-
closed—true/false, filter by open/closed status -
limit— max results per page (default 50) -
offset— pagination offset -
order— sort field (volume24hr,liquidity,startDate) -
ascending—true/false -
tag_id— filter by category
Example: Find High-Volume Markets
import json
events = get_all_events(max_pages=5)
markets = []
for event in events:
for m in event.get("markets", []):
prices = json.loads(m.get("outcomePrices", "[]"))
if len(prices) >= 2:
markets.append({
"question": m["question"],
"yes": float(prices[0]),
"volume_24h": float(m.get("volume24hr", 0) or 0),
"liquidity": float(m.get("liquidity", 0) or 0),
})
# Top 10 by volume
markets.sort(key=lambda x: x["volume_24h"], reverse=True)
for m in markets[:10]:
print(f"${m['volume_24h']:>12,.0f} vol | {m['yes']:5.1%} | {m['question'][:50]}")
Example: Detect Mispricings
For events with multiple exclusive outcomes, the Yes prices should sum to 1.0:
for event in events:
markets_data = event.get("markets", [])
if len(markets_data) < 2:
continue
total_yes = 0
valid = 0
for m in markets_data:
prices = json.loads(m.get("outcomePrices", "[]"))
if len(prices) >= 2:
total_yes += float(prices[0])
valid += 1
if valid >= 2 and abs(total_yes - 1.0) > 0.05:
deviation = (total_yes - 1.0) * 100
print(f"{event['title'][:50]}")
print(f" Sum(Yes) = {total_yes:.4f} ({deviation:+.1f}% off)")
print(f" Markets: {valid}")
Caveat: Not all multi-market events have exclusive outcomes. Sports events often bundle match winner + O/U lines, which aren't exclusive. Only election-style "who will win" events are truly arbitrageable.
Rate Limiting
The Gamma API doesn't document rate limits, but in practice:
- Add
time.sleep(0.3)between paginated requests - Don't hammer it with concurrent requests
- Cache results for a few minutes
Or use our pre-built scanner API that handles all this: polymarket-scanner-api
Full scanner source code: GitHub
The Gamma API is one of the best free data sources for prediction market research. No signup, no billing, just requests.get().
Top comments (0)