# Election Odds API — Kalshi & Polymarket Live Probabilities (`lergassy/election-odds-api`) Actor

Live election odds from both prediction markets in one table: implied probability, price, 24h move, volume and close date for every political contract on Kalshi and Polymarket. Midterms, presidential races, party control, primaries and nominations, and national elections worldwide. No API key.

- **URL**: https://apify.com/lergassy/election-odds-api.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** News, Developer tools, Automation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.75 / 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.
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?

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

**Election Odds API** returns what the two big prediction markets currently price for every election on the board — Kalshi and Polymarket in one table, in one shape. Each contract comes back with the implied probability in per cent, the yes and no price, best bid and ask, the 24-hour move, volume, liquidity and the close date. No API key, no account, no browser.

![One run of Election Odds API: election contracts from Kalshi and Polymarket with probability, move and volume.](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/election-odds-api/election-odds-api-output-table.png)

Presidential races, midterms, party control of the House and Senate, primaries and nominations, governors and mayors, and elections outside the US — Brazil, Germany, the UK, wherever a market exists.

### What is Election Odds API?

When people ask "what are the odds", they usually mean the number people are actually betting at, not a pundit's guess. Prediction markets publish exactly that, and this Actor turns it into data for newsrooms, dashboards, researchers and AI agents that get asked who is going to win.

Four modes: **markets** (one row per contract), **events** (one row per race with every candidate and their probability), **search** by keyword, and **price history**.

### What makes it different

**It is an election board, not a politics board.** Both venues file plenty of non-election contracts under a political tag — Polymarket's Fed-rate markets carry a "Politics" tag, and a naive filter fills the table with interest rates. This Actor matches on what the contract actually asks, so the board is elections and nothing else. On the run this README was written from, zero of sixty rows were off-topic.

**Both venues, one schema.** Kalshi is the CFTC-regulated US exchange, Polymarket the global crypto-settled one. They word the same race differently and price it differently. The rows come back interleaved, so a capped run always shows both rather than whichever venue reports larger numbers.

**A race in one row.** The events mode collapses a race into a single row with every candidate sorted by probability, the favourite, and a ready-made summary sentence — the shape a chart or a paragraph actually needs.

### What data does it return?

| Field | Example |
|---|---|
| `platform`, `marketId`, `slug` | polymarket · 516729 · … |
| `question`, `eventTitle` | Will the Democratic Party control the House after the 2026 Midterms? |
| `probability`, `yesPrice`, `noPrice` | 87.5 (per cent) · 0.875 · 0.125 |
| `bestBid`, `bestAsk`, `spread`, `lastPrice` | 0.87 · 0.88 · 0.01 · 0.875 |
| `priceChange24h` | 0.02 — a move in price, so ±0.02 is two points of probability |
| `volume`, `volume24h`, `liquidity`, `openInterest` | … |
| `status`, `openTime`, `closeTime`, `category`, `tags` | open · ISO 8601 · Elections |
| `outcomes`, `rules`, `url` | every side with its price · resolution text · link |

Events mode adds `favourite`, `favouriteProbability`, `outcomeCount` and a `summary`. History mode returns one row per price point.

### How much does it cost?

| Event | Price |
| --- | --- |
| Market | $0.0025 |
| Event (a whole race) | $0.0012 |
| Price point | $0.0002 |
| Order book snapshot | $0.001 |

**Error rows are never charged, and there is no charge for starting a run.** Two public JSON APIs, no browser and no proxy.

| Job | Cost |
| --- | --- |
| 500 election contracts across both venues | $1.25 |
| Every race as one row (≈100 races) | $0.12 |
| A daily 200-contract snapshot for a month | $15.00 |

### How to use it

1. Choose **📋 What to get**: markets, events, search or price history.
2. Narrow with **🔍 Keyword** — `midterm`, `senate`, `brazil`, a candidate's name.
3. Set **💧 Minimum volume** — both venues list thousands of near-empty contracts, and 1000 keeps the ones people actually trade.
4. Sort by 24-hour volume, total volume, probability, biggest move or closing date.
5. Click **Start**, then export as JSON, CSV or Excel, or read the dataset through the API.

![The input form of Election Odds API: mode, keyword, volume filter and sorting.](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/election-odds-api/election-odds-api-input-form.png)

### ⬇️ Input

```json
{ "mode": "markets", "minVolume": 1000, "sortBy": "volume24h", "maxMarkets": 200 }
```

#### Every race with all candidates

```json
{ "mode": "events", "minVolume": 5000, "maxMarkets": 60 }
```

#### One race by keyword

```json
{ "mode": "search", "query": "midterm", "minVolume": 500 }
```

### ⬆️ Output

```json
{
  "type": "market",
  "platform": "polymarket",
  "question": "Will the Democratic Party control the House after the 2026 Midterms?",
  "category": "Elections",
  "probability": 87.5,
  "yesPrice": 0.875,
  "noPrice": 0.125,
  "bestBid": 0.87,
  "bestAsk": 0.88,
  "priceChange24h": 0.02,
  "volume": 4120880.5,
  "volume24h": 218400.25,
  "liquidity": 96300.75,
  "status": "open",
  "closeTime": "2026-11-04T05:00:00Z",
  "url": "https://polymarket.com/event/...",
  "scrapedAt": "2026-09-09T13:00:00.000Z"
}
```

A venue that fails to answer arrives as a `type: "error"` row with the reason, never as a silently short list.

### Use cases

#### Newsroom graphics

One row per race, updated as often as you schedule it, with the number readers recognise.

#### Election night dashboards

