How to get resolved prediction market history as data

Five ways to pull settled markets and their outcomes out of Kalshi and Polymarket — a bulk snapshot, two venue APIs, SQL over the chain, and a workspace.

There are two shapes of answer. For a one-off backtest, download a pre-collected archive: Prediction Market Analysis ships both venues' trades, with Kalshi's settled result carried as a column and Polymarket's read off its market table. For anything current, call the venues yourself — Kalshi's historical endpoints for Kalshi, Gamma plus the price-history host for Polymarket. Neither gives you a complete record, and the outcome column is somebody's judgement rather than a reading.

The short way

Pick which question you are asking, because the two answers share nothing.

A one-off backtest over history that already happened. Download an archive. Prediction Market Analysis is the cheapest starting point in this catalogue, because somebody else already paid the collection cost: a make target pulls roughly 36 GiB compressed from the author's own object storage and extracts it to Parquet under data/kalshi and data/polymarket. The settled outcome is a field rather than an inference — the Kalshi market schema carries a result column of yes, no or empty beside a status of open, closed or finalized. The Polymarket trade tables carry no equivalent: the outcome sits on the market table rather than on the fills, which is the first place a naive join goes wrong.

import polars as pl

# The archive extracts to data/kalshi and data/polymarket. Point this at the market files.
markets = pl.read_parquet(KALSHI_MARKET_FILES)

settled = markets.filter(
    (pl.col("status") == "finalized") & (pl.col("result") != "")
)

Prices there are Kalshi's cents, 1 to 99, and the schema documentation notes that a no_price is always 100 minus the yes_price — so do not store both and expect them to disagree usefully.

Anything that has to stay current. Call the venues. Neither of them will give you the other.

What the options are

The Kalshi API is the most conventional surface in this catalogue and reads like a futures venue: series, events, markets, order books, trades and candlesticks over REST at external-api.kalshi.com/trade-api/v2, with candlesticks in 1-minute, 1-hour and 1-day periods. The part that matters here is that archived markets have a separate historical endpoint of their own, and that market data answers unauthenticated requests.

The Polymarket Gamma API is the read half of Polymarket and needs no key: events, markets, series, tags, sports fixtures and a search endpoint, each record carrying the slug, the condition id, the outcome token ids, the start and end dates and — the field worth more attention than it gets — the resolution rules text. Gamma carries no price history. That lives on Polymarket's Data API, at a prices-history endpoint keyed by the outcome token id you got from Gamma.

Polymarket dashboards on Dune answer the same questions in SQL instead, because Polymarket settles on Polygon and its whole order flow — fills, conditional-token transfers, positions, resolutions — is on a public chain. Reading and forking any dashboard is free with a view-only account; running or scheduling your own queries, CSV export and higher API limits are what the paid plans are for. Kalshi has no public chain behind it and is not in Dune's data at all.

Lychee is the no-code version: a browser workspace over both archives, with query, chart, backtest and export to CSV, XLSX or JSON. It is the fastest way to an answer and the quickest to hit a wall — a historical pull is capped at 12,500 rows on its cheapest paid tier and 500,000 on the next, and there is no free plan, only a demo on the home page.

Where this breaks

The outcome column is a judgement with a source behind it, not a reading. On Kalshi the exchange resolves its own markets under the rules of each series, and the series record in the API carries a settlement_sources list with the name and URL of the source, links to the contract terms and to the product certification filed with the CFTC. On Polymarket the outcome is proposed to the UMA optimistic oracle against a bond, with a challenge window, a second proposal round on a first dispute, and escalation to a token-holder vote on a second. That vote can return Unknown, in which case the market resolves 50/50 and every token on both sides redeems at 50 cents. A backtest that assumes a binary payout books a result nobody collected. Who decides how a prediction market resolves is the page to read before you treat the column as ground truth, and the rules text rather than the question title is where the real source and the edge cases live.

A venue's archive is not a complete record, and the gaps are shaped differently on each. Kalshi's live endpoints stop at a moving cutoff: markets, candlesticks, trades, orders and positions older than that timestamp move to the parallel historical endpoints, and the cutoff advances over time — so a backfill written against the live endpoints quietly loses its tail. Query the cutoff rather than assuming a fixed window. The bulk archive has the opposite problem: the repository has no tags and no versioned distribution, so "which vintage of the data do you have" has no answer beyond the day you downloaded it, and it carries no order books at all — trade executions and market metadata only, which rules out any question that needs the book at a point in time. DepthFeed and Predexon are where that question goes.

