{"ok":true,"service":"polymarket market data for agents","meta_version":10,"coverage":{"markets_indexed":5061,"events_indexed":631,"top_list_markets":100,"universe":{"version":10,"markets":5061,"events":631,"book_tokens":7968,"hot_markets":1,"last_refresh":{"at_ms":1792681701739,"ms":3028,"core_events":631,"sports_events":0,"markets":5061,"orderable_markets":3984,"undeployed_options":1,"unparseable":0,"bad_events":0,"purged_markets":0,"sports_ordering_fallback":false},"last_sweep":{"at_ms":1792682119661,"ms":781,"tokens":7766,"skipped_hot":202,"books":7630,"missing":136,"bad_books":0,"failed_chunks":0},"last_refresh_error":null,"last_sweep_error":null,"config":{"exclude_tag_ids":["1","21","64"],"market_refresh_ms":600000,"book_sweep_ms":60000,"book_sweep_concurrency":4,"touch_ttl_ms":600000,"touch_max_markets":200,"scope":{"allowIds":["129","131","159","225","309","370","604","702","993","1312","1624","100196","100328","100448","100478","100733","101031","101589","101615","101701","101705","101800","102000","102028","102134","102507","102548","102676","102721","102831","102849","102965","102973","102990","103060","103176","103360","103665","104416","104421","105112","105299","105533","105534","105614","106367"],"denyIds":["1","2","18","53","64","144","596","1101","1597","100265","100639","102175","102289","102467","102531","102892"]},"sports":null}}},"server":{"snapshot_cache":{"entries":0,"gzip_bytes":0,"max_bytes":157286400,"builds":0,"active":0,"max_concurrent":0},"rate_limit":{"perMinute":120,"burst":30,"snapshotPerMinute":6,"snapshotBurst":3,"maxClients":10000,"tracked_clients":1,"tracked_snapshot_clients":0}},"conventions":{"prices":"decimal strings exactly as returned by Polymarket CLOB; never floats","times":"*_ms fields are epoch milliseconds; the response header x-generated-at-ms is the server time of the response","errors":"HTTP 400 / 404 / 409 (CURSOR_EXPIRED) / 429 (RATE_LIMITED, honour retry-after) with { ok:false, code, message }","compression":"send Accept-Encoding: gzip; responses over 1 KB are gzipped","caching":"every GET returns an ETag; send If-None-Match to get 304 (no body) when unchanged. Bodies carry no per-request timestamps, so the ETag only changes when the data does.","rate_limit":"per client IP: 120/min (burst 30); /api/agent/snapshot 6/min (burst 3)","freshness":"yes/no.fetched_at_ms is when we fetched the book; compute age yourself (x-generated-at-ms − fetched_at_ms). Top-list markets and markets recently opened on the website refresh every ~10 s; the rest refresh once per universe sweep. Reading this API never changes a market’s refresh tier. Trading happens on the website and requires a quote younger than stale_price_ms.","stale_price_ms":30000,"paging":"cursor encodes the index version; after a metadata refresh an old cursor returns 409 CURSOR_EXPIRED: restart from the first page.sort=spread / changed_at are recomputed every ~2 s, so paging through them is not stable.","segments":{"core":"every open event except excluded tags (Sports, Crypto, Esports)","sports":"top Sports events by 24h volume that end within the configured window; whole events with every option","top_list":"web top list markets that are not in the universe (e.g. Crypto); their events may be incomplete"},"change_fields":"change_1h / change_24h / change_1w are absolute price deltas (0.08 = 8 cents), not percentages; null = unknown","settlement_rules":"rules = { description (the full resolution text), resolution_source, uma_resolution_status, uma_end_date_ms, resolved_by, outcome_prices, neg_risk_other }; event rules = { description, resolution_source }. Included on /markets/:id and /events/:id; add include=rules on /markets, /changes and /snapshot.","full_dump":"everything we hold = GET /api/agent/snapshot?status=all&include=rules (every market with rules) + GET /api/agent/snapshot?type=events (every event with rules, market_ids, undeployed_options, complete).","changes_semantics":"at-least-once: a market may appear in two consecutive pages; de-duplicate by id keeping the larger changed_at_ms. Only quote changes are reported. Metadata changes (a market closing, being delisted, new markets) are not; when meta_version differs from the one you loaded, reload the snapshots."},"recommended_usage":["Bulk load: GET /api/agent/snapshot?status=all&include=rules and GET /api/agent/snapshot?type=events (NDJSON), then poll GET /api/agent/changes?since=<x-next-since header of the snapshot>, continuing with next_since.","Search: GET /api/agent/markets?q=fed+rate&status=open&sort=-volume_24h&fields=id,question,yes,no","Whole multi-outcome event: GET /api/agent/events/:id (all options with rules; sum of yes.mid ≈ 1 for neg_risk events).","One market: GET /api/agent/markets/:id (book levels, rules, event). Check tradable_now and yes.fetched_at_ms before acting."],"endpoints":[{"path":"GET /api/agent/snapshot","params":{"type":"markets (default) | events","levels":"0|1 (8 book levels per side; markets only)","status":"open (default) | closed | tradable | all (markets only)","include":"rules (markets only; events always include rules)","fields":"not supported (400); project rows yourself"},"returns":"NDJSON, one row per line; headers x-market-count (row count), x-generated-at-ms, x-next-since; rebuilt at most every 15 s"},{"path":"GET /api/agent/changes","params":{"since":"epoch ms (required)","limit":"500..5000 (default 2000; smaller values count as 500)","levels":"0|1","include":"rules","fields":"comma list, <= 40"},"returns":"markets whose best bid / ask / mid changed after since, oldest first; continue with next_since. A page never splits a group of markets fetched at the same instant; a group larger than 10000 returns 400 CHANGES_GROUP_TOO_LARGE."},{"path":"GET /api/agent/markets","params":{"q":"space-separated terms (<= 200 chars, <= 8 distinct terms), all must match question / event / option / slug","ids":"comma list, <= 1000; status defaults to all","category":"comma list, <= 20, any-of (see /api/agent/categories)","segment":"core | sports | top_list (comma list)","event_id":"string","status":"open (default) | closed | tradable | all","min_volume_24h":"number","min_liquidity":"number","end_before":"epoch ms or ISO","end_after":"epoch ms or ISO","changed_since":"epoch ms","sort":"-volume_24h (default) | liquidity | end_date | change_24h | abs_change_24h | spread | changed_at; prefix - for desc","limit":"1..1000 (default 100)","cursor":"next_cursor from the previous page (409 CURSOR_EXPIRED after an index rebuild)","levels":"0|1","include":"rules","fields":"comma list of row keys to keep, <= 40 (id always kept)"}},{"path":"GET /api/agent/markets/:id","returns":"full row + rules, description, tick size, event (with event rules), refresh_tier"},{"path":"GET /api/agent/markets/:id/history","params":{"minutes":"1..1440","side":"yes | no"}},{"path":"GET /api/agent/events","params":{"q":"terms (same limits as markets)","category":"comma list, <= 20","segment":"comma list","min_volume_24h":"number","end_before":"time","end_after":"time","sort":"-volume_24h | end_date | market_count","limit":"<= 1000","cursor":"next_cursor"}},{"path":"GET /api/agent/events/:id","params":{"status":"all (default) | open | closed | tradable","levels":"0|1","include":"rules (default on)","fields":"comma list"},"returns":"event with rules + every option row with rules"},{"path":"GET /api/agent/categories","returns":"open market and event counts per category"}],"market_row_fields":{"id":"Gamma market id","question":"market question","option":"option label inside a multi-outcome event (groupItemTitle)","event_id":"parent event","segment":"core | sports | top_list","neg_risk":"true for mutually exclusive multi-outcome events","outcomes":"[\"Yes\",\"No\"]; token_ids align by index","status":"open | not_accepting | closed","yes":"{ bid, ask, mid, fetched_at_ms, changed_at_ms, levels? } for token_ids[0]; null = never fetched","no":"same for token_ids[1]","tradable_now":"open, not expired, both sides quoted and fresher than stale_price_ms","rules":"settlement rules (only with include=rules or on detail endpoints)"}}