# Polymarket Scraper: Election Odds & Midterms 2026 Markets (`pennydata/polymarket-markets-scraper`) Actor

Election odds and implied probability from Polymarket: House, Senate and Governor midterms 2026 markets as JSON (yes/no price, bid/ask, volume, liquidity, close time). Input {"electionMode":true,"maxItems":25}. $0.003/row. Kalshi markets optional. Public API, no login or wallet. AI-operated.

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

## Pricing

from $2.10 / 1,000 row scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Polymarket Scraper: Election Odds, Midterms 2026 & Prediction Markets

**Election-week ready (Nov 3, 2026).** Click Start: the prefilled input returns the 15 most traded US midterms markets (House, Senate, California governor, balance of power, ballot measures), about $0.045. Copy-paste scheduled run, movers only, every 15 minutes (create a Schedule with cron `*/15 * * * *` and this input):

```
{"mode":"markets","preset":"us-midterms","moversOnly":true,"sinceLastRun":true,"minMovePts":2,"maxItems":50}
```

The first run stores a baseline; each later run returns only markets that moved at least 2 points, with `prev_price`, `delta` and `hours_since`. The `us-midterms` preset unions the tags midterms, governor-midterms, senate-midterms and referendums-midterms with any event slug matching midterm, election-2026 or balance-of-power (deduped by event, most traded first). Narrow it with `race`: `house`, `senate`, `governor`, `balance-of-power` or `ballot-measures`.

Polymarket scraper for prediction market odds: yes/no price, volume and close time as flat rows. Click Start: the prefilled input (15 most traded US midterms markets) runs as is, about $0.045. Get Polymarket odds for the US midterms (Nov 3, 2026) as flat rows: yes/no price, volume and close time for Senate, House and balance-of-power election markets. Also works for any other Polymarket topic.

Get Polymarket prediction-market data as flat rows: search markets by keyword or tag, read current outcome prices, volume and liquidity, and pull price history for any market. You are charged $0.003 per row returned; failed requests, unknown markets and empty results are free (charged only for rows that contain data). Built with AI assistance (Claude); maintained by the publisher. Not affiliated with, endorsed by or sponsored by Polymarket.

### Quickstart (one API call)

```bash
curl -X POST "https://api.apify.com/v2/acts/pennydata~polymarket-markets-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"markets","preset":"us-midterms","maxItems":15}'
```

Or open the Actor in the Console and click **Start**: the prefilled input (preset `us-midterms`, the 15 most traded active US midterms markets right now) runs as-is. Use `"tagSlug":"elections"` for all elections, or clear the tag for top markets overall. Store page: https://apify.com/pennydata/polymarket-markets-scraper

### Kalshi markets (optional source)

Set `"source":"kalshi"` to read Kalshi's public prediction markets instead of Polymarket, or `"source":"both"` for Polymarket first, then Kalshi (about half of `maxItems` from each). Default is `polymarket`, so existing inputs behave as before. Example, Kalshi US midterms 2026 markets, most traded first:

```
{"source":"kalshi","preset":"us-midterms","maxItems":25}
```

Kalshi rows use the same fields as Polymarket rows (`question`, `yesPrice` and `noPrice` as implied probability from the bid/ask midpoint, `volume`, `endDate`, `url`) plus `source: "kalshi"`, so one dataset can hold both. For Kalshi, `yesPrice` is the midpoint of the yes bid and ask (last trade if there is no quote), `volume` is contracts traded, `priceChange24h` is last price minus previous-day price, and `id` is the Kalshi market ticker. Keyword (`query`), `electionMode`, the `us-midterms` preset, `race`, `moversOnly` and `activeOnly` work with Kalshi; `tagSlug`, `market-detail` and `price-history` are Polymarket only. The Kalshi midterms preset matches Politics and Elections events whose ticker or title says midterm or 26NOV. Same price per row ($0.003).

### Modes

| mode | input used | one row is |
|---|---|---|
| `markets` | `query` or `preset`/`tagSlug`, `race`, `activeOnly`, `maxItems` | one market with current prices, volume, liquidity. No keyword or tag: top markets by 24h volume |
| `market-detail` | `marketIds` (ids or slugs) | one market, current snapshot |
| `price-history` | `marketIds`, `historyInterval`, `historyFidelity` | one outcome of one market, with a `history` array of `{t, p}` price points |

