API
Joining Polymarket markets to reference prices in Python
To grade a market yourself, join three things: the market's open strike, its expiry time, and the reference price at expiry. The archive gives you the reference series and the market metadata, so the join is a few lines of Python.
What this guide covers
- Crypto markets settle on a Chainlink 60-second TWAP of the asset in USD
- get_market returns the market object; the reference series comes from /v1/reference-prices
- Grading compares the reference level at expiry against the opening strike
- The SDK does not wrap the reference endpoint, so use requests for that call
The three inputs
Grading needs the opening strike, the expiry timestamp and the reference value at expiry. The market object supplies the timing; the reference series supplies the settlement level. The join is on the asset and the expiry window.
Because markets settle on the 60-second TWAP rather than the last trade, the reference series - not the book - is the correct input. Pulling the contract's final price would grade a different question.
Finding the expiry value
Query the reference endpoint for the asset over a window ending at expiry and take the last TWAP observation at or before the close. That is the value the grade compares against the strike.
If the window is empty - because reference capture did not cover it - the market cannot be graded from reference data. Record it as ungradeable rather than falling back to a spot print, which would silently change the settlement rule.
Labeling the outcome
The label is simply the sign of the difference: reference at expiry above the strike is Up, below is Down. Compare against the market's recorded result when available to validate your join; disagreement usually means a timezone or boundary error, not a data error.
Build this into a function so every market in a study is graded identically. A grading rule applied by hand across a hundred markets will contain mistakes; a single function will not.
Building a graded dataset
Once grading is a function, loop it over a list of markets to build a labeled dataset: slug, strike, expiry, reference at expiry and the label. That table is the input to any study that needs outcomes rather than raw books.
Cache the reference lookups as you go, because many markets in the same window share the same asset and expiry. A small in-memory dictionary keyed by asset and expiry avoids re-fetching the same reference rows.
Export the graded table alongside the books. Reproducible research needs both the market data and the labels, and regenerating labels later risks a subtle difference in the join.
Code examples
import os
import requests
from polyorderbooks import PolyOrderbooksClient
BASE = "https://api.polyorderbooks.com/v1"
KEY = os.environ["POLYORDERBOOKS_API_KEY"]
HEADERS = {"X-API-Key": KEY}
def reference_twap(asset, at_ts):
r = requests.get(
f"{BASE}/reference-prices",
headers=HEADERS,
params={"asset": asset, "kind": "twap",
"start_ts": at_ts - 300, "end_ts": at_ts},
)
r.raise_for_status()
rows = r.json()["data"]
return rows[-1]["value"] if rows else None
with PolyOrderbooksClient(api_key=KEY) as c:
market = c.get_market("btc-updown-5m-1787486400")
strike = market.get("strike")
expiry = 1787486700
level = reference_twap("btc", expiry)
if level is None or strike is None:
label = "ungradeable"
else:
label = "Up" if level > float(strike) else "Down"
print(market["slug"], 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 reference should I grade against?
The 60-second Chainlink TWAP for the market's asset. That is the settlement input, so a contract's final price is the wrong series.
Does the SDK expose reference prices?
Not currently. Its coverage ends at books, prices and metrics, so call /v1/reference-prices with requests using the X-API-Key header.
What if the reference window is empty?
Mark the market ungradeable. Reference capture does not cover every window, and falling back to spot would change the settlement rule.
How do I match the market's own result?
Compare your label to the market's recorded outcome. Disagreements usually indicate a boundary or timezone error in the join, not a data problem.