Sort by 24-hour move to see what repriced overnight, or by closing date for what resolves next.

#### Research

Pull price history across a campaign and study how the crowd's estimate moved against the news.

#### Alerts

Schedule the run and fire when a probability crosses a threshold you care about.

#### AI agents

An agent asked "who is favoured in the midterms" runs the events mode and reads `favourite` and `favouriteProbability` off one row.

### 🤖 For AI Agents & LLM Apps

Compact reference for agents calling this Actor through the [Apify MCP server](https://mcp.apify.com) or the Apify API (`lergassy/election-odds-api`).

**Minimal input:**

```json
{ "mode": "events", "query": "senate", "minVolume": 1000 }
```

**Behaviors an agent should know:**

- **`probability` is the field to quote**, in per cent. `yesPrice` is the same number as a price between 0 and 1, because a contract pays $1 if the event happens.
- `priceChange24h` is a change in *price*: 0.02 is two percentage points of probability.
- Always pass `minVolume` (1000 is a good floor) or thin contracts crowd out the real ones.
- Kalshi and Polymarket word the same race differently and their prices need not agree. Say which venue a number came from, and read `rules` before treating two contracts as the same bet.
- The board is already filtered to elections; `query` narrows it further.
- Both APIs are public: no key, no account, no proxy.

### ❓ FAQ

#### Is this a forecast?

No. It is what people are paying right now, which is a market price rather than a model's prediction. Treat it as such.

#### Why do Kalshi and Polymarket disagree?

Different user bases, fees and resolution wording. The gap is real information, but check `rules` before assuming the two contracts settle the same way.

#### Which elections are covered?

Whatever the two venues list — US federal and state races, primaries and nominations, and national elections elsewhere. Run it and see; the board changes weekly.

#### How fresh are the numbers?

Live at the moment of the run. Schedule the Actor for a time series of your own.

#### Can I use it with the Apify API or an MCP server?

Yes. It runs from the API and the official clients, and AI agents reach it through the Apify MCP server without extra setup.

### Your feedback

Missing a race or a field? Open an issue on the **Issues** tab — every one gets answered.

### You might also like

| Actor | What it does |
|---|---|
| [Prediction Markets API](https://apify.com/lergassy/prediction-markets-api) | The whole board, not only elections |
| [Kalshi Scraper & API](https://apify.com/lergassy/kalshi-scraper) | Every Kalshi market on its own |
| [Polymarket Scraper & API](https://apify.com/lergassy/polymarket-scraper) | The same for Polymarket |
| [Kalshi Weather Markets](https://apify.com/lergassy/kalshi-weather-scraper) | Temperature brackets with the forecast beside them |

### Also known as

People look for this Actor as an election odds API, prediction market election data, midterm odds, presidential election odds, Kalshi election markets and Polymarket election odds.

# Actor input Schema

## `platforms` (type: `array`):

Which venues to read. Keep both to get one table across the whole prediction market.

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

<b>Markets</b> gives one row per tradable contract. <b>Events</b> collapses them into one row per question with every outcome and its probability, which is the shape you want for “who will win” questions.

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

Filter to markets whose question, event or tags contain this text: <code>fed</code>, <code>election</code>, <code>bitcoin</code>, <code>super bowl</code>.

## `category` (type: `string`):

Kalshi category or Polymarket tag: Politics, Economics, Crypto, Sports, Culture, Science. Several at once, comma separated — <code>Politics, Crypto</code> keeps a market matching either.

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

Drop thin markets. Both venues list thousands of near-empty contracts; 1000 keeps the ones people actually trade.

## `minLiquidity` (type: `integer`):

Drop markets with less than this much money resting in the book, in US dollars. Polymarket publishes this figure; Kalshi reports zero on almost every market, so on Kalshi use <b>Minimum open interest</b> instead.

## `minOpenInterest` (type: `integer`):

Drop markets with fewer than this many contracts still open. This is Kalshi's measure of how much is actually at stake in a market.

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

How to order the result.

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

Cap on rows per run. The default is deliberately small so a first run costs cents; raise it once you know which markets you need.

## `includeClosed` (type: `boolean`):

Off by default: only markets you can still trade.

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

For the history and order-book modes: Kalshi tickers such as <code>KXOAIANTH-40-OAI</code> or Polymarket numeric ids. Leave empty to use the most active markets.

## `historyDays` (type: `integer`):

How far back the price history goes.

## `seriesTicker` (type: `string`):

Narrow Kalshi to one series, for example <code>KXPRESPARTY</code>.

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

Price levels per side in the order-book mode.

## Actor input object example

```json
{
  "platforms": [
    "kalshi",
    "polymarket"
  ],
  "mode": "markets",
  "minVolume": 0,
  "minLiquidity": 0,
  "minOpenInterest": 0,
  "sortBy": "volume24h",
  "maxMarkets": 25,
  "includeClosed": false,
  "historyDays": 7,
  "orderbookDepth": 10
}
```

# Actor output Schema

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

One row per market with the venue, the question, implied probability in per cent, yes and no prices, best bid and ask, 24h price move, volume, liquidity, close date and link. Compare mode returns one row per matched question with both probabilities and the gap; history mode one row per price point; order-book mode one row per market with both sides.

# 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 = {
    "query": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/election-odds-api").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 = { "query": "" }

# Run the Actor and wait for it to finish
run = client.actor("lergassy/election-odds-api").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 '{
  "query": ""
}' |
apify call lergassy/election-odds-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/election-odds-api"
        }
    }
}
```

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/kj5kPK3VWtBf6Sbbg/builds/yIQm2Er0PgF3N8Whf/openapi.json