Two of these archives may be one archive. Lychee advertises 7.68 million-plus unique markets, 72.1 million-plus historical trades since July 2021 and a 36 GB-plus compressed archive. Those three numbers are, to the digit, the size of the Prediction Market Analysis dataset, and Lychee names no upstream source for its Kalshi side at all.

A licence on the code is not a licence on the data. Prediction Market Analysis is MIT by its LICENSE file, and its research page states no licence for the dataset itself — the venues' own terms govern material collected from their APIs. That is a question to settle before you redistribute rather than after.

If you outgrow this

If you need more than two venues, the rented version exists and so does the cost of it: tools that cover more than one venue is the listing, and Adjacent vs DepthFeed vs Predexon is the head to head. Every one of them flattens a difference to put two venues in one schema, and on resolved history the difference being flattened is exactly the one above.

If what you actually want is whether the prices were any good rather than what they were, Brier.fyi already did the matching and the scoring — read how accurate a prediction market's price actually is first, and note that its pipeline is paused, so what you are reading is an archive with a published method.

The approaches, in order

Cards in the catalogue that do this, ordered editorially. Paid placement does not affect this order.

  1. 1.Prediction Market Analysis

    A pre-collected Parquet archive of both venues' trades — Kalshi's settled result is a column, Polymarket's has to come off its market table.

    Open-source Kalshi and Polymarket dataset, indexers and analysis scripts.

    FreeFree tierOpen source

  2. 2.Kalshi API

    The exchange's own data, with archived markets on a parallel set of historical endpoints behind a cutoff that keeps advancing.

    REST, WebSocket and FIX access to a CFTC-regulated event exchange.

    Free tier onlyFree tier

  3. 3.Polymarket Gamma API

    Polymarket's free catalogue of markets and their rules text; the price series lives on a separate host, keyed by outcome token id.

    Polymarket's read-only catalogue of events, markets, series and tags.

    FreeFree tier

  4. 4.Polymarket dashboards on Dune

    SQL over Polymarket's on-chain record, free to read and fork, where a resolution is a settlement you can see rather than a field.

    Community SQL dashboards over Polymarket's on-chain record, free to read and fork.

    Free tier onlyFree tier

  5. 5.Lychee

    A browser workspace over both archives with row-capped exports, for when the answer is wanted before there is a pipeline to put it in.

    No-code queries, charts and backtests over Kalshi and Polymarket history.

    $19.99/mo

FAQ

Is there one endpoint that returns every resolved market on every venue?

No. Kalshi and Polymarket are unrelated systems with different identifiers, different price units and different resolution processes, and nothing first-party spans them. The cross-venue feeds in this catalogue do span them, at the cost of flattening the differences — read the cross-venue collection before treating two matched rows as the same question.

Do I need an account to read settled markets?

Not for the two venue APIs here. Kalshi's REST market data answers unauthenticated requests, and Polymarket's Gamma API needs no key and no account at all. What needs an account is Kalshi's WebSocket, which returns 401 without signed headers even on channels carrying only public data, and anything about your own fills on either venue.

Why does a settled Polymarket contract sometimes redeem at 50 cents?

Because a UMA token-holder vote can return Unknown. Polymarket's own documentation describes that case as the market resolving 50/50, with every token on both sides redeeming at 50 cents. Code that assumes a binary payout will mis-book that day, and a backtest that assumes it will quietly book a profit that nobody collected.

How far back does the free data go?

It depends what you mean by free. The Prediction Market Analysis snapshot behind its companion paper runs from June 2021 to November 2025 on the Kalshi side; anything after that you collect yourself. Artemis publishes a per-venue data-start date for thirteen venues, which is the cheapest way to find out where a chart legitimately begins.

Sources

  1. Resolution Polymarket, read
  2. Discover markets Polymarket, read
  3. API environments Kalshi, read
  4. Dataset schemas Jonathan Becker, read

The catalogue next door

This page names a handful of cards. The rest of them are in Prediction Market Data APIs, each filled in against the same schema, with the fields to narrow it yourself.

Last updated . Corrected in place: this is a reference page, not a dated post.