# Polymarket & Kalshi Odds API Data Scraper (`pulse-data/polymarket-kalshi-odds`) Actor

Get live Polymarket and Kalshi odds in one table. Filter markets by keyword, category, venue, volume or close time and export clean JSON for analysis.

- **URL**: https://apify.com/pulse-data/polymarket-kalshi-odds.md
- **Developed by:** [Pulse Data](https://apify.com/pulse-data) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 market row delivereds

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?

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 & Kalshi Odds Scraper: Market Data API

Get live Polymarket and Kalshi odds in one clean table. This Actor reads the public market-data APIs of Polymarket and Kalshi and returns one row per prediction market: the question, the price and implied probability of every outcome, best bid and ask, last trade, 24-hour and total volume, liquidity or open interest, status, close time, a unified category and a link. No API key, no login, no proxy and no browser are needed, and the rows of the two venues have exactly the same fields, so you can sort, filter and compare them in Google Sheets, Excel, Python, n8n or Make without writing two different API clients.

### Example output

One Polymarket row (a Federal Reserve market) and one Kalshi row (a daily high-temperature bracket for New York City), exactly as the Actor returns them:

```json
{"schemaVersion": 1, "venue": "polymarket", "marketId": "2589811", "slug": "will-the-fed-decrease-interest-rates-by-25-bps-after-the-october-2026-meeting-20260617190324030", "eventId": "606422", "eventTitle": "Fed Decision in October?", "series": "fomc", "question": "Will the Fed decrease interest rates by 25 bps after the October 2026 meeting?", "outcomes": [{"name": "Yes", "price": 0.0055, "probabilityPct": 0.55}, {"name": "No", "price": 0.9945, "probabilityPct": 99.45}], "primaryOutcome": "Yes", "primaryProbabilityPct": 0.55, "bestBid": 0.005, "bestAsk": 0.006, "lastPrice": 0.006, "volume24h": 534822.74, "volumeTotal": 6622382.12, "volumeUnit": "USD", "liquidity": 367175.36, "openInterest": null, "status": "open", "winningOutcome": null, "openTime": "2026-06-18T00:02:08Z", "closeTime": "2026-10-29T03:59:00Z", "category": "economics", "venueCategory": "economy", "tags": ["fed", "fomc", "trump", "economy", "fed-rates", "kevin-warsh", "Global-Rates", "economic-policy", "macro-indicators", "recurring"], "marketType": "binary", "strikeType": null, "floorStrike": null, "capStrike": null, "url": "https://polymarket.com/event/fed-decision-in-october-20260617190323537", "rules": null, "fetchedAt": "2026-10-13T06:08:33Z"}
```

```json
{"schemaVersion": 1, "venue": "kalshi", "marketId": "KXHIGHNY-26OCT13-T71", "slug": null, "eventId": "KXHIGHNY-26OCT13", "eventTitle": "Highest temperature in New York City on Oct 13, 2026?", "series": "KXHIGHNY", "question": "Will the maximum temperature be <71° on Oct 13, 2026?", "outcomes": [{"name": "Yes", "price": 0.365, "probabilityPct": 36.5}, {"name": "No", "price": 0.635, "probabilityPct": 63.5}], "primaryOutcome": "Yes", "primaryProbabilityPct": 36.5, "bestBid": 0.34, "bestAsk": 0.39, "lastPrice": 0.35, "volume24h": 4558.25, "volumeTotal": 4668.45, "volumeUnit": "contracts", "liquidity": null, "openInterest": 3376.95, "status": "open", "winningOutcome": null, "openTime": "2026-10-12T14:00:00Z", "closeTime": "2026-10-14T05:00:00Z", "category": "weather", "venueCategory": "Climate and Weather", "tags": [], "marketType": "binary", "strikeType": "less", "floorStrike": null, "capStrike": 71.0, "url": "https://kalshi.com/markets/kxhighny", "rules": null, "fetchedAt": "2026-10-13T06:10:42Z"}
```

Prices are in US dollars for a contract that pays 1 dollar, so 0.365 means an implied probability of 36.5 percent. Polymarket volume is in US dollars; Kalshi volume is in contracts (see the FAQ).

### What you can do with it

- Follow the most active open markets on both venues in one table, ranked by 24-hour volume. On Kalshi the Actor always reads the popular series (NFL, NBA, MLB, NHL, college football and UFC game winners, daily high temperatures in five US cities, Fed decisions and CPI) before it samples other events, so the sports games and weather brackets people trade today are in the table.
- Search by keyword: bitcoin, fed rate, election, hurricane, a candidate or a team.
- Filter by unified category: politics, elections, world, economics, finance, crypto, sports, weather, entertainment, science-tech.
- Read whole Kalshi series, for example KXHIGHNY (highest temperature in New York City) with its temperature brackets as numbers (strikeType, floorStrike, capStrike).
- Feed a spreadsheet, a dashboard, a newsletter or a research notebook on a schedule; every row carries a fetchedAt time in UTC.
- Export the closed markets of a venue to study how questions were priced before they ended.

Kalshi combination ("parlay") markets are left out on purpose, because they drown out the real markets in the venue's default listing.

### How it works

1. Choose the venues, an optional keyword or category, and how many market rows you want.
2. Run the Actor. It reads the venues politely (one request at a time, about two requests per second at most), drops what you filtered out and turns every market into the same row format.
3. Open the Markets overview view or export the dataset as JSON, CSV or Excel, or call it from your own code or automation. In the overview, the Event column shows the event each market belongs to (for example the matchup, city and date), so short questions such as "Denver wins" stay unambiguous.

If one venue is temporarily unavailable, the Actor still returns the rows of the other one and says so in the run's status message. A summary record (RUN_SUMMARY) in the key-value store shows what was read and why the run stopped.

### Output fields

| Field | Meaning |
|---|---|
| schemaVersion | Version of this output format. |
| venue | Which prediction market the row comes from. |
| marketId | Polymarket market id, or Kalshi market ticker. |
| slug | Polymarket market slug; null for Kalshi. |
| eventId | Polymarket event id, or Kalshi event ticker. |
| eventTitle | Title of the event that groups related markets. |
| series | Kalshi series ticker, or the Polymarket series slug when the event belongs to one. |
| question | The market question. |
| outcomes | Every outcome with its current price (US dollars for a 1 dollar payout) and implied probability in percent. |
| primaryOutcome | Name of the first outcome (Yes for Yes/No markets). |
| primaryProbabilityPct | Implied probability in percent of the first outcome. |
| bestBid | Highest buy price of the first outcome in US dollars; null when nobody is bidding. |
| bestAsk | Lowest sell price of the first outcome in US dollars; null when nobody is offering. |
| lastPrice | Price of the last trade of the first outcome in US dollars; null when unknown. |
| volume24h | Traded volume in the last 24 hours, in the unit given by volumeUnit. |
| volumeTotal | Total traded volume since the market opened, in the unit given by volumeUnit. |
| volumeUnit | Unit of the volume fields: USD for Polymarket, contracts for Kalshi. |
| liquidity | Polymarket order book liquidity in US dollars; null for Kalshi. |
| openInterest | Kalshi open interest in contracts; null for Polymarket. |
| status | Unified market status. |
| winningOutcome | Name of the winning outcome once settled; null otherwise. |
| openTime | When the market opened for trading, UTC. |
| closeTime | When trading closes or closed, UTC. |
| category | Unified category. |
| venueCategory | The venue's own category label (Kalshi) or the Polymarket tag slug used for the unified category. |
| tags | Polymarket tag slugs of the event (at most 20); empty for Kalshi. |
| marketType | binary: two outcomes; scalar: Kalshi numeric market; multi: more than two outcomes. |
| strikeType | Kalshi strike type of the market, for example less, between or greater; null otherwise. |
| floorStrike | Kalshi lower strike value, for example a temperature bracket start; null otherwise. |
| capStrike | Kalshi upper strike value; null otherwise. |
| url | Link to the market page on the venue's website. |
| rules | Resolution rules text; null unless Include resolution rules is on. |
| fetchedAt | When the Actor received this data, UTC. |

### Pricing

You pay per delivered market row: 0.0008 US dollars per row (0.80 US dollars per 1,000 rows) on the free plan, less on higher Apify plans, plus Apify's small start fee per run. You are charged only for rows that were actually delivered to the dataset: nothing for filtered, duplicate or skipped markets, nothing for failed requests, nothing for runs that fail. Platform costs are not passed on to you. If you set a maximum cost per run, the Actor stops at that limit and tells you how many rows it delivered.

### FAQ

**Do I need an API key or an account at Polymarket or Kalshi?** No. The Actor uses only public, documented market-data endpoints that need no key.

**Is this legal?** The Actor requests only the public APIs of the two venues, politely and without logging in or bypassing anything. You are responsible for using the data in line with the terms of Polymarket and Kalshi. This Actor is not affiliated with or endorsed by either venue; the names are used only to say where the data comes from.

**Is this financial advice?** No. It is data, not advice, and it does not trade. Prices can change at any moment; check the venue before you rely on a number.

**Why is Kalshi volume in contracts and Polymarket volume in dollars?** Because that is what each venue publishes. The volumeUnit field tells you which unit a row uses. The Actor does not convert one into the other, and it ranks the two venues separately, then alternates their rows, so that the units are never mixed.

**How are the most active Kalshi markets found?** Kalshi's API cannot sort by volume and lists long-dated events first, so the Actor ranks what it reads: a fixed list of popular series (game winners in the main US sports and UFC, daily high temperatures in New York City, Los Angeles, Chicago, Miami and Austin, Fed decisions and CPI), then a sample of 600 other open events. Full depth reads up to 12,000 events and takes much longer. A popular market outside these series is found only if it is in the sample, which for politics, elections, entertainment and world markets is rarely the case; enter the series ticker to read such a series directly. The RUN_SUMMARY record tells you how many requests and pages were read.

**Why did I get fewer rows than my maximum?** Fewer markets matched your filters, or one venue was unavailable (the status message says so).

**What are Kalshi series tickers?** A series is a family of recurring Kalshi markets, for example KXHIGHNY for the daily high temperature in New York City. Enter tickers to read only those families.

**How fresh is the data?** The Actor reads the venues when it runs; the fetchedAt field is the moment each page was received. Schedule the Actor to refresh it.

**Does it include settled markets from Kalshi?** Only markets the live Kalshi API still lists with their details; the closed status returns trading-ended markets. Long-term history is not part of this Actor.

### Input settings

| Setting | What it does | Default |
|---|---|---|
| Venues | Polymarket, Kalshi or both | both |
| Keyword | Every word must appear in the event title or question (case-insensitive) | empty |
| Categories | Unified categories to keep | all |
| Market status | Open (tradable now) or closed (trading ended) | open |
| Kalshi series tickers | Read only these Kalshi series (up to 20); skips the popular series and the sample | none |
| Minimum 24h volume | Skip quieter markets (USD for Polymarket, contracts for Kalshi) | 0 |
| Include resolution rules | Add the full rules text to each row | off |
| Sort by | 24h volume (highest first, venues alternate) or close time (soonest first; markets already past their close time are left out) | 24h volume |
| Kalshi scan depth | Standard (popular series + 600 events) or full (up to 12,000 events) | standard |
| Maximum market rows | Stop after this many rows (1 to 5,000) | 20 |

# Actor input Schema

## `venues` (type: `array`):

Which prediction markets to read. Results from the two venues are returned in one unified format.

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

Only return markets whose event title or question contains every word you type (case-insensitive). Leave empty for all markets. Example: bitcoin, fed rate, hurricane.

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

Only return markets in these unified categories. Leave empty for all categories.

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

Open returns markets that can be traded now. Closed returns markets whose trading has ended (closed or settled) and that were actually traded.

## `kalshiSeriesTickers` (type: `array`):

Optional. Read only these Kalshi series, for example KXHIGHNY for the daily high temperature in New York City. When set, the Actor skips its built-in highlight series and its general scan. Ignored when Kalshi is not selected. Maximum 20.

## `minVolume24h` (type: `number`):

Skip markets traded less than this in the last 24 hours. Polymarket volume is in US dollars, Kalshi volume is in contracts; see the volumeUnit field. 0 keeps everything.

## `includeRules` (type: `boolean`):

Add the full resolution rules text to every row (makes rows larger). Off by default.

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

Volume ranks the most traded markets first within each venue and alternates venues. Close time puts markets that close soonest first across both venues and leaves out markets whose close time has already passed; with status Closed it puts the most recently closed first.

## `scanDepth` (type: `string`):

Kalshi cannot rank markets by volume itself, so the Actor ranks what it reads. Standard reads the popular Kalshi series (sports games, daily weather, Fed and CPI) plus up to 600 other events. Full reads up to 12,000 events and takes much longer.

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

Stop after this many market rows have been delivered. You are charged per delivered row.

## Actor input object example

```json
{
  "venues": [
    "polymarket",
    "kalshi"
  ],
  "query": "",
  "categories": [],
  "status": "open",
  "kalshiSeriesTickers": [],
  "minVolume24h": 0,
  "includeRules": false,
  "sortBy": "volume24h",
  "scanDepth": "standard",
  "maxItems": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

A concise table using the overview view defined in dataset_schema.json.

## `allData` (type: `string`):

All market records produced by the Actor. The dataset view selector includes the overview and quotes views.

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

The RUN_SUMMARY record written by the Actor to the default key-value store.

# 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("pulse-data/polymarket-kalshi-odds").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("pulse-data/polymarket-kalshi-odds").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 pulse-data/polymarket-kalshi-odds --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pulse-data/polymarket-kalshi-odds"
        }
    }
}
```

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/xxXnNr0ZMrhmwtB0E/builds/ZXayic1MTzDRHzpIx/openapi.json
