# Polymarket Markets Scraper – Odds, Volume & Order Books (`rowfeed/polymarket-markets-scraper`) Actor

Extract Polymarket prediction markets: live yes/no odds, bid/ask, volume, liquidity, end dates and optional order books. Filter by event, tag, search term or status. Clean JSON for traders, researchers and AI agents.

- **URL**: https://apify.com/rowfeed/polymarket-markets-scraper.md
- **Developed by:** [Rowfeed](https://apify.com/rowfeed) (community)
- **Categories:** Developer tools, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 markets

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Polymarket Markets Scraper – Odds, Volume & Order Books

Get Polymarket prediction-market data as clean JSON rows: every market's YES/NO odds, best bid and ask, last trade, spread, lifetime and 24 h volume, liquidity, start and end dates and, on request, the live order book.
Built for traders, researchers, AI agents and dashboards that need Polymarket odds without a wallet, an API key, a headless browser or a proxy.
Plain HTTPS calls to Polymarket's public Gamma and CLOB APIs with retries and a silent-failure check, so a scheduled run keeps working when the exchange hiccups.

### What you get

- **Every market as one row** – question, both outcomes with price and CLOB token id, YES price (the implied probability), best bid/ask, last trade, spread, lifetime and 24 h volume, liquidity, start/end dates, the parent event, `category` (Politics, Sports, Crypto, Geopolitics, Economy…), all event tags and a link to the market page. Multi-candidate questions ("Presidential Election Winner 2028") arrive as one row per candidate.
- **Order books on demand** – the top N price levels on the YES and the NO side as `[price, size]` pairs, read live from the CLOB at the same moment as the row.
- **Filters that match real questions** – one event or market (slug or pasted URL), a tag (`politics`, `sports`, `crypto`, `nba`, `bitcoin`…), a title search, a status (active, closed, all) and a sort order (24 h volume, volume, liquidity, end date), with a hard cap on rows so the cost of a run is known up front.

### Sample row

One market scraped with `marketSlugs: ["xi-jinping-out-before-2027"]`, `includeOrderbook: true` and `orderbookDepth: 3`. The remaining raw Gamma fields (`groupItemTitle`, `volume1wk`, `oneDayPriceChange`, `orderPriceMinTickSize`, `umaResolutionStatuses`, …) are trimmed here but present in every row.

```json
{
  "market_id": "559651",
  "condition_id": "0xa467b14d51f01b957109d9cbb1d6c124fab2a089d52ed8f471d23c2812e743b7",
  "slug": "xi-jinping-out-before-2027",
  "question": "Xi Jinping out before 2027?",
  "event_id": "30828",
  "event_slug": "xi-jinping-out-before-2027",
  "event_title": "Xi Jinping out before 2027?",
  "outcomes": [
    { "name": "Yes", "price": 0.0385, "token_id": "32338220190071351435772801779725302244575775216413325951443816017994629993401" },
    { "name": "No", "price": 0.9615, "token_id": "25659310674993675562345759665114759892400026242514633218387667107987341231962" }
  ],
  "yes_price": 0.0385,
  "best_bid": 0.038,
  "best_ask": 0.039,
  "last_trade_price": 0.038,
  "spread": 0.001,
  "volume": 13098406.06,
  "volume_24h": 48394.75,
  "liquidity": 287890.47,
  "start_date": "2025-07-03T20:37:00.228Z",
  "end_date": "2027-01-01T04:59:00Z",
  "active": true,
  "closed": false,
  "category": "Geopolitics",
  "tags": ["world affairs", "Geopolitics", "World", "Earn 4%", "Macro Geopolitics", "HFC"],
  "url": "https://polymarket.com/event/xi-jinping-out-before-2027/xi-jinping-out-before-2027",
  "scraped_at": "2026-09-09T10:49:54+00:00",
  "description": "This market will resolve to \"Yes\" if China's General Secretary of the Communist Party, Xi Jinping, is removed from power for any length of time between July 3, 2025, and December 31, 2026, 11:59 PM ET. Otherwise, this market will resolve to \"No\". …",
  "negRisk": false,
  "orderbook": {
    "yes": [[0.036, 2431.77], [0.037, 25982.29], [0.038, 3743.67]],
    "no": [[0.959, 602.0], [0.96, 1047.02], [0.961, 78451.1]]
  }
}
```

### Filters

| Input | Default | What it does |
|---|---|---|
| `eventSlugs` | `[]` | Events to scrape, e.g. `["uefa-champions-league-2027-champion-20260701202025549"]`; every market inside becomes a row. The slug is the part after `/event/` in the page URL; the whole URL works too. |
| `marketSlugs` | `[]` | Single markets, e.g. `["xi-jinping-out-before-2027"]` (last part of the market URL, or the URL). Used together with event slugs when both are set. |
| `tagSlug` | `""` | Only events carrying this tag: `politics`, `sports`, `crypto`, `soccer`, `nba`, `bitcoin`, `fed`… Ignored when slugs are set. |
| `searchTerm` | `""` | Only events whose title contains this text, e.g. `bitcoin` or `Champions League`. Ignored when slugs are set. |
| `status` | `active` | `active` (trading now), `closed` (resolved or expired) or `all`. Applied per market, so an event's resolved sub-markets and unfunded placeholders are skipped unless you ask for them. |
| `sortBy` | `volume24hr` | `volume24hr`, `volume`, `liquidity` (highest first) or `endDate` (soonest first). Applies to the event list and to the markets inside each event. |
| `maxMarkets` | `200` | Stop after this many rows. |
| `includeOrderbook` | `false` | Fetch the live order book for every row. |
| `orderbookDepth` | `10` | Price levels per side (1–100). |

With no slugs, tag or search term the Actor walks Polymarket's whole active event list in the chosen order, so the default run returns the 200 most traded markets of the day.

### Pricing

Pay per event, no subscription: **$1 per 1,000 markets** and **$2 per 1,000 order books**. A default run (200 active markets, no order books) costs $0.20; 200 markets with order books cost $0.60. Set a maximum charge on the run and the Actor stops cleanly when it is reached, charging only for rows that were actually saved.

### Use it from your tools

- **API and SDKs** – call it via the Apify API or the official Python/JavaScript clients: one call to start the run, one to fetch the dataset as JSON or CSV.
- **Schedules** – run it hourly or daily inside Apify and push new rows to Google Sheets, a webhook or your own storage automatically.
- **n8n, Make and Zapier** – trigger runs and pipe markets into a workflow through Apify's integration for each.
- **AI agents and MCP** – this Actor is eligible for agentic use via Apify's MCP server and supports pay-per-event pricing, so an agent can call it mid-task and pay only per market it actually reads.
- **Webhooks** – fire on run finished to kick off the next step in a pipeline as soon as fresh markets land.

### Details

- **Source**: Polymarket's public Gamma API (`gamma-api.polymarket.com`, markets, events, tags) and CLOB API (`clob.polymarket.com`, order books). No authentication, no proxies, no browser. No personal data: wallet and contract addresses (`submitted_by`, `resolvedBy`, `marketMakerAddress`, reward asset addresses) are stripped from every row.
- **Freshness**: `scraped_at` is the UTC timestamp of the run. Gamma prices and volumes are served from a CDN that caches for up to 5 minutes; order books are read live from the CLOB, so turn them on when you need the exact current bid and ask.
- **Outcomes**: every Polymarket market is binary. `outcomes[0]` is the YES side, or the first named side on sports markets (`"Frances Tiafoe"` vs `"Alex Michelsen"`), and `yes_price` is its price (0–1). Index 0 of `outcomes`, `orderbook.yes` and the raw `groupItemTitle` label line up.
- **Order book**: `yes` holds the bids on the first outcome token, `no` the bids on the second, each as `[price, size]` with the best level last, prices 0–1 and sizes in shares (a share pays $1 if it wins). Polymarket's CLOB serves the second token's book as the exact mirror of the first (a NO bid at *p* is the YES ask at *1 − p*), so both sides come from one request per market.
- **Reliability**: 429 and 5xx responses are retried with exponential backoff (5 tries), a 200 without the expected data counts as a failure, and one bad slug never stops the run: it becomes an error row (`slug`, `error`, `errorMessage`) and the rest continues. A run fails only when it produced no rows *and* hit errors; a filter with no matching markets (e.g. a tag with nothing active) is a successful, empty run.
- **Run stats**: the `STATS` record in the run's key-value store holds request and error counts per category (`network`, `rate_limit`, `blocked`, `not_found`, `other`).
- **Speed**: a default run finishes in a few seconds; one API call carries about 100 events and 1,800 active markets. Order books add roughly a quarter of a second per market.
- **Output**: one dataset row per market with the columns above first and every raw Gamma field after them. The Overview table shows question, YES price, 24 h volume, volume, end date and link. Export as JSON, CSV or Excel, fetch through the Apify API, or schedule runs and pipe them into Google Sheets, Make, Zapier or your own code.

# Actor input Schema

## `eventSlugs` (type: `array`):

Polymarket events to scrape, e.g. xi-jinping-out-before-2027. The slug is the part after /event/ in the page URL; pasting the whole URL also works. Every market inside the event becomes a row. Leave empty to scrape across all events.

## `marketSlugs` (type: `array`):

Single markets to scrape, e.g. will-paris-saint-germain-win-the-2026-27-uefa-champions-league-championship-20260701202025550. The slug is the last part of a market's page URL; pasting the URL also works. Used together with event slugs when both are set.

## `tagSlug` (type: `string`):

Keep only events carrying this tag, e.g. politics, sports, crypto, soccer, bitcoin, nba, fed. Tag slugs are the lower-case, dash-separated labels shown on polymarket.com. Ignored when event or market slugs are set.

## `searchTerm` (type: `string`):

Keep only events whose title contains this text (case-insensitive), e.g. bitcoin or Champions League. Ignored when event or market slugs are set.

## `status` (type: `string`):

Which markets to return: active (trading now), closed (resolved or trading ended), or all. Applied to every market, also inside a requested event: an active event still lists its resolved sub-markets and unfunded placeholders, and those are skipped unless you pick closed or all.

## `sortBy` (type: `string`):

Order of the rows, so maxMarkets keeps the most relevant ones: 24 h volume, lifetime volume or liquidity (highest first), or end date (soonest first). Applies to the event list and to the markets inside each event.

## `maxMarkets` (type: `integer`):

Stop after this many market rows. Each row is one `market` event ($1 per 1,000).

## `includeOrderbook` (type: `boolean`):

Fetch the live order book for every market from Polymarket's CLOB. One extra request and one `orderbook` event ($2 per 1,000) per market.

## `orderbookDepth` (type: `integer`):

Number of price levels per side to include when the order book is on.

## Actor input object example

```json
{
  "eventSlugs": [
    "xi-jinping-out-before-2027",
    "uefa-champions-league-2027-champion-20260701202025549"
  ],
  "marketSlugs": [
    "will-paris-saint-germain-win-the-2026-27-uefa-champions-league-championship-20260701202025550"
  ],
  "tagSlug": "politics",
  "searchTerm": "bitcoin",
  "status": "active",
  "sortBy": "volume24hr",
  "maxMarkets": 200,
  "includeOrderbook": false,
  "orderbookDepth": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("rowfeed/polymarket-markets-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("rowfeed/polymarket-markets-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call rowfeed/polymarket-markets-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rowfeed/polymarket-markets-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CIrT3djH4qapTXJf3/builds/qwDksDbHScDBvXVx3/openapi.json
