API

Chainlink TWAP resolution for Polymarket Up/Down markets

All 5,005 crypto Up/Down markets in the archive settle the same way: a Chainlink 60-second TWAP. This page documents the resolution source, the 60-second lookback that applies to every horizon, and how to reproduce a grade from the archived reference data.

What this guide covers

  • All 5,005 crypto Up/Down markets carry settlement_source = chainlink_twap
  • twap_enabled is true and twap_lookback_seconds is 60 for every market, regardless of horizon
  • settlement_config_source is gamma; resolution_source is a Chainlink Data Streams URL per coin
  • The 60-second TWAP is the same for 5-minute, 15-minute and 4-hour markets

How Up/Down markets grade

An Up/Down market asks a single question: is the reference price higher or lower at expiry than the strike recorded at open? Grading compares the market's settlement reference level at expiry against that opening strike, and the market resolves Up or Down accordingly.

Because the comparison uses a reference price and not the CLOB mid, a trader's PnL and the market's outcome can diverge. You can be right on the order book and still lose the contract if the reference feed printed the other direction - which is exactly why the reference data is archived next to the books.

The resolution source per coin

The archive records the exact resolution source for every market as a Chainlink Data Streams URL. The pattern is uniform: a 60-second TWAP stream for the asset in US dollars. The only variable is the asset symbol.

This is the authoritative answer to 'what price does this market settle on' - not a blog post or a UI tooltip. If you need to defend a backtest's settlement logic, cite the resolution_source recorded on the market itself.

Recorded resolution_source by asset (2026-10-17)
Assetresolution_source
btcdata.chain.link/streams/btc-usd-twap-60s-streams
ethdata.chain.link/streams/eth-usd-twap-60s-streams
soldata.chain.link/streams/sol-usd-twap-60s-streams
xrpdata.chain.link/streams/xrp-usd-twap-60s-streams
bnbdata.chain.link/streams/bnb-usd-twap-60s-streams
hypedata.chain.link/streams/hype-usd-twap-60s-streams
dogedata.chain.link/streams/doge-usd-twap-60s-streams
zecdata.chain.link/streams/zec-usd-twap-60s-streams

Why a 60-second TWAP, not a last price

A single print at expiry is gameable by a momentary wick: push the price for one tick, settle, release. A 60-second TWAP averages the reference across a full minute, so a one-tick manipulation barely moves the average. That single design choice removes most settlement-time gaming.

Averaging has a cost, though. On a choppy minute the TWAP can land far from both the open and the last trade, so a strategy that watched the book the whole window can still be graded against a level it never saw. Modeling against archived TWAP rows, rather than spot, is the only way to catch this.

Verifying a grade from the archive

To reproduce a grade, pull the TWAP reference rows around the market's close, take the value the stream published at expiry, and compare it to the opening strike. The archive holds both the reference rows and the market's books, so the whole chain is reconstructable from one API key.

If a reference row is missing for a window - because capture began partway through the day for some assets - fall back to the point-in-time snapshot endpoint, which reports how old the nearest reference observation is.

import requests

BASE = "https://api.polyorderbooks.com/v1"
HEADERS = {"X-API-Key": "your-key"}

# The TWAP the BTC stream published around a 5-minute close.
r = requests.get(
    f"{BASE}/reference-prices",
    headers=HEADERS,
    params={"asset": "btc", "kind": "twap",
            "start_ts": 1787486640, "end_ts": 1787486700},
)
r.raise_for_status()
rows = r.json()["data"]
print("twap at expiry:", rows[-1]["value"] if rows else None)

Code examples

import requests

BASE = "https://api.polyorderbooks.com/v1"
HEADERS = {"X-API-Key": "your-key"}

slug = "btc-updown-5m-1787486400"
r = requests.get(f"{BASE}/markets/{slug}", headers=HEADERS)
r.raise_for_status()
m = r.json()
print("question:", m.get("question"))
print("resolved label:", m.get("resolved_token_label"))

Free tier

The Starter plan is free, includes order books, prices, and metrics at 250ms resolution, with 3 days of history, 60 requests/min, 1,000/day, 1 free AI backtest, and 3 strategy backtests. No credit card required.

Paid data windows from $19/mo extend history to 30–120 days at higher throughput. Backtest AI add-on is +$19/mo or standalone at $29/mo.

FAQ

What price does a Polymarket crypto market settle on?

A Chainlink 60-second TWAP of the asset in US dollars. Every market records settlement_source = chainlink_twap and a resolution_source URL of the form data.chain.link/streams/<coin>-usd-twap-60s-streams.

Is the TWAP window different for 15-minute markets?

No. twap_lookback_seconds is 60 for every market, whether the horizon is 5 minutes, 15 minutes or 4 hours. The market horizon is the contract length; the TWAP window is always 60 seconds.

Why use a TWAP instead of the last price?

A 60-second TWAP makes momentary wicks at expiry ineffective, removing the easiest settlement-time manipulation. The trade-off is that a choppy minute can settle away from both the open and the last trade.

Can I reproduce the exact grade?

Yes. Pull the TWAP reference rows at the market close from /v1/reference-prices and compare to the opening strike; the archive stores both the reference series and the market books.