Logo
Soccer
Crypto
CS2
Trump
Elon Musk
US Politics
NHL
NFL

Developers / API & open data

One feed for Polymarket, Kalshi and Manifold

Predictions.io ingests every market from the three biggest prediction venues, normalizes them into one schema — prices as probabilities, volume in US dollars — and links the questions that are the same across venues. That data is available through one REST API — lobbies, events, markets, cross-venue matches and price history — with keys issued on request.

How access works

REST API — key-based

JSON endpoints for lobbies, events, markets, cross-venue matches and price history. Send your key as X-API-Key; 100 requests per minute per key by default, with the remaining quota in every response's headers.

Getting a key

Keys are issued by hand. Email support@predictions.io with what you are building and the request volume you expect, and we will set you up with a key and a limit that fits.

Quick start

One event, with its markets and the matched question on the other venue:

curl -s https://predictions.io/api/v1/events/EVENT_ID \
  -H "X-API-Key: YOUR_KEY"

curl -s https://predictions.io/api/v1/events/EVENT_ID/matches \
  -H "X-API-Key: YOUR_KEY"

Every response uses the same envelope, so a client only needs one parser:

{
  "ok": true,
  "data": {
    "id": "…",
    "platform": "polymarket",
    "title": "Will the Fed cut rates in September?",
    "volume": 4215330,
    "markets": [
      { "id": "…", "title": "Yes", "volume": 4215330,
        "outcomes": [ { "name": "Yes", "price": 0.62 },
                      { "name": "No",  "price": 0.38 } ] }
    ]
  },
  "meta": { "request_id": "req_…", "timestamp": "…", "cached": false }
}

Endpoints

All read-only, all under /api/v1. Cache times are how long a repeated call may return the same payload — the meta.cached flag tells you when it did.

EndpointReturnsCache
GET /api/v1/lobbiesEvery curated topic lobby with event counts and share URLs60 s
GET /api/v1/lobbies/:idOne lobby with its approved events, markets, and volume/sentiment stats60 s
GET /api/v1/lobbies/:id/summaryThe lobby's AI-generated market summary60 s
GET /api/v1/events/:idAn event with its markets, outcomes, prices and volume30 s
GET /api/v1/events/:id/matchesThe validated same-question matches for an event on the other venues120 s
GET /api/v1/markets/:idA single market with current outcome prices30 s
GET /api/v1/markets/:id/price-history?range=7d&fidelity=60Price history points for a market (range and fidelity in minutes)per range
GET /api/v1/currency/usd-ratesUSD → EUR / GBP rates used for displayhourly

Worked examples

What the main calls return once you have a key. Responses are trimmed for length; field names and shapes are exact.

1. The same question on another venue

The core of the feed: given one event, which events on the other venues have been validated as the same question. Pair this with /events/:id on each side and you have both venues' prices for one bet.

GET /api/v1/events/EVENT_ID/matches
X-API-Key: YOUR_KEY

{
  "ok": true,
  "data": [
    {
      "matched_event_id": "KXFEDDECISION-26SEP",
      "matched_event_title": "Fed decision in September?",
      "matched_platform": "kalshi",
      "similarity": 0.91,
      "confidence": 96
    }
  ],
  "meta": { "request_id": "req_…", "timestamp": "…", "cached": true, "cache_age_s": 41 }
}

2. Browse by topic

Lobbies are the human-curated topic hubs on the site. List them, then pull one with its approved events and markets.

GET /api/v1/lobbies
X-API-Key: YOUR_KEY

{
  "ok": true,
  "data": [
    {
      "id": 6,
      "title": "US Politics",
      "description": "Elections, Congress, the White House…",
      "event_count": 142,
      "review_count": 0,
      "images": { "description": { "avif": "…", "webp": "…" },
                  "background": { "avif": "…", "webp": "…" },
                  "sidemenu":   { "avif": "…", "webp": "…" } }
    }
  ],
  "meta": { "request_id": "req_…", "timestamp": "…", "cached": false }
}

GET /api/v1/lobbies/6            → the lobby with events, markets, volume + sentiment stats
GET /api/v1/lobbies/6/summary    → its AI-written market summary

3. Price history for a chart

Points are t (Unix seconds) and p (probability 0–1), downsampled to your fidelity in minutes. Ranges: 1d, 7d, 30d, 90d, all. The window anchors on the last data point, so a settled market still returns its final days.

GET /api/v1/markets/MARKET_ID/price-history?range=7d&fidelity=60
X-API-Key: YOUR_KEY

{
  "ok": true,
  "data": {
    "market_id": "MARKET_ID",
    "platform": "polymarket",
    "points": [
      { "t": 1756771200, "p": 0.58 },
      { "t": 1756774800, "p": 0.60 },
      { "t": 1756778400, "p": 0.62 }
    ],
    "updated_at": "2026-09-03T18:20:11.000Z"
  },
  "meta": { "request_id": "req_…", "timestamp": "…", "cached": false }
}

4. In code

JavaScript

