Tony Wang8 min readHow to Scrape Polymarket in 2026 (API & Python)
Polymarket splits public reads across Gamma, CLOB, and Data APIs — no key needed. Here's when to call them directly, and when a structured API is easier.
Polymarket already publishes open, credential-free JSON for its market data — but it's spread across three separate services with three different id schemes: Gamma for discovering events and markets, CLOB for live order books and prices, and a Data API for account and trade activity. So the honest answer for "how to scrape Polymarket" in 2026 is: for most read use cases, call Polymarket's own APIs directly. What gets tedious is that there's no single client tying Gamma, CLOB, and Data together, and Gamma's raw response shape has some rough edges (stringified JSON fields) you have to work around. This guide covers Polymarket's own APIs, a DIY Python pull against them, and when a structured API is worth adding on top.
Why scrape Polymarket data?
- Market-implied probability tracking — Polymarket is the largest prediction market by volume, so its "Yes" price is a liquid, real-money read on how likely traders think an outcome is, for elections, Fed decisions, sports, and pop-culture events alike.
- Arbitrage and cross-platform signal — compare Polymarket's odds against Kalshi, polls, or expert forecasts to see where different markets and crowds disagree.
- Order book and liquidity research — Polymarket prices each outcome as its own CLOB token, so depth, spread, and midpoint are available per contract for quant and market-microstructure research.
- Sentiment and forecasting datasets — feed live event probabilities into research agents, news widgets, or dashboards that need a numeric read on an uncertain outcome.
- Academic research on crowd forecasting — Polymarket's scale (thousands of active markets, deep order books on the biggest ones) makes it a common dataset for studying how well prediction markets forecast real-world events.
Is it legal to scrape Polymarket?
Option 1: Polymarket's own official APIs (and their limits)
For Polymarket specifically, its own APIs are the first thing to reach for — they're public, documented, and return the same data you'd otherwise scrape:
curl "https://gamma-api.polymarket.com/markets?limit=5&order=volume24hr&ascending=false"
No x-api-key, no OAuth, no account needed for reads. What it covers and where it still has friction:
- Reads are open across all three services. Gamma (events/markets discovery), CLOB (prices, order books, trade history), and Data (account/activity) all serve public data without an API key — only placing or managing orders requires a Polygon wallet-derived signature via Polymarket's official TypeScript or Python SDK.
- Rate limits are Cloudflare IP-based, per endpoint. Per the official rate limits page, Gamma's
/marketsallows 300 req/10s and/events500 req/10s; CLOB's/bookand/priceallow 1,500 req/10s each. Limits throttle rather than hard-reject, on a sliding window — but a heavy poller across many tokens can still queue up. - Three services, three id schemes, no shared client. An event has a
slug; a market has anid, its ownslug, and an on-chainconditionId; each outcome inside that market has a separate CLOBtoken_idused for price, order book, midpoint, and spread calls. You resolve the chain yourself — Gamma for ids, CLOB for live numbers. - Gamma's raw fields aren't all ready to use. The Markets endpoint's schema types
outcomesandoutcomePricesas plain strings, not arrays — they come back as JSON-encoded text (e.g.'["Yes","No"]') that youjson.loads()yourself before you have a real list.
Option 2: DIY in Python against Gamma and CLOB
A minimal DIY pull looks like this — one call to discover a market, a second to price one of its outcomes:
import json
import requests
GAMMA = "https://gamma-api.polymarket.com"
CLOB = "https://clob.polymarket.com"
markets = requests.get(f"{GAMMA}/markets", params={
"limit": 5, "order": "volume24hr", "ascending": False, "closed": "false",
}).json() # a bare array — no envelope
top = markets[0]
outcomes = json.loads(top["outcomes"]) # '["Yes","No"]' -> ["Yes", "No"]
token_ids = json.loads(top["clobTokenIds"]) # same trick for the token id list
price = requests.get(f"{CLOB}/price", params={"token_id": token_ids[0], "side": "buy"}).json()
book = requests.get(f"{CLOB}/book", params={"token_id": token_ids[0]}).json()
This works fine for a single script. The tradeoffs show up once you're pulling multiple markets or platforms:
- You own the JSON-string parsing.
outcomes,outcomePrices, andclobTokenIdsall arrive as encoded strings on the raw Gamma response — a small but recurring bit of glue code every integration re-writes. - No unified auth or normalization across sources. If you're also pulling Kalshi, Metaculus, or traditional market data, each has its own base URL, id scheme, and rate-limit behavior to reconcile.
- You still own the polling and storage. Neither Gamma nor CLOB retries, dedupes, or timestamps your pulls for you — that's on your code either way.
Option 3: A structured Polymarket API
The value-add of a Polymarket scraping API isn't unlocking data Polymarket hides — it's one normalized, snake_case schema and one x-api-key across Gamma, CLOB, Data, and every other platform in the catalog, with outcomes and token ids already parsed into real arrays. List active markets by 24-hour volume:
curl "https://api.crawlora.net/api/v1/polymarket/markets?limit=5&order=volume24hr" \
-H "x-api-key: $CRAWLORA_API_KEY"
Markets, a specific market by slug, and events in Python:
import requests
h = {"x-api-key": "YOUR_API_KEY"}
base = "https://api.crawlora.net/api/v1/polymarket"
markets = requests.get(f"{base}/markets", headers=h,
params={"limit": 5, "order": "volume24hr"}).json()["data"]["markets"]
market = requests.get(f"{base}/market/slug/will-the-fed-increase-interest-rates-by-25-bps-after-the-september-2026-meeting-649",
headers=h).json()["data"]
events = requests.get(f"{base}/events", headers=h,
params={"limit": 5, "order": "volume24hr"}).json()["data"]["events"]
A market detail response is normalized JSON you can store directly (real fields, from a live pull):
{
"code": 200,
"msg": "OK",
"data": {
"id": "2252245",
"slug": "will-the-fed-increase-interest-rates-by-25-bps-after-the-september-2026-meeting-649",
"condition_id": "0x876506d8b2bd7a0d3fa4fe18c024eee6e1dd81ee24c26795dadd6cfe4a7b5d0d",
"market": {
"question": "Will the Fed increase interest rates by 25 bps after the September 2026 meeting?",
"active": true,
"closed": false,
"best_bid": 0.41,
"best_ask": 0.42,
"last_trade_price": 0.41,
"liquidity": 669602.9468,
"volume": 5588803.527363,
"volume_24h": 1116366.822159,
"end_date": "2026-09-16T00:00:00Z",
"token_ids": [
"63842529068710005716169325380315470359047749786610778647370693404952498013178",
"2881957189963819690709899387312951271986076905757701114514025622922000576600"
],
"outcomes": [
{ "outcome": "Yes", "price": 0.415, "volume": 5588803.527363 },
{ "outcome": "No", "price": 0.585, "volume": 5588803.527363 }
]
},
"source_url": "https://gamma-api.polymarket.com/markets/2252245",
"fetched_at": "2026-08-11T07:26:38Z"
}
}
Live price, order book, and price history for a specific outcome token behind the same key:
token_id = market["market"]["token_ids"][0] # the "Yes" outcome
price = requests.get(f"{base}/token/{token_id}/price", headers=h,
params={"side": "buy"}).json()["data"]
book = requests.get(f"{base}/token/{token_id}/orderbook", headers=h).json()["data"]
history = requests.get(f"{base}/token/{token_id}/price-history", headers=h,
params={"interval": "1d"}).json()["data"]
search = requests.get(f"{base}/search", headers=h,
params={"q": "bitcoin", "sort": "volume24hr"}).json()["data"]
Markets are addressed by id, slug, or on-chain condition_id; events by slug or id; and every individual outcome (each Yes/No contract) has its own token_id used for price, orderbook, midpoint, spread, and price-history calls — that extra layer of ids is where Polymarket's granularity, and its complexity, both come from. Every response carries source_url and fetched_at, so store the timestamp with each row and re-pull on a schedule.
What you can collect
- Markets — id, slug, condition_id, question, active/closed status, best bid/ask, last trade price, liquidity, and volume, listed or looked up individually.
- Events — the grouping layer above markets: title, description, tags, market count, combined liquidity/volume, and start/end dates for a topic (e.g. all the strike-price markets under one "Bitcoin above ___" event).
- Token-level pricing — live price by buy/sell side, midpoint, spread, and the full order book (bids and asks with size) for a single outcome, plus batch variants for pricing several tokens in one call.
- Price history — a time series of price points for a token at a chosen interval, from
1mup tomax. - Tags — market and event categorization, plus related-tag lookups for browsing by topic.
- Leaderboard and activity — trader leaderboard rankings and a feed of recent trade activity, filterable by size.
- Search — free-text search across events, sortable by relevance, volume, or liquidity.
Limitations
- Public market data, not investment advice. A "Yes" price is the market's implied probability, not a guarantee of the outcome — treat it as a signal, not a forecast, and see Polymarket's own Terms of Use before commercial use.
- Not a trading connection. These reads don't place or manage orders — that requires Polymarket's own wallet-based CLOB client and a funded, connected account, which is a different integration entirely.
- Rate-limited by IP, even on reads. Cloudflare enforces per-endpoint sliding-window limits on Gamma and CLOB (see Option 1) — a heavy poller should still back off rather than assume unlimited throughput.
- Markets resolve and close. A
closed: truemarket's price freezes at resolution; treat historical/settled markets as archival data, not a live feed. - Not real-time guaranteed. Store
fetched_atwith every pull and treat values as research inputs, not a substitute for Polymarket's own live order book if you're actually trading.
Where this gets used
- Forecasting and probability dashboards — track how Polymarket's implied odds move for an event over time, across every outcome in a multi-strike event.
- Cross-platform sentiment comparison — set Polymarket prices beside Kalshi, polls, or news coverage of the same event.
- Quant and market-microstructure research — per-token order books and price history for spread and liquidity research.
- AI agents and research tools — a numeric probability read on real-world events for downstream reasoning.
Sources
Start collecting
Try it first, free: run any public URL through the Free Web Scraper, or check whether a site blocks bots with the Anti-Bot Checker — no signup.
Test the markets endpoint in the Playground, check the schema in the API docs, and review pricing. For the other major regulated event exchange, how to scrape Kalshi covers a single-ticker market with a CFTC-regulated framing instead of Polymarket's per-token order-book depth. For a forecast source without real-money stakes, how to scrape Metaculus tracks community-forecaster probabilities on similar events, and how to scrape CoinGecko covers the crypto prices that show up as resolution sources on many Polymarket markets. See the broader prediction market data use case for how these sources fit together. For the legal basics of any of this, see is web scraping legal.
Part of our how-to-scrape guide series — every platform we cover, in one index.
Frequently asked questions
Does Polymarket have an official API?
Yes. Polymarket splits its public API surface across several services — the Gamma API (gamma-api.polymarket.com) for discovering events and markets, the CLOB API (clob.polymarket.com) for live prices, order books, and trading, and a separate Data API for account and trade activity. Reading market data from Gamma and CLOB doesn't require an account or API key.
Do I need a Polymarket API key to read market data?
No. Polymarket's own Gamma and CLOB read endpoints are credential-free and unauthenticated — anyone can call them directly. A wallet-derived API key, via Polymarket's official TypeScript or Python SDK, is only needed to place or manage orders. A Crawlora API key is separate again, needed only if you use the structured API in this guide to get one schema across Gamma, CLOB, and other platforms.
How do I use the Polymarket API in Python?
For a quick pull, requests.get("https://gamma-api.polymarket.com/markets", params={"limit": 10, "order": "volume24hr"}) returns a plain JSON array of markets, no auth headers needed. Live prices and order books come from a second base URL, https://clob.polymarket.com, keyed by a per-outcome token_id you get out of the market response.
What's the difference between Polymarket's Gamma API and CLOB API?
Gamma is the discovery and catalogue layer — events, markets, tags, and metadata. CLOB is the live order-book and trading layer — best bid and ask, midpoint, spread, and full depth for a specific outcome token, plus authenticated order placement. Most read-only projects need both: Gamma to find a market's token_id, CLOB to price it.
Polymarket vs Kalshi API — which is more open for reads?
Both publish credential-free public read APIs, so neither requires signup to pull market data. The shapes differ: Kalshi addresses everything by one ticker, while Polymarket layers ids — an event slug, a market id/slug/condition_id, and then a separate CLOB token_id per outcome — because it prices each Yes/No contract independently down to its own order book. Kalshi is a single CFTC-regulated exchange; Polymarket runs globally, with US access split off into a separate Polymarket US product.
Is Polymarket market data public?
Yes. Event listings, market details, prices, order books, and trade activity are all public reads through Polymarket's own Gamma, CLOB, and Data APIs, with no login wall between you and the data. Placing trades is the part that needs a connected, funded wallet.
Can I get historical Polymarket price data?
Yes. The CLOB's price-history endpoint returns a time series for a token_id at a chosen interval, from 1 minute up to "max", and Polymarket's Data API separately tracks trade and activity history per wallet or market for research on how a market moved.