### Pricing

Pay per event, no subscription. **$3 per 1,000 rows ($0.003 per row).** A `price-history` row is one outcome with its whole history array (for example 168 hourly points for a week), billed once.

| Event | When it is charged | Price |
|---|---|---|
| `item-scraped` | One market or one outcome-history row was returned. | $0.003 |

Errors, unknown markets and empty results are not charged. Set a maximum cost per run to cap spend.

### Polymarket election odds and implied probability

Prices are implied probabilities (0.675 = 67.5%). Pull House, Senate and Governor election odds for the US midterms, or any other prediction market, as flat rows.

### US midterms 2026 odds

Polling stations close on Nov 3, 2026 and Polymarket odds move fast. Use the **Election preset** and the **Race filter** to pull live odds with no tag lookup:

- `"preset":"us-midterms"`: US midterm markets (Senate, House, governor, balance of power, ballot measures), most traded first. Unions four tags plus slug matches, deduped by event.
- `"preset":"all-elections"`: every active election market worldwide.
- `"race":"senate"`, `"house"`, `"governor"`, `"balance-of-power"` or `"ballot-measures"`: keep only markets whose question or event title mentions that race (keyword match). Default `any`.

Every row has flat `yesPrice`, `noPrice` and `change24h` (24h move of the yes price, e.g. 0.04 = +4 points; `null` if Polymarket sends none) next to the full `outcomes` array.

Input: `{"mode":"markets","preset":"us-midterms","maxItems":5}`. Five rows from a real local run on 2026-10-22 (prices are probabilities):

| question | yesPrice | change24h | volume24hr (USD) | ends |
|---|---|---|---|---|
| 2026 Balance of Power: D Senate, D House | 0.675 | 0.04 | 438636 | 2026-11-04 |
| 2026 Balance of Power: D Senate, R House | 0.0085 | null | 117272 | 2026-11-04 |
| 2026 Balance of Power: R Senate, D House | 0.235 | -0.04 | 216944 | 2026-11-04 |
| 2026 Balance of Power: R Senate, R House | 0.075 | -0.01 | 1239907 | 2026-11-04 |
| 2026 Balance of Power: Other | 0.0015 | null | 187294 | 2026-11-04 |

Election-night recipe: schedule the Actor every few minutes with `{"mode":"markets","preset":"us-midterms","race":"senate","maxItems":50}` for a rolling odds feed, then run `price-history` on the market ids you care about (`"historyInterval":"1d","historyFidelity":5`) to chart how the odds moved as results came in. Each run costs 50 rows x $0.003 = $0.15.

### Election night

Set `"electionMode": true` for a one-click midterms feed: only US 2026 midterm Senate, House and governor markets (tag `midterms`), most traded in the last 24h first. Every row carries `priceChange24h` (24h move of the yes price, 0.04 = +4 points), `volume24h` (USD) and `endDate`. It overrides keyword, preset and tag in markets mode. Pricing is unchanged: $0.003 per row.

Example input:

```
{"mode":"markets","electionMode":true,"maxItems":50}
```

### Example: US midterms 2026 election markets

Input: `{"mode":"markets","tagSlug":"midterms","maxItems":25}`

Sample output row (shortened, from the live API on 2026-10-20; yes/no price, volume, close time):

```json
{
  "id": "562828",
  "question": "2026 Balance of Power: D Senate, D House",
  "url": "https://polymarket.com/event/balance-of-power-2026-midterms",
  "eventTitle": "Balance of Power: 2026 Midterms",
  "outcomes": [
    { "name": "Yes", "price": 0.635 },
    { "name": "No", "price": 0.365 }
  ],
  "volume": 6122343.98,
  "endDate": "2026-11-04T04:59:00Z",
  "active": true,
  "closed": false
}
```

Each row also has `tokenId`, `lastTradePrice`, `bestBid`, `bestAsk`, `spread`, `volume24hr`, `liquidity` and `scrapedAt`.

Prices are probabilities between 0 and 1. Fields Polymarket does not return are `null`.

### Data source, limits and terms