const res = await fetch(
  "https://predictions.io/api/v1/events/EVENT_ID",
  { headers: { "X-API-Key": process.env.PREDICTIONS_KEY } }
);
const { ok, data, error } = await res.json();
if (!ok) throw new Error(error.code + ": " + error.message);

for (const m of data.markets) {
  const yes = m.outcomes.find((o) => o.name === "Yes");
  console.log(m.title, yes?.price);
}

Python

import os, requests

r = requests.get(
    "https://predictions.io/api/v1/events/EVENT_ID/matches",
    headers={"X-API-Key": os.environ["PREDICTIONS_KEY"]},
    timeout=10,
)
body = r.json()
if not body["ok"]:
    raise RuntimeError(body["error"]["code"])

for m in body["data"]:
    print(m["matched_platform"], m["matched_event_title"],
          m["confidence"])

5. Errors, limits and caching

Errors use the same envelope with ok: false. Codes: BAD_REQUEST 400, UNAUTHORIZED 401, FORBIDDEN 403, NOT_FOUND 404, RATE_LIMITED 429, INTERNAL_ERROR 500, SERVICE_UNAVAILABLE 503.

HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1756778460

{
  "ok": false,
  "error": { "code": "RATE_LIMITED",
             "message": "Rate limit exceeded",
             "retry_after_s": 23 },
  "meta": { "request_id": "req_…", "timestamp": "…" }
}

Every successful response carries the three X-RateLimit-* headers and an ETag. Send it back as If-None-Match and an unchanged payload returns 304 without counting against your body transfer; meta.cached and meta.cache_age_s tell you how fresh a cached hit is.

What the unified layer adds

The venues' own APIs are good. What they can't do is agree with each other — three price formats, three volume definitions, three ways to say "this question". The feed does that work once:

One schema

Market → outcomes → price, identical for every venue. Prices are probabilities from 0 to 1 whether the source quoted cents, token prices or a probability field.

Cross-venue matches

Embedding similarity finds candidate pairs, an LLM checks the two questions truly resolve on the same thing, a human validates. Only validated pairs are served — the set behind Polymarket vs Kalshi.

Dollar volume, comparable

Kalshi's volume_fp and Polymarket's volumeNum both land as USD; Manifold's mana is kept, but flagged as play money so it never mixes into dollar totals.

Curation and history

Human-curated topic lobbies, price history per market, and the whale-trade feed — context the raw venue APIs don't carry.

Polymarket API vs Kalshi API vs Manifold API

If you want to go straight to the source, here is how the three venues' own APIs differ — and why normalizing them is most of the work.

Polymarket API

Reads
Public: markets, events and prices via the Gamma API; order book via the CLOB API
Trading
Needs API credentials and an on-chain wallet (USDC on Polygon)
Quirks
Prices are outcome token prices 0–1; events group several markets; USD volume as volumeNum
Official docs ↗

Kalshi API

Reads
Public: markets, events, series and order books over REST; WebSocket feed for updates
Trading
Needs a registered account and signed API requests
Quirks
Prices in cents; legacy volume in contracts, dollar volume as volume_fp; series → events → markets hierarchy
Official docs ↗

Manifold API

Reads
Public REST, no key needed for reads
Trading
Key required; play-money (mana), not USD
Quirks
Probability field directly; resolution values in the market object; huge long tail of user-created questions
Official docs ↗

Questions developers ask

Is the Predictions.io API public?+

It is available on request. Every endpoint is key-based: tell us what you are building and the request volume you expect, and we issue a key with a per-minute limit that fits. There is no self-serve signup and no unauthenticated access.

Does Polymarket have an API?+

Yes. Polymarket exposes market and event data through its Gamma API and the order book through its CLOB API; reads are public, trading needs credentials and a Polygon wallet. Predictions.io re-serves that data in a normalized schema alongside Kalshi and Manifold, with the same questions matched across venues.

Does Kalshi have an API?+

Yes. Kalshi's trading API serves markets, events, series and order books over REST with a WebSocket feed; market data is public and trading requires signed requests. Our feed normalizes Kalshi's cent prices to probabilities and its volume_fp field to US dollars so it lines up with Polymarket.

How do you match the same market across Polymarket and Kalshi?+

Every event is embedded as a vector; candidates above a similarity threshold go to an LLM that judges whether the two questions genuinely resolve on the same thing, and a human reviews the result. Only validated pairs are served — the compare page and the /events/:id/matches endpoint both read from that set.

How fresh is the data?+

Background jobs sync all three venues continuously. API responses are cached for 30–120 seconds depending on the endpoint, and the meta.cached flag tells you when a response came from cache.

Can I get historical prices?+

Yes — /api/v1/markets/:id/price-history returns time-series points for a market; pass a range (for example 7d) and a fidelity in minutes. The site's own price charts read from the same endpoint.

How do I get an API key?+

Keys are issued by the Predictions.io team — email support@predictions.io with what you are building and expected request volume. Keys are rate-limited per minute and every request returns your remaining quota in the response headers.

Three venues, one schema, matched questions. Ask for a key.

Tell us what you are building and the volume you expect — we reply with a key and a limit that fits.

Request an API key