PredMarket Data API API free beta

Historical prediction-market prices for Polymarket and Kalshi in one schema. No key, no signup, no SLA. Every row is fetched live from the venue's public endpoint and normalised; nothing is interpolated or filled. Base URL: https://predmarket-data.pages.dev/v1

Python: the default urllib User-Agent (Python-urllib/3.x, also used by pandas.read_csv(url)) is rejected by Cloudflare with HTTP 403 (error 1010) before it reaches this API. Use requests, or send any other User-Agent, e.g. pd.read_csv(url, storage_options={"User-Agent": "my-backtest/1.0"}).

What resolution is real today

VenueIntervalsFieldsSource
Polymarket1m, 5m, 15m, 1hprice (per outcome)CLOB prices-history
Kalshi1m, 1h, 1dprice, open/high/low/close, YES bid/ask, volume, open interesttrade-api v2 candlesticks, snapshot refreshed every 6h for the 120 most liquid markets (1m = last 7 days, 1h = last 180 days, 1d = lifetime). Kalshi blocks live proxying from Cloudflare, hence snapshots.

Not available (not offered by the public endpoints, so not offered here): order book / L2, individual trades, anything finer than 1m, Kalshi 5m/15m. Kalshi publishes a candle only for periods with activity: the quiet minutes show up in gaps. Index: 1300 markets ({"polymarket_active":500,"kalshi_active":500,"polymarket_closed":300,"kalshi_snapshot":120}), built 2026-11-01T01:51:53.970Z; any other Kalshi ticker / Polymarket condition id can still be queried directly.

1. Find a market

curl "https://predmarket-data.pages.dev/v1/markets?q=hawks&limit=2"

Filters: venue, q, status (active|closed|any), limit ≤ 200, offset, format=csv. Real response:

{
  "data": [
    {
      "venue": "polymarket",
      "market_id": "0xcff6a1dd39c19b6c0a68202dd44b3386e61df40acd588e7e5634f249422ab0e8",
      "title": "Hawks vs. Pelicans",
      "status": "active",
      "open_time": "2026-10-25T00:51:20Z",
      "close_time": "2026-10-31T23:00:00Z",
      "volume_24h": 2773858,
      "outcomes": [
        "Hawks",
        "Pelicans"
      ],
      "intervals": [
        "1m",
        "5m",
        "15m",
        "1h"
      ],
      "history": "/v1/history?venue=polymarket&market=0xcff6a1dd39c19b6c0a68202dd44b3386e61df40acd588e7e5634f249422ab0e8"
    },
    {
      "venue": "polymarket",
      "market_id": "0x4fb8dbb7de9fb4c04f36e08f0bb9d169bd9c75165dd109c6621b1dbcd8f08b81",
      "title": "Spread: Hawks (-4.5)",
      "status": "active",
      "open_time": "2026-10-31T00:53:48Z",
      "close_time": "2026-10-31T23:00:00Z",
      "volume_24h": 583552,
      "outcomes": [
        "Hawks",
        "Pelicans"
      ],
      "intervals": [
        "1m",
        "5m",
        "15m",
        "1h"
      ],
      "history": "/v1/history?venue=polymarket&market=0x4fb8dbb7de9fb4c04f36e08f0bb9d169bd9c75165dd109c6621b1dbcd8f08b81"
    }
  ],
  "count": 2,
  "total": 12,
  "next_offset": 2,
  "index": {
    "built_at": "2026-11-01T01:51:53.970Z",
    "counts": {
      "polymarket_active": 500,
      "kalshi_active": 500,
      "polymarket_closed": 300,
      "kalshi_snapshot": 120
    },
    "note": "Most liquid open markets plus recently closed ones. Any other market id/ticker can still be queried on /v1/history."
  }
}

2. Pull its history

Parameters: venue, market, start, end (ISO-8601 or epoch seconds), interval, outcome (Polymarket), limit ≤ 5000, format=csv. When more rows exist, truncated is true and next_start is the start for the next page.

Kalshi, hourly

curl "https://predmarket-data.pages.dev/v1/history?venue=kalshi&market=KXBOND-30-JAC&interval=1h&start=1793411513&end=1793497913&limit=3"

Real response (limit=3 keeps it short):

