vike

Recipe 11 of 30

How accurate were Polymarket's final prices? A calibration curve

For each settled market take the outcome's price a fixed time before the close from /ohlcv, bucket the prices, and compare each bucket with how often that outcome won on /settlements/bulk.

GET /v1/polymarket/ohlcv gives an outcome's price, a probability from 0 to 1, at the moment you choose before the close, in one call per market. GET /v1/polymarket/settlements/bulk lists the settled markets with their token ids and the winning token. Bucket the prices (0-10%, 10-20%, ...) and compare each bucket's average price with the share of its outcomes that won: a calibrated market wins 70% of the time when it says 70%. The candle parameters are on Outcome candles.

Quick answer

Take Up's minute bars from two minutes before a 5-minute window's end to its final minute.

cURL
# Up's minute bars from two minutes before the window end to the final minute
curl -H "X-API-Key: $VIKE_API_KEY" \
  "https://data.vike.io/v1/polymarket/ohlcv?token_id=49453782677730298729295238194951727156421227964664364260179136470131299796336&interval=1m&from=1792840380000&to=1792840440000"

Example response

Captured from the live API on 2026-10-24 at 17:14 UTC, both bars of the 7:10-7:15 AM ET market. The window ends at 1792840500000 (11:15 UTC). The first bar closes one minute before that, with Up at 0.63; the second is the final minute, which already falls to 0.01 as the answer becomes clear. Score the first bar, never the last. The settlement says Down won, so this is a 63% price that lost. The next two markets of the settlement page closed their scored bar at 0.01 on Up, and Down won both.

Example response
[
  {"close": 0.63, "high": 0.92, "low": 0.53, "open": 0.87, "trades": 199, "ts": 1792840380000, "volume": 3787.328807},
  {"close": 0.01, "high": 0.81, "low": 0.01, "open": 0.63, "trades": 243, "ts": 1792840440000, "volume": 7789.647681}
]

Variations

The markets to score, with their winners. One bulk call lists a family's settled markets with token_ids, outcomes and winning_token_id; each market's window end comes from its slug.

cURL — settled markets
# settled 5-minute BTC markets, with token ids and the winner
curl -H "X-API-Key: $VIKE_API_KEY" \
  "https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792840425357&limit=5"

Did the favourite win, a week before. For long markets, take the daily bar a week before resolved_ts_ms. This market resolved on 2026-09-03 and Yes traded at 0.004 a week earlier; No won, so the favourite won.

cURL — a week before
# the Yes token's daily bar that starts seven to eight days before resolution
curl -H "X-API-Key: $VIKE_API_KEY" \
  "https://data.vike.io/v1/polymarket/ohlcv?token_id=100208760979006815700821365554623989048585541964271047036444923380678560443951&interval=1d&from=1787721750000&to=1787808150000"
cURL — its winner
# the on-chain winner of the same market
curl -H "X-API-Key: $VIKE_API_KEY" \
  "https://data.vike.io/v1/polymarket/settlements/0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13"

A longer lead time. Four minutes before the end of a 5-minute window is the bar at the window start.

cURL — four minutes out
# Up's first minute bar of the window
curl -H "X-API-Key: $VIKE_API_KEY" \
  "https://data.vike.io/v1/polymarket/ohlcv?token_id=49453782677730298729295238194951727156421227964664364260179136470131299796336&interval=1m&from=1792840200000&to=1792840200000"

Thousands of markets. One call per market adds up. For a large sample, download the daily trades files and price every market from them.

cURL — archive
# the daily trades files of the 5-minute BTC family
curl -H "X-API-Key: $VIKE_API_KEY" \
  "https://data.vike.io/v1/polymarket/archive/datasets?asset=btc&tenor=5m&stream=trades&limit=5"

Before you rely on it

limit keeps the oldest bars

Bars come oldest first and limit cuts the recent end, so to=X&limit=1 returns the first bar of the token's whole tape, not the last one before X. Bound the window with from as well and take the last row. A bar exists only for a minute that traded, so a missing bar means no trade, not a price. Only markets Vike recorded have candles, from 2026-07-25 on. A daily bar closes at the end of its UTC day, which can be after your cut: use 1h or 1m bars for an exact moment.

Ask your agent

Connected to the Vike MCP server (https://vike.io/mcp) in Claude, ChatGPT or Cursor, ask it in plain words. The polymarket_ohlcv tool answers, at 1 credit a call, with polymarket_settlement for the winner at 1 credit a call.

Ask your agent
What was the Up price one minute before the end of the Bitcoin Up or Down 7:10AM-7:15AM ET market of October 24, and which side won?
Example response
[  {"close": 0.63, "high": 0.92, "low": 0.53, "open": 0.87, "trades": 199, "ts": 1792840380000, "volume": 3787.328807},  {"close": 0.01, "high": 0.81, "low": 0.01, "open": 0.63, "trades": 243, "ts": 1792840440000, "volume": 7789.647681}]