- Data source: the public, unauthenticated Polymarket Gamma API (market discovery and metadata) and CLOB API (price history), both listed in the Polymarket developer docs (https://docs.polymarket.com/getting-started/api.md): "Gamma API https://gamma-api.polymarket.com Discover events and markets, and retrieve the metadata needed to work with them." and "CLOB API https://clob.polymarket.com Read prices and order books, then place and manage orders."
- Kalshi source (optional): the public, unauthenticated Kalshi market-data API (https://api.elections.kalshi.com/trade-api/v2/events, https://docs.kalshi.com). No API key or login; read-only, no orders. Requests are sequential and spaced, with backoff on HTTP 429/5xx, well below Kalshi's published read limits. Not affiliated with Kalshi; use the data in line with Kalshi's terms and applicable law.
- Read-only. This Actor never places, signs or manages orders and needs no wallet or key. Polymarket restricts order placement in some regions; this Actor does not place orders.
- Rate limits: requests are spaced and retried with exponential backoff on HTTP 429/5xx, honouring `Retry-After`, far below the limits Polymarket publishes (https://docs.polymarket.com/api-reference/rate-limits.md).
- Not financial advice. Prices are a snapshot and can be stale or illiquid. You are responsible for using the data in line with Polymarket's Terms of Use and applicable law.

### Prediction market data for House, Senate and Governor races

One row per market: yes/no price, volume, liquidity and close time. Filter with `race`: `house`, `senate`, `governor`, `balance-of-power`, `ballot-measures`.

### Use cases

Prediction-market dashboards, odds and probability tracking, research datasets of forecasts, event-risk monitoring, backtesting against historical prices.

### Election night: biggest movers

Add `movers` to see which markets moved most in the last 1, 6 or 24 hours. The actor takes the most traded matching Polymarket markets (up to about 2x Max items, at most 150), pulls the public CLOB price history of each Yes token, and returns them sorted by absolute change, biggest mover first. Each row keeps all its normal fields and adds `priceFrom`, `priceTo`, `priceChange` (probability delta, 0.05 = +5 points), `pctChange` (relative to `priceFrom`), `windowHours`, `fromAt` and `toAt`.

- `windowHours`: 1, 6 or 24 (default 24).
- `minAbsChange`: drop markets that moved less than this, as a probability delta (0.02 = 2 points). Default 0.

Example for election night, top 20 midterm movers over the last 6 hours: `{"preset":"us-midterms","maxItems":20,"movers":{"windowHours":6,"minAbsChange":0.01}}`

Polymarket only (Kalshi rows are skipped in this mode). Only returned rows are charged, $0.003 each, same event as before. Without `movers` nothing changes. Movement shown is as reported by Polymarket price history, so quiet markets with no trades show 0.

### Movers only

Set `"moversOnly": true` to keep only markets whose yes price moved at least `minMovePts` points (default 5) over the last 24 hours, up or down, based on Polymarket's `oneDayPriceChange`. Markets with no 24h change are skipped. Default is off, so existing inputs behave as before. Pricing is unchanged: $0.003 per row returned.

Input for a daily midterms movers feed: `{"mode":"markets","electionMode":true,"moversOnly":true,"minMovePts":5,"maxItems":50}`

#### Movers since your last run (scheduled)

Add `"sinceLastRun": true` to compare against the snapshot saved by your previous run (stored in the named key-value store `polymarket-movers` on your account, one snapshot per keyword/preset/race). Only markets whose yes price moved at least `minMovePts` points are returned, with `prev_price`, `delta` (points) and `hours_since`. The first run returns every market and saves the baseline, so you pay for the first run's rows only once. Schedule it from Apify Console, for example hourly: cron `0 * * * *`, input `{"mode":"markets","electionMode":true,"moversOnly":true,"sinceLastRun":true,"minMovePts":3,"maxItems":200}`. Default off; pricing unchanged.

### Feedback

If this Actor saved you time, a short honest rating on its Store page helps others find it: https://apify.com/pennydata/polymarket-markets-scraper/reviews . Bugs or missing fields: open an issue on the Actor page.

# Actor input Schema

## `electionMode` (type: `boolean`):

Only US 2026 midterm Senate, House and governor markets (tag midterms), sorted by 24h volume, with priceChange24h, volume24h and endDate on every row. Overrides keyword, preset and tag in markets mode.

## `moversOnly` (type: `boolean`):

Markets mode: keep only markets whose yes price moved at least the minimum points over the last 24h (up or down). Combine with electionMode or the US midterms preset for a daily movers feed. Rows without a 24h change are skipped.

## `sinceLastRun` (type: `boolean`):

Use with Movers only, for scheduled runs. Compares the yes price with the snapshot stored by your previous run (same keyword/preset/race) and returns only markets that moved at least the minimum points, with prev_price, delta (points) and hours_since. The first run returns all markets and stores the baseline.

## `minMovePts` (type: `number`):

Used with Movers only. Minimum 24h move of the yes price in percentage points, e.g. 5 = 0.05 probability.

## `movers` (type: `object`):

Optional. {"windowHours": 1|6|24, "minAbsChange": 0.02}. Markets mode, Polymarket: pulls the public CLOB price history for the Yes token of the most traded matching markets, adds priceFrom, priceTo, priceChange (probability delta, 0.05 = 5 points), pctChange and windowHours, drops markets below minAbsChange and sorts by absolute change, biggest mover first. Max items limits rows returned (and charged). Kalshi is not included. Leave empty for the normal behaviour.

## `source` (type: `string`):

polymarket (default) = Polymarket only; kalshi = Kalshi public markets only (markets mode; keyword, election mode, US midterms preset, race filter and movers options apply, tag slug does not); both = Polymarket then Kalshi, about half of Max items from each. Every row has a source field. market-detail and price-history modes are Polymarket only.

## `mode` (type: `string`):

markets = search markets by keyword or tag (or top markets by 24h volume when both are empty); market-detail = current prices for the given market ids or slugs; price-history = price history per outcome for the given market ids or slugs.

## `query` (type: `string`):

Keyword for markets mode, e.g. bitcoin, fed rate, election. Leave empty to list top markets by 24h volume.

## `preset` (type: `string`):

One-click election odds. us-midterms = union of tags midterms, governor-midterms, senate-midterms, referendums-midterms plus slugs matching midterm / election-2026 / balance-of-power, deduped by event and sorted by volume (Nov 3 2026); all-elections = tag elections (worldwide elections). custom = use the Tag slug below. A keyword, if given, still takes priority.

## `race` (type: `string`):

Keep only markets whose question or event title mentions this race: senate, house (also congress), governor, balance-of-power, ballot-measures (referendums such as California's wealth tax). any = no filter. Works with the US midterms preset or any tag/keyword in markets mode.

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

Polymarket tag slug for markets mode, e.g. midterms, elections, politics, crypto, sports. Used when no keyword is given. Default midterms = US midterm election markets; clear it (and the keyword) to list top markets by 24h volume.

## `marketIds` (type: `array`):

Polymarket market ids (e.g. 5409680) or slugs. Used by market-detail and price-history modes.

## `activeOnly` (type: `boolean`):

Skip closed and resolved markets in markets mode.

## `maxItems` (type: `integer`):

Maximum rows to return (1-2000).

## `historyInterval` (type: `string`):

price-history mode: how far back to read prices.

## `historyFidelity` (type: `integer`):

price-history mode: minutes between price points (for example 60 = hourly).

## Actor input object example

```json
{
  "electionMode": false,
  "moversOnly": false,
  "sinceLastRun": false,
  "minMovePts": 5,
  "source": "polymarket",
  "mode": "markets",
  "preset": "us-midterms",
  "race": "any",
  "tagSlug": "midterms",
  "activeOnly": true,
  "maxItems": 15,
  "historyInterval": "1w",
  "historyFidelity": 60
}
```

# 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 = {
    "source": "polymarket",
    "mode": "markets",
    "preset": "us-midterms",
    "race": "any",
    "tagSlug": "midterms",
    "maxItems": 15
};

// Run the Actor and wait for it to finish
const run = await client.actor("pennydata/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 = {
    "source": "polymarket",
    "mode": "markets",
    "preset": "us-midterms",
    "race": "any",
    "tagSlug": "midterms",
    "maxItems": 15,
}

# Run the Actor and wait for it to finish
run = client.actor("pennydata/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 '{
  "source": "polymarket",
  "mode": "markets",
  "preset": "us-midterms",
  "race": "any",
  "tagSlug": "midterms",
  "maxItems": 15
}' |
apify call pennydata/polymarket-markets-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pennydata/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/f7snhnv8bXNcUgWEq/builds/fyhmYU0DyfDEFdiqe/openapi.json
