Data
Exports
Order book history as Parquet, served via presigned download URLs. The files, formats and free samples are described on Polymarket dataset.
/markets/{market_id}/exportclient.exports.download(market_id)Order book history (snapshots, deltas, trades) for a single market as a Parquet file. Returned as a 302 redirect to a presigned URL valid for one hour. The file's rows are charged against your data row allowance the first time only; a file you already unlocked charges zero rows on every later request. On Free, whole market exports cover markets open in the last 7 days, and a file that does not fit the remaining free allowance answers FREE_ALLOWANCE_EXHAUSTED (402) with rows_needed.
from datetime import datetime, timedelta, timezone
end = datetime.now(timezone.utc) - timedelta(days=1)
[market] = client.markets.list(
series_id="btc-up-or-down-5m", status="resolved",
close_before=end, sort="-close_time", take=1,
)
client.exports.download(
market.id,
data_dir="data",
)
result = client.backtest(
strategy, market.id,
initial_cash=10_000,
data_dir="data",
)HTTP/1.1 302 Found
Location: https://hel1.your-objectstorage.com/marketlens/history/...
X-Export-Rows: 92866
Cache-Control: no-store/series/{series_id}/exportclient.exports.download_series(series_id, **params)Order book history for every market in a series, with one presigned URL per ready market. Each market's file charges its row count the first time you unlock it; markets you already unlocked appear with rows: 0 and cost nothing, so polling a series for newly built markets is free. Markets whose first unlock does not fit your remaining row balance are listed under rate_limited without URLs, and wall states it once: the reason, how many markets were withheld, the rows needed to finish, when the monthly allowance resets (null on Free) and the upgrade link. The SDK raises IncompleteExportError with those fields after downloading the ready files, on plain downloads and inside backtests alike. On Free, the manifest serves markets open in the last 7 days and names older ones in outside_window, and a series export where no market fits the remaining free allowance answers FREE_ALLOWANCE_EXHAUSTED (402) and charges nothing. Pass dry_run first to see the exact cost of a window before spending it; on Free it still answers the quote with its wall block.
from datetime import datetime, timedelta, timezone
end = datetime.now(timezone.utc) - timedelta(days=1)
client.exports.download_series(
"btc-up-or-down-5m",
data_dir="data",
after=end - timedelta(minutes=15),
before=end,
)
result = client.backtest(
strategy, "btc-up-or-down-5m",
initial_cash=10_000,
after=end - timedelta(minutes=15),
before=end,
data_dir="data",
){
"ready": [
{
"market_id": "4ee145e2-3fee-5b15-bb95-56a33a292945",
"url": "https://hel1.your-objectstorage.com/marketlens/history/...",
"events": 92866,
"rows": 92866
},
{
"market_id": "8b6f1a02-9c3d-4e7a-b1f8-2a9d4c5e6f70",
"url": "https://hel1.your-objectstorage.com/marketlens/history/...",
"events": 81234,
"rows": 0
}
],
"pending": [],
"failed": [],
"rate_limited": [],
"wall": null,
"events_charged": 174100,
"rows_charged": 92866,
"coverage": {"data_start": 1766791812000, "data_end": 1767743412000, "collection_tier": "streamed"}
}/markets/{market_id}/orderbook/metrics/exportclient.exports.download_market_bars_batch(market_ids, **params)Order-book metrics or OHLCV candles for a single market at one resolution, as a Parquet file. Returned as a 302 redirect to a presigned URL.
from datetime import datetime, timedelta, timezone
end = datetime.now(timezone.utc) - timedelta(days=1)
[market] = client.markets.list(
series_id="btc-up-or-down-5m", status="resolved",
close_before=end, sort="-close_time", take=1,
)
bars = client.exports.download_market_bars_batch(
[market.id],
resolution="1m",
price="mid",
data_dir="bars",
)
result = client.backtest(
strategy, market.id,
initial_cash=10_000,
resolution="1m",
data_dir=bars,
)HTTP/1.1 302 Found
Location: https://hel1.your-objectstorage.com/marketlens/metrics/...Auto-download
Backtest directly against the bulk export, no separate download step required. The first run fetches the files to disk; subsequent runs replay from the local cache. The signal backtest works the same way, downloading bar Parquet on the first run.
from datetime import datetime, timedelta, timezone
end = datetime.now(timezone.utc) - timedelta(days=1)
# downloads on first run, replays from cache after
result = client.backtest(
strategy, "btc-up-or-down-5m",
initial_cash=10_000,
after=end - timedelta(minutes=5),
before=end,
data_dir="data",
)