# Prediction Markets Scraper – Kalshi & Polymarket (`anxuanng/prediction-markets-scraper`) Actor

Kalshi and Polymarket prediction market data in one schema: yes/no probabilities, bid/ask, last price, 24h change, volume, liquidity, open interest, close time and results. Filter by keyword, category, volume and close date; only-changed mode for monitoring.

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

## Pricing

$1.00 / 1,000 market scrapeds

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

## Prediction Markets Scraper – Kalshi & Polymarket

Get **Kalshi** and **Polymarket** markets in one clean schema: the question, **yes/no probabilities**, bid/ask,
last price, 24-hour change, **volume, liquidity and open interest**, close time and the result once resolved.
Filter by keyword, category, minimum volume and close date, or turn on **only-changed** mode to monitor odds
over time and pay only for markets that moved.

### What data can I get?

| Field | Example |
|---|---|
| `source`, `marketId`, `eventId` | `kalshi`, `KXELONMARS-99`, `KXELONMARS` |
| `eventTitle`, `marketTitle`, `marketLabel` | `Who will the next Pope be?`, the market's question, `Pietro Parolin` |
| `yesPrice`, `noPrice` | `0.105`, `0.895` (probabilities, 0–1) |
| `outcomes`, `outcomePrices` | `["Yes","No"]`, `[0.105, 0.895]` |
| `bestBid`, `bestAsk`, `lastPrice`, `priceChange24h` | `0.10`, `0.11`, `0.11`, `-0.02` |
| `volume`, `volume24h`, `liquidity`, `openInterest` | USD |
| `status`, `result` | `open` / `closed` / `resolved`, winning outcome |
| `openTime`, `closeTime` | ISO dates |
| `category`, `tags`, `rules` | `World`, topic tags, resolution rules |
| `url` | public market page |

Prices are normalised to probabilities on both exchanges, so a Kalshi 11¢ contract and a Polymarket 11% outcome
read the same: `0.11`.

### How much does it cost?

**$1 per 1,000 markets.** You pay only for markets delivered. A daily snapshot of the 500 busiest markets costs
$0.50.

### How do I use it?

1. Pick the exchanges (both by default) and the status (open, closed, or all).
2. Optionally filter: a keyword (`bitcoin`, `election`, `fed`), categories, minimum volume, or markets closing
   within N days.
3. Run, then download JSON, CSV or Excel, or call the API.

```json
{
  "sources": ["kalshi", "polymarket"],
  "search": "bitcoin",
  "status": "open",
  "minVolume": 10000,
  "closesWithinDays": 30,
  "maxItems": 500
}
```

### How do I track odds over time?

Turn on **Only changed** and schedule the Actor (e.g. every hour). Each run returns a market only if it is new or
its price or volume changed since your last run, so a quiet market costs nothing. Every row carries `scrapedAt`, so
the dataset history becomes your price series.

### Use cases

- **Trading and research:** compare the same event across Kalshi and Polymarket and spot price gaps.
- **Newsrooms and newsletters:** "what the markets say" on elections, the Fed, sports and tech, refreshed daily.
- **Data science:** resolved markets with their final prices for calibration studies.
- **Alerts:** only-changed runs piped to Slack or email when odds move.

### FAQ

**Where does the data come from?** From each exchange's official public market-data API (Kalshi trade API v2,
Polymarket Gamma API). No login, no trading, no private data.

**Is any personal data included?** No. No trader profiles, wallet addresses or comments are collected.

**How fresh is it?** Kalshi is live at run time. Polymarket's API is cached by the exchange for up to 5 minutes.

**Why does a keyword search take longer?** Kalshi has no server-side search, so the Actor reads every open market and
filters them; a narrow search can take a minute or two. You still pay only for the markets returned.

### More scrapers by the same developer

- [ATS Jobs Scraper](https://apify.com/anxuanng/ats-jobs-scraper): Job postings straight from company career boards on Greenhouse, Lever, Ashby, Workday, Workable, Recruitee and SmartRecruiters in one schema, with salary ranges and an only-new mode.
- [Chotot Scraper](https://apify.com/anxuanng/chotot-scraper): Scrape Chợ Tốt (chotot.com), Vietnam's largest classifieds site: cars, motorbikes, real estate, phones, laptops and more, with prices in VND, location and all item attributes. Pay per listing.
- [SEEK, JobStreet & JobsDB Jobs Scraper](https://apify.com/anxuanng/seek-jobs-scraper): Job listings from SEEK (Australia, New Zealand), JobStreet (Malaysia, Singapore, Philippines, Indonesia) and JobsDB (Hong Kong, Thailand) in one schema, with salary, work type, classification and an only-new mode.
- [Substack Scraper](https://apify.com/anxuanng/substack-scraper): Posts from any Substack newsletter with likes, comments, word count, free or paid flag and the full text of free posts. Search publications by keyword; only-new mode for monitoring.
- [Telegram Channel Scraper](https://apify.com/anxuanng/telegram-channel-scraper): Scrape public Telegram channels: posts, views, reactions, media, links, forwards, plus channel stats. Incremental mode for daily monitoring. Pay per post.
- [Vietnam Jobs Scraper](https://apify.com/anxuanng/vietnam-jobs-scraper): Scrape job postings from VietnamWorks, TopCV and ITviec in one unified schema. Extract title, company, salary in VND/USD, location, level, skills, deadline and full description. Pay per job, JSON/CSV export, API and MCP access.

# Actor input Schema

## `sources` (type: `array`):

Which prediction markets to read. Rows from both are returned in the same schema.

## `search` (type: `string`):

Keep markets whose event title, question or option label contains this phrase (case-insensitive), e.g. 'bitcoin', 'fed decision', 'world cup'. On Polymarket the phrase is matched against event titles. Empty keeps all.

## `categories` (type: `array`):

Keep markets in any of these categories or tags (case-insensitive). Kalshi categories: Politics, Elections, Economics, Financials, Crypto, Sports, Climate and Weather, Science and Technology, Entertainment, Companies. Polymarket tags: politics, sports, crypto, finance, economy, geopolitics, tech, pop-culture, weather. Empty keeps all.

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

'Open' returns markets trading now. 'Closed' returns markets that stopped trading, with the result once resolved, newest first. 'All' returns both.

## `minVolume` (type: `integer`):

Skip markets with less total traded volume than this. Kalshi volume is contracts traded; each pays $1, which is how Kalshi shows dollar volume. Try 1000 to skip dead markets.

## `closesWithinDays` (type: `integer`):

Open markets: keep only those closing in the next N days. Closed markets: keep only those that closed in the last N days. When empty, closed markets are read from the last 30 days.

## `onlyChanged` (type: `boolean`):

Return a market only if you have not received it before, or its price, volume, status or result changed since you last received it. Turn this on for scheduled monitoring so you pay only for movement.

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

Stop after this many markets across both exchanges; rows alternate between exchanges. You are only charged per market delivered.

## Actor input object example

```json
{
  "sources": [
    "kalshi",
    "polymarket"
  ],
  "status": "open",
  "onlyChanged": false,
  "maxItems": 1000
}
```

# Actor output Schema

## `markets` (type: `string`):

All market rows as JSON; append ?format=csv for CSV or ?format=xlsx for Excel.

## `runSummary` (type: `string`):

Counts of pushed/skipped/failed rows and whether the budget limit was hit.

# 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 = {
    "sources": [
        "kalshi",
        "polymarket"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("anxuanng/prediction-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 = { "sources": [
        "kalshi",
        "polymarket",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("anxuanng/prediction-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 '{
  "sources": [
    "kalshi",
    "polymarket"
  ]
}' |
apify call anxuanng/prediction-markets-scraper --silent --output-dataset

```

## MCP server setup

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