API · Reference
The Gamma API at gamma-api.polymarket.com is the "catalog" - it's how you
discover markets and events and get the token IDs the CLOB needs to trade. It's public,
no auth, so you can explore every endpoint from a browser or curl right now, and so can the
live tools on this page.
- Base URL:
https://gamma-api.polymarket.com· no authentication, read-only. - Rate limit: ~4,000 requests / 10s overall (
/events~500,/markets~300). - Step 1 of almost every bot: turn a market into its token IDs, then trade them on the CLOB.
- Everything is JSON. Three important fields come back as strings of JSON you must parse again (see below).
The endpoints you'll actually use
| Endpoint | Returns | Use it to |
|---|---|---|
GET /markets | Markets with metadata, live prices and token IDs. | Resolve a slug to token IDs; scan tradeable markets. |
GET /events | Events (a group of related markets) with their child markets. | Browse by topic; render multi-outcome cards. |
GET /public-search?q= | Full-text search over events and markets. | Find a market when you only know a name. |
GET /tags | The category tags (politics, crypto, sports...). | Discover valid tag_slug filters. |
Common query parameters on /markets and /events:
active=true, closed=false, slug=, tag_slug=,
order=volume24hr, ascending=false, limit= and offset= for paging.
GET /markets - request and response
Ask for one market by slug. You get back an array (even for a single market), so take element [0]:
curl -s "https://gamma-api.polymarket.com/markets?slug=will-it-rain-in-nyc-today" | jq '.[0]'
import requests, json
m = requests.get("https://gamma-api.polymarket.com/markets",
params={"slug": "will-it-rain-in-nyc-today"}).json()[0]
A trimmed, annotated response (the fields a bot cares about):
{
"id": "519284",
"question": "Will it rain in NYC today?",
"slug": "will-it-rain-in-nyc-today",
"conditionId": "0x1f2e...c0", // the market id (NOT what you trade on)
"active": true, // listed and live
"closed": false, // not yet resolved
"acceptingOrders": true, // the CLOB is currently taking orders
"outcomes": "[\"Yes\", \"No\"]", // JSON string -> parse it
"clobTokenIds": "[\"7142...\", \"1098...\"]", // JSON string, aligned with outcomes
"outcomePrices": "[\"0.62\", \"0.38\"]", // JSON string, last prices
"bestBid": 0.61,
"bestAsk": 0.63,
"lastTradePrice": 0.62,
"volume24hr": 48213.5,
"endDate": "2026-06-16T00:00:00Z"
}
The two outcome token IDs live inside clobTokenIds. They are what the
CLOB trades on - read them and you can place an order.
The #1 gotcha: JSON-encoded string fields
Gamma returns clobTokenIds, outcomes and outcomePrices as
JSON-encoded strings inside the JSON, so you have to decode them a second time. And never
hardcode which token is "Yes": read the parsed outcomes array and map by name, because the order
is not guaranteed.
import requests, json
m = requests.get("https://gamma-api.polymarket.com/markets",
params={"slug": SLUG}).json()[0]
outcomes = json.loads(m["outcomes"]) # e.g. ["Yes", "No"]
token_ids = json.loads(m["clobTokenIds"]) # aligned with outcomes
prices = json.loads(m["outcomePrices"]) # aligned with outcomes
yes_token = token_ids[outcomes.index("Yes")]
print(yes_token, prices[outcomes.index("Yes")])
const r = await fetch(`https://gamma-api.polymarket.com/markets?slug=${SLUG}`);
const m = (await r.json())[0];
const outcomes = JSON.parse(m.outcomes);
const tokenIds = JSON.parse(m.clobTokenIds);
const yesToken = tokenIds[outcomes.indexOf("Yes")];
curl -s "https://gamma-api.polymarket.com/markets?slug=$SLUG" | jq -r '.[0].clobTokenIds | fromjson | .[0]'
Try it on a real market - paste a slug and pull its token IDs live:
Scan for tradeable markets
A typical bot's discovery query asks for active, open markets, busiest first, in one category:
GET https://gamma-api.polymarket.com/markets
?active=true&closed=false&order=volume24hr&ascending=false&limit=20&tag_slug=politics
Filter the result client-side to markets that are genuinely tradeable before you act on them:
# keep only markets the CLOB will accept orders on right now
tradeable = [m for m in markets
if m.get("active") and not m.get("closed") and m.get("acceptingOrders")]
Search live (this calls /public-search, then loads token IDs per market):
Paging and freshness
- Paging: add
limitandoffsetand walk until you get a short page. Keeplimit≤ 500 on/events, ≤ 300 on/markets. - Freshness: prices (
bestBid,bestAsk,lastTradePrice) move constantly. Gamma is fine for discovery and a rough price, but quote and trade off the live CLOB book, not a cached Gamma price. - Caching: cache the slug -> token_id mapping (it's stable), not the prices.
GET /events - multi-outcome groups
An event bundles related markets (e.g. "NYC Mayoral Election" holds one market per candidate). Use it to render multi-outcome cards or to find every market on a topic:
curl -s "https://gamma-api.polymarket.com/events?slug=nyc-mayor-2025" | jq '.[0].markets | length'
Each event has a markets array; every entry has the same clobTokenIds /
outcomes string fields as a top-level market, so the same parsing applies.
conditionId and its clobTokenIds (one per outcome). The CLOB trades on
token_id, never on conditionId - mixing them up is the most common first-bot bug.Field reference (the ones that bite)
| Field | Meaning |
|---|---|
conditionId | The market identifier. Used for resolution and on-chain lookups, not for placing orders. |
clobTokenIds | JSON string array of the outcome token IDs. Parse it; trade these on the CLOB. |
outcomes / outcomePrices | JSON string arrays, index-aligned with clobTokenIds. |
active / closed | Listed-and-live / resolved. A tradeable market is active && !closed. |
acceptingOrders | Whether the CLOB will take orders right now. Check this before quoting. |
bestBid / bestAsk / lastTradePrice | Indicative prices. Authoritative price comes from the CLOB book. |
Next: CLOB API (trade on a token_id) · Data API (history & PnL) · Fix an error.