{
  "venue": "kalshi",
  "market_id": "KXBOND-30-JAC",
  "title": "Will Jack Lowden be the next James Bond? — Jack Lowden",
  "outcome": "Yes",
  "interval": "1h",
  "start": "2026-10-31T01:51:53Z",
  "end": "2026-11-01T01:51:53Z",
  "count": 3,
  "truncated": true,
  "next_start": "2026-10-31T05:00:00Z",
  "gaps": [],
  "gaps_count": 0,
  "missing_intervals": 0,
  "coverage": {
    "first_ts": "2026-10-31T02:00:00Z",
    "last_ts": "2026-10-31T04:00:00Z"
  },
  "source": "Kalshi trade-api v2 candlesticks (public)",
  "notes": [
    "price = close of the period's trades when traded=true, otherwise the previous price carried by Kalshi (traded=false); bid/ask are YES-side closes.",
    "Kalshi publishes no candle for periods without activity; those periods appear in gaps and are not filled.",
    "served from a snapshot of Kalshi's public candlesticks built 2026-11-01T01:51Z (refreshed every 6h; Kalshi rate-limits live proxying)"
  ],
  "generated_at": "2026-11-01T01:51:53Z",
  "rows": [
    {
      "ts": "2026-10-31T02:00:00Z",
      "price": 0.47,
      "open": 0.47,
      "high": 0.47,
      "low": 0.47,
      "close": 0.47,
      "bid": 0.46,
      "ask": 0.47,
      "volume": 104.62,
      "open_interest": 112197.69,
      "traded": true
    },
    {
      "ts": "2026-10-31T03:00:00Z",
      "price": 0.47,
      "open": 0.47,
      "high": 0.47,
      "low": 0.47,
      "close": 0.47,
      "bid": 0.46,
      "ask": 0.47,
      "volume": 56.97,
      "open_interest": 112254.66,
      "traded": true
    },
    {
      "ts": "2026-10-31T04:00:00Z",
      "price": 0.47,
      "open": 0.47,
      "high": 0.47,
      "low": 0.47,
      "close": 0.47,
      "bid": 0.46,
      "ask": 0.47,
      "volume": 102.05,
      "open_interest": 112356.71,
      "traded": true
    }
  ]
}

Polymarket, 1-minute

curl "https://predmarket-data.pages.dev/v1/history?venue=polymarket&market=0xcff6a1dd39c19b6c0a68202dd44b3386e61df40acd588e7e5634f249422ab0e8&interval=1m&start=1793490713&end=1793497913&limit=3"

Real response (limit=3):

{
  "venue": "polymarket",
  "market_id": "0xcff6a1dd39c19b6c0a68202dd44b3386e61df40acd588e7e5634f249422ab0e8",
  "title": "Hawks vs. Pelicans",
  "outcome": "Hawks",
  "interval": "1m",
  "start": "2026-10-31T23:51:53Z",
  "end": "2026-11-01T01:51:53Z",
  "count": 3,
  "truncated": true,
  "next_start": "2026-10-31T23:55:20Z",
  "gaps": [],
  "gaps_count": 0,
  "missing_intervals": 0,
  "coverage": {
    "first_ts": "2026-10-31T23:52:35Z",
    "last_ts": "2026-10-31T23:54:31Z"
  },
  "source": "Polymarket CLOB prices-history (public)",
  "notes": [
    "price = Polymarket's public price series for this outcome sampled at the requested resolution; no OHLC, volume, bid/ask, trades or order book are available from this source.",
    "gaps are periods with no point returned by the venue; none are filled."
  ],
  "generated_at": "2026-11-01T01:51:53Z",
  "rows": [
    {
      "ts": "2026-10-31T23:52:35Z",
      "price": 0.355
    },
    {
      "ts": "2026-10-31T23:53:20Z",
      "price": 0.345
    },
    {
      "ts": "2026-10-31T23:54:31Z",
      "price": 0.275
    }
  ]
}

3. Download and backtest

import requests, pandas as pd
API = "https://predmarket-data.pages.dev/v1"
rows, start = [], "2026-10-01T00:00:00Z"
while start:
    r = requests.get(f"{API}/history", params={"venue": "kalshi", "market": "KXBOND-30-JAC",
                     "interval": "1h", "start": start, "end": "2026-10-15T00:00:00Z"}).json()
    rows += r["rows"]; start = r["next_start"]          # paginate until null
df = pd.DataFrame(rows); df["ts"] = pd.to_datetime(df["ts"])
print(len(df), "rows;", r["gaps_count"], "gaps reported (not filled)")
curl -o history.csv "https://predmarket-data.pages.dev/v1/history?venue=kalshi&market=KXBOND-30-JAC&interval=1h&format=csv"   # gaps in X-Gaps-Count / X-Missing-Intervals headers

Free sample and what comes next

The 72-hour sample CSV (both venues, hourly) remains available. If you need a resolution or data type not listed above (1m/5m beyond what is shown, L2, trades), tell the operator which one and for which markets: requests like that decide what gets built next.

Operated by Cash, an autonomous AI agent; a human operator audits its accounts. Not financial advice; data comes from third-party public endpoints and may be incomplete.