Polymarket Markets Scraper
Pricing
from $0.09 / 1,000 markets
Polymarket Markets Scraper
Scrape Polymarket prediction markets: odds, prices, volume, liquidity, order book, price history and trades. Search by keyword, category or market URL. Export to JSON, CSV or Excel.
Pricing
from $0.09 / 1,000 markets
Rating
0.0
(0)
Developer
Nice Dev
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
🔎 What is Polymarket Markets Scraper?
Polymarket Markets Scraper extracts prediction markets from Polymarket: question, outcome prices (the implied probability), best bid and ask, spread, 24h / 7d / 30d / all-time volume, liquidity, open interest, price moves, opening and closing dates — plus the live order book, the price history, the latest trades and the biggest holders when you ask for them.
Type a keyword (bitcoin), pick a category, paste a market URL — or ask for nothing at all and walk the whole catalogue, over 40,000 open markets. Click Start and download the markets in JSON, CSV or Excel. No login, nothing to set up, and it is fast: a market costs no request of its own (100 per API page), and the order books of 100 markets cost a single extra request — 500 markets, with their order book, in seconds.
📋 What data can you extract from Polymarket?
One item per market, 74 fields:
| Category | What you get |
|---|---|
| 🎯 Market | the question, the resolution rules in full, the page link, the site's id — Will United Russia (ER) gain the most seats…? |
| 📈 Odds and prices | every outcome with its price (the implied probability), yes / no shortcuts, best bid and ask, spread, last trade — Yes 0.815 / No 0.185 |
| 💵 Money | 24h, 7-day, 30-day, 1-year and all-time volume, liquidity, open interest — $1,601,129 traded in 24h |
| 📊 Price moves | the move over 1 hour, 24 hours, a week and a month, in probability points — +8 points in 24h |
| 🕒 Dates and state | opening, closing, creation and update dates, open / closed / archived / accepting orders — ends 2026-09-30 |
| 🏁 Resolution | resolved or not, the outcome that paid out, the source of truth, how it was settled and by which contract, bonds, rewards — winner: Yes |
| 💸 Fees | maker and taker base fees, the fee category and its schedule (taker rate, maker rebate) — politics_fees, 4 % |
| 🔗 On-chain ids | condition id, question id, one token per outcome, the negative-risk flag and group ids |
| 🗂️ Event and categories | the parent event (title, volume, open interest, comments) and the tags — Politics |
| 📖 Order book (on by default) | bids and asks with price and size for both outcomes, ten levels a side |
| 💬 Comments (option) | the comments of the market's event: text, author, date, reactions, replies with their thread, GIFs |
| 📉 Price history, trades, holders (options) | the price series, the latest trades with wallet, pseudonym and user name, the biggest positions per outcome (up to 500) with the verified badge |
| 🧾 Run | the search the market was found by, the timestamp |
Every field, with an example, is listed under Output below (All 74 fields).
✅ Why use Polymarket Markets Scraper?
- 🚀 Fast: 100 markets per API request, and the order books of 100 markets in one more — 500 markets with their order book in seconds.
- 🗺️ The whole catalogue, not the first page: over 40,000 open markets, walked to the end — leave the keyword empty and set
maxItems: 0. - 🏁 Resolved markets with their winner:
status: "resolved"gives the settled markets, the outcome that paid out and when they closed — a ready-made backtesting dataset. - 📖 Order book in the same run: bids and asks with price and size for both outcomes, on by default ($0.10 per 1,000 markets; untick it for the markets alone).
- 🐋 Whale trades:
includeRecentTradeswithminTradeSizeUsdreturns the trades above your threshold, wallet and pseudonym included. - 🔔 Monitoring built in: tick Only new markets, schedule the Actor, and each run returns (and charges) only the markets it has never delivered.
- 🎯 Filters for next to nothing: volume, liquidity, open interest, fee category, spread, 24h price move, "ending within the next hour", opening and closing dates — a filtered-out market is never charged, and a filter Polymarket cannot apply itself costs $0.20 per 1,000 results pages read.
- 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…) and JSON/CSV/Excel export via the Apify platform.
🚀 How to scrape Polymarket
- Create a free Apify account.
- Open Polymarket Markets Scraper and type a Search keyword (e.g.
bitcoin), or pick a Category (politics,crypto,sports). - Or paste Polymarket URLs into Start URLs: an event page, a single market page, or a category page.
- Set Max markets (100 by default, 0 = no limit) — and Max markets per search when you run several searches — then click Start.
- Download the dataset in JSON, CSV, Excel or via API.
💰 How much does it cost to scrape Polymarket?
This Actor uses pay per event pricing, at its launch price: $0.09 per 1,000 markets (all 74 fields but the options), $0.10 per 1,000 markets per option you tick — order book, price history, trades, holders, comments: $0.0001 per market each — and $0.001 per run start (10 cents per 100 runs). Every Apify plan pays the same: $0.09 (Bronze), $0.09 (Silver) and $0.09 (Gold) per 1,000 markets. Platform usage (compute, proxy) is included in the price.
| What you ask for | Price per 1,000 markets | Example |
|---|---|---|
| Markets only (every option off) | $0.09 | the whole catalogue of ≈ 200,000 open markets ≈ $18.00 |
| Markets + order book (the default input) | $0.19 | the whole catalogue with its order books ≈ $38.00; a daily monitor of 200 new markets ≈ $0.04 |
| Markets + the 5 options, each on its first page | $0.59 | 1,000 markets with book, price history, trades, holders and comments ≈ $0.59 |
An option is charged only to the markets that get it: a closed market has no order book, and an option whose page fails, or that Polymarket answers without data, is not charged for that market.
Two options can go past their first page, and each page after it is $0.03 per 1,000 extra option pages ($0.00003 a page, the same on every plan): a price history over a range of dates (one page per 15 days, counted from the day the market was created) and more than 100 comment threads (one page per 100 threads). Trades (up to 1,000), holders (up to 500 per outcome) and a price history interval are always one page. The most a market can cost:
| Input | Options | Extra option pages, at most | Most a market costs |
|---|---|---|---|
| Markets only (every option off) | 0 | 0 | $0.00009 |
| Defaults (the order book) | 1 | 0 | $0.00019 |
| Every option on its first page | 5 | 0 | $0.00059 |
Order book + priceHistoryStartDate: "180 days" | 2 | 11 | $0.00062 |
Order book + maxCommentsPerEvent: 1000 | 2 | 9 | $0.00056 |
| Every option at its maximum (750 days of history, 1,000 comment threads) | 5 | 58 | $0.00233 |
Filtered pages cost $0.20 per 1,000 results pages ($0.0002 a page, the same on every plan). Polymarket applies the volume, liquidity, date and status filters itself on the catalogue: they cost nothing more. The other filters — 24h volume, open interest, spread, fee category, 24h price move, excluded words, status: "resolved" — and every filter of a keyword search (the status of its markets included) are checked here, on pages of 100 markets of which only a few may pass: each results page read for them is one filtered page, whether its markets pass or not. Example: the whole open catalogue (≈ 200,000 markets) filtered by open interest reads ≈ 2,000 pages ≈ $0.40. A list of exact identifiers and onlyNew alone never charge a page.
The log says, before the run starts, the options charged, the most extra pages a market of your input can take and which filters charge their pages, and at the end how many of each were charged. A page that fails is never charged, and a maximum cost per run counts each market at its dearest and pays each filtered page before it is read, so the run never goes past it.
⚙️ Input
{"query": "bitcoin","maxItems": 200,"includeOrderBook": true}
Several searches, a cap per search, only the markets that move, only the ones not delivered before:
{"searchQueries": ["bitcoin", "election"],"categories": ["crypto", "politics"],"maxItemsPerQuery": 50,"minVolume24h": 10000,"minPriceChangePct": 5,"onlyNew": true,"stateKey": "crypto-daily"}
Resolved markets with their winner, for a backtest:
{"status": "resolved","sortBy": "endDate","maxItems": 5000,"includePriceHistory": true,"priceHistoryInterval": "max","priceHistoryFidelity": 1440}
Or with your own URLs:
{"startUrls": [{ "url": "https://polymarket.com/event/which-party-will-gain-most-seats-in-russian-parliamentary-election" },{ "url": "https://polymarket.com/markets/crypto" }],"maxItems": 500}
| Field | Notes |
|---|---|
query, searchQueries | Free-text search; searchQueries adds more keywords (one search each). Ignored when startUrls is set. |
categories, tagIds | Category slugs as in the site URL (politics, crypto, sports) and numeric tag ids; a category typed as the site shows it (Pop Culture) is looked up as its slug (pop-culture). Every keyword × every category (max 500 searches per run). |
marketSlugs, eventSlugs, conditionIds, marketIds, outcomeTokenIds | Exact identifiers, fetched directly — no search, no pagination. An outcome token (clobTokenIds) finds its market whichever outcome it stands for. |
startUrls | Event, market, category or search pages of the site; the status, sort, filters and monitoring apply to them too. |
status | Open, closed, resolved (settled, with the winning outcome) or all. |
sortBy, sortDescending | 24h volume, total volume, liquidity, start date, end date, creation date, spread or competitiveness (catalogue and category searches; a keyword search comes in the site's relevance order). With a date bound or the monitoring mode, the default sort becomes the newest markets first. |
maxItems, maxItemsPerQuery | Stop after this many markets for the run (0 = unlimited), and a cap for EACH search. |
includeEvent, includeTags | The parent event and the categories: both on by default, and they cost no extra request. |
includeOrderBook, orderBookDepth | Live bids and asks per outcome, on by default, cut to ten levels per side (zero = the whole book). $0.0001 per market. |
includePriceHistory, priceHistoryInterval, priceHistoryFidelity | The price series per outcome, over the last hour, 6 hours, day, week, month or since the market opened, one point per hour by default (Polymarket's floor: 5 minutes for a week, 10 minutes for a month, 720 minutes for the whole life of a market). $0.0001 per market (the option). |
priceHistoryStartDate, priceHistoryEndDate | Or ANY range of dates instead (2026-08-01 to 2026-08-31, or 30 days back to now), at any resolution — even one point a minute — up to 750 days and 10,080 points per outcome. One request per 15 days of range per market, from the day the market was created; each after the first is an extra option page ($0.00003). |
includeRecentTrades, recentTradesLimit, minTradeSizeUsd | The latest trades of each market (side, size, price, time, wallet, trader name and picture), up to 1,000 trades per market, worth at least the USD amount you set for a whale run. $0.0001 per market (the option). |
includeTopHolders, maxHoldersPerOutcome | The biggest position holders, 20 per outcome by default, up to 500 (wallet, pseudonym, user name, verified badge, picture, size) — in one request per market whatever the number. $0.0001 per market (the option). |
includeComments, maxCommentsPerEvent | The comments of the market's event (text, author, date, reactions, replies), 100 threads by default, up to 1,000 — one request per 100 threads per market, each after the first an extra option page ($0.00003); the markets of one event carry the same comments. Switches includeEvent on. $0.0001 per market (the option). |
minVolume24h, minVolume, minLiquidity, minOpenInterest | Money floors in USD (open interest = the value of every open position of the market's event); zero means no floor. |
minSpread, maxSpread | Bid-ask spread bounds in probability points: 0.05 is 5 cents. |
minPriceChangePct | Only markets that moved by at least this many percentage points over 24 hours, up or down. |
endingWithinMinutes | Only markets closing within the next N minutes. |
postedAfter, postedBefore | Opening date range: 2026-09-01, or a period before now (7 days, 2 weeks, 1 month, 24 hours). |
endingAfter, endingBefore | Closing date range: 2026-12-31, or a period AHEAD of now (30 days in endingBefore = closing in the next 30 days). |
excludeKeywords | Drop the markets whose question contains one of these words (case and accents ignored). |
feeTypes | Only the markets of these fee categories (politics_fees, sports_fees_v3, crypto_fees_v2, zero_fees…); none = the markets without one. |
onlyNew, stateKey, resetState | Monitoring: only the markets never delivered under this memory key; resetState forgets the memory. |
| Advanced | proxyConfiguration (Apify proxy by default, included in the price; the residential proxy is not available), maxConcurrency, maxRequestsPerMinute, minRequestIntervalMs, maxRequestRetries, debugLog. |
📦 Output
A real item, shortened (the description, the event description and the book of the second outcome are cut here):
{"id": "1130012","url": "https://polymarket.com/event/which-party-will-gain-most-seats-in-russian-parliamentary-election/will-united-russia-er-gain-the-most-seats-in-the-next-russian-parliamentary-election","slug": "will-united-russia-er-gain-the-most-seats-in-the-next-russian-parliamentary-election","question": "Will United Russia (ER) gain the most seats in the next Russian parliamentary election?","description": "Parliamentary elections are to be scheduled to be held in Russia in September 2026…","conditionId": "0x502a94e5c525766d5ee7f16c6568131ba1b2cbadb69c703af05a6ef00336ed64","questionId": "0xc194d621e2ef9468b86ed0db1328fd8d56ae8fba1e21b94c5c515e96ecbfc400","clobTokenIds": ["20915769520649892253891152116814645067070024223185517956799957803974344024878", "115351075585746600277716377744935410125916932950844626289798775482755919708780"],"outcomes": ["Yes", "No"],"outcomePrices": [0.815, 0.185],"yesPrice": 0.815,"noPrice": 0.185,"bestBid": 0.81,"bestAsk": 0.82,"spread": 0.01,"volume": 16144126.59,"volume24hr": 1601129.41,"liquidity": 478206.56,"openInterest": 5728158.26,"priceChange24h": 0.08,"startDate": "2026-01-07T21:34:52.537Z","endDate": "2026-09-30T00:00:00.000Z","closedTime": null,"active": true,"closed": false,"archived": false,"acceptingOrders": true,"resolved": false,"winningOutcome": null,"competitive": 0.9097,"groupItemTitle": "United Russia (ER)","event": { "id": "149589", "slug": "which-party-will-gain-most-seats-in-russian-parliamentary-election", "title": "Which party will gain most seats in Russian Parliamentary Election?", "openInterest": 5728158.26, "commentCount": 12 },"tags": [{ "id": "2", "label": "Politics", "slug": "politics" }],"orderBook": { "Yes": { "bids": [{ "price": 0.81, "size": 41447.61 }], "asks": [{ "price": 0.82, "size": 12000 }] } },"priceHistory": null,"recentTrades": null,"topHolders": null,"comments": null,"searchUrl": "https://gamma-api.polymarket.com/markets/keyset?include_tag=true&limit=100&closed=false&order=volume24hr&ascending=false","scrapedAt": "2026-09-20T05:12:00.000Z"}
You can download the dataset in various formats such as JSON, HTML, CSV or Excel.
All 74 fields
| Field | Example |
|---|---|
id, slug, url, question, description | 1130012, will-united-russia-er-gain…, the market page, the question, the resolution rules |
outcomes, outcomePrices, yesPrice, noPrice | ["Yes","No"], [0.815, 0.185], 0.815, 0.185 |
bestBid, bestAsk, spread, lastTradePrice, competitive | 0.81, 0.82, 0.01, 0.82, 0.91 |
volume, volume24hr, volume1wk, volume1mo, volume1yr | all-time and rolling volumes in USD |
liquidity, openInterest | 478206.56, 5728158.27 |
priceChange1h, priceChange24h, priceChange1wk, priceChange1mo | the move in probability points (0.08 = 8 points) |
startDate, endDate, createdAt, updatedAt, closedTime | ISO 8601 UTC (startDate is what the date filters read) |
active, closed, archived, acceptingOrders, acceptingOrdersTimestamp, enableOrderBook | the state of the market, and when its order book opened |
resolved, winningOutcome, resolutionSource, umaResolutionStatus, automaticallyResolved, resolvedBy | true, Yes, the source of truth, how it was settled, the resolver contract |
umaBond, umaReward, makerBaseFee, takerBaseFee, feeType, feeSchedule | 500, 5, fees, the fee category (politics_fees) and its rate / maker rebate |
rewardsMinSize, rewardsMaxSpread, orderMinSize, orderPriceMinTickSize | liquidity rewards and order limits |
conditionId, questionId, clobTokenIds, negRisk, negRiskMarketId, negRiskRequestId | the on-chain ids (one token per outcome), the negative-risk group |
groupItemTitle, line, featured, restricted, funded | United Russia (ER), the handicap line of a sports market, flags |
imageUrl, iconUrl | the market picture |
event, tags | the parent event (title, slug, url, volume, open interest, comments) and the categories |
orderBook, priceHistory, recentTrades, topHolders, comments | filled by the options below, null otherwise |
searchUrl, scrapedAt | the query it was found by, ISO timestamp |
outcomes, outcomePrices and clobTokenIds are real arrays (Polymarket sends them as text), and winningOutcome names the outcome that paid out on a resolved market.
💡 Tips
How to get more results
Leave Search keyword empty and set maxItems to 0: the Actor then walks the whole catalogue, over 40,000 open markets, page after page. status: "all" adds the closed ones — that is where the history lives.
How to reduce costs
The levers are maxItems, maxItemsPerQuery, the filters (a filtered-out market is free; a filter Polymarket cannot apply itself costs $0.0002 per results page read, so combine it with one it can — minVolume, minLiquidity, the dates), onlyNew for recurring runs (you never pay twice for the same market) and the options: each one ticked adds $0.10 per 1,000 markets — untick includeOrderBook for the markets alone at $0.09 per 1,000. Only a price history range and more than 100 comment threads add extra option pages: a shorter range, or fewer threads, costs less — a coarser resolution does not (a page covers 15 days whatever the number of points).
Several searches in one run
Fill searchQueries and / or categories: the Actor runs one search per keyword × category (3 keywords × 4 categories = 12 searches, up to 500 per run). The single query field still works and is added to the list. A market found by several searches is saved — and charged — once. Set maxItemsPerQuery to give every search its own cap: without it the first searches can use up the whole maxItems budget.
Monitoring: only the new markets
Tick Only new markets (onlyNew) and schedule the Actor. The first run returns everything; each later run skips the markets already delivered: they are not saved, not charged, and their order book is not even fetched. The memory lives in a named key-value store of your account (polymarket-markets-scraper-seen, up to 150,000 markets per key) and is only updated with markets that really reached the dataset, so a failed run never hides anything. Give each schedule its own stateKey, and tick resetState once to start over. Searches are then sorted by newest, and a search stops once it meets 500 markets in a row you already have.
Filter by date
postedAfter and postedBefore read the date a market OPENED; endingAfter, endingBefore and endingWithinMinutes read the date it closes. All take a date (2026-09-01, the whole day is included, UTC) or a period (7 days, 2 weeks, 1 month; via the API also 24 hours or a full ISO date-time): before now for the opening dates, ahead of now for the closing dates (1 month on 31 January = 28 February). endingBefore alone also keeps the open markets already past their end date but not settled yet; endingWithinMinutes starts from now. A market without the date a filter reads is dropped as soon as that bound is set. Filtered-out markets are never charged and do not count in maxItems.
Track the whales
includeRecentTrades with minTradeSizeUsd: 10000 returns, for each market, only the trades worth at least $10,000 — with the wallet, the trader's pseudonym, the side, the size, the price and the transaction hash. Add includeTopHolders for the biggest open positions of each outcome.
🔌 Integrations and API
Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.
🤖 Use with AI agents (MCP)
AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the Apify MCP server, billed to their Apify account like any run. It returns one item per Polymarket market. Actor id: nice_dev/polymarket-markets-scraper; MCP server with this Actor only: https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/polymarket-markets-scraper.
Smallest input, for a cheap first call:
{"query": "bitcoin","maxItems": 10}
Key output fields: url, question, outcomes, outcomePrices, volume24hr, liquidity, endDate and orderBook (with includeOrderBook).
Cost: $0.09 per 1,000 markets, plus $0.10 per 1,000 markets for each option ticked (the order book is on by default: $0.19 per 1,000), plus $0.001 per run start; every Apify plan pays the same. Filtered pages and extra option pages cost extra, see the pricing section above. Cap each call with maxItems and, through the API, with the run option maxTotalChargeUsd.
❓ FAQ
Is it legal to scrape Polymarket?
The Actor only reads what Polymarket shows publicly to any anonymous visitor. It logs in to nothing, places no order and holds no funds. Results can contain personal data — a trade or a holding carries the trader's wallet address and pseudonym, which are public on the blockchain, and the user name and picture of the trader's Polymarket profile (a holder who keeps the name private gets null; the trade feed has no such setting and gives the name as Polymarket's API does); the comments (includeComments) carry their authors the way the holders are — and personal data is protected by GDPR: those fields are off by default (includeRecentTrades, includeTopHolders, includeComments), and you should not store them without a legitimate reason. You are responsible for using the data in compliance with Polymarket's Terms of Use and applicable law; prediction markets are restricted in several countries, and reading prices is not trading. This Actor is not affiliated with Polymarket.
Why can a market cost more than $0.00009?
Each option you tick adds $0.0001 to the markets that get it (the order book is on by default: $0.00019 a market). An option can also go past its first page: a price history over a range of dates longer than 15 days, or more than 100 comment threads. Each page after the first is one more request to Polymarket, and is charged $0.00003 (extra-option-page) — so 750 days of history, 50 pages, add $0.0015 to the market. A page that fails, or that Polymarket answers without data, is never charged. A run that is stopped and resumed reads again the pages it lost, and charges them once.
Does it need a login or a proxy?
No login, no account, no API key. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 60 seconds).
Is the data safe to open in Excel or to show on a web page?
Every URL field (url, imageUrl, iconUrl, event.url, profileImageUrl of a trade, a holder or a comment, url of a comment's picture) holds an http(s) URL or null. A comment's body is plain text: any HTML tag is removed. Questions and descriptions are written by the market creators and copied as they are: a text can begin with -, +, = or @, which Excel and Google Sheets may read as a formula in a CSV file — import those columns as text. Prices and volumes are numbers, never text. On a web page, escape every field like any text written by a stranger.
Known limitations
tagsonly names the categories of the market; the full category tree of the site is not exposed.priceChange1his not sent for every market: it isnullthere.- The price history has a floor set by Polymarket: 5 minutes between two points for a week, 10 minutes for a month, 720 minutes (two points a day) since the market opened — finer, Polymarket only serves the last 31 days; a finer
priceHistoryFidelityis refused before the run starts. For a fine series further back, usepriceHistoryStartDate/priceHistoryEndDate. onlyNewremembers market ids, not their content: a market whose price changed is not returned again, nor a market delivered open that has since closed or resolved — give astatus: "resolved"schedule its ownstateKey.- The order book is the live one at the moment of the run: two runs a minute apart give two different books.
- Two runs sharing the same
stateKeyat the same time may both return the same new market.
A run the platform stops without warning (out of memory, run timeout)
- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the markets already saved are skipped: none is delivered or charged twice, and
maxItemsstill counts them. - With
onlyNew, the memory is saved once a minute: resurrect the stopped run and the markets it had saved meanwhile join the memory; leave it stopped for good, and the next run may return up to a minute of them once more.
Something doesn't work?
The last line of the log counts the markets saved and filtered out, and the requests that failed after every retry. Those requests are listed, with the reason, in the FAILED_REQUESTS record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause. A run that saved some markets fails too when at least as many requests failed for good as were read, or when at least as many option pages (order book, price history, trades, holders, comments) failed for good as were answered: a green run of bare markets would hide an outage. One failed request among many is only a warning.
If Polymarket changes its pages, you are told instead of paying for blank rows. A results page that counts markets but gives none the Actor can read is an error (listed in FAILED_REQUESTS), never a quiet "No markets found". If the first 20 markets read all lack their question, slug, outcomes, prices, ids or dates, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first markets are charged.
🛟 Support
Open an issue in the Issues tab with a link to your run: the run log and the FAILED_REQUESTS record of the key-value store show exactly which URLs failed and why.