API
PolyOrderbooks REST API reference
The PolyOrderbooks REST API serves historical L2 order books, prices, metrics, and market metadata for Polymarket crypto markets. This reference covers the base URL, authentication, all four endpoints, query parameters, response formats, and error handling.
What this guide covers
- Base URL: https://api.polyorderbooks.com/v1
- Authentication: X-API-Key header on every request
- 4 endpoints: /markets, /books, /prices, /metrics
- JSON responses with consistent error format
Base URL and authentication
All API requests go to https://api.polyorderbooks.com/v1. There is no trailing slash issue because the API normalizes paths. All responses are JSON.
Authentication requires an X-API-Key header on every request. Get your key from the dashboard after signing up for a plan. The key is per-request, not per-IP, so the same key works from multiple machines.
There is no OAuth flow, no bearer token, and no session management. The API key is a static secret that you include in every request header. Rotate keys from the dashboard if you suspect a leak.
The API supports HTTP/2 and keep-alive connections. Reuse your HTTP client across requests for better performance, especially in batch workflows.
The four endpoints
GET /v1/markets returns a list of available markets with slugs, coin identifiers, timeframes, and resolution timestamps. This is the discovery endpoint for finding slugs for downstream calls.
GET /v1/markets/{slug}/books returns full L2 order book snapshots. Each response is an array of snapshots containing the complete bid/ask ladder at each timestamp.
GET /v1/markets/{slug}/prices returns the midpoint price series. Each entry contains a timestamp and the midpoint price (average of best bid and best ask).
GET /v1/markets/{slug}/metrics returns pre-computed liquidity metrics: spread, bid depth, ask depth, and VWAP at each timestamp.
| Method | Path | Description |
|---|---|---|
| GET | /v1/markets | List markets with filters |
| GET | /v1/markets/{slug}/books | L2 order book snapshots |
| GET | /v1/markets/{slug}/prices | Midpoint price series |
| GET | /v1/markets/{slug}/metrics | Liquidity metrics |
Query parameters
The /markets endpoint accepts: coin (string filter), timeframe (string filter), status (active/resolved), limit (max 100), and cursor (pagination). All are optional.
The /books, /prices, and /metrics endpoints accept: start_ts (Unix seconds), end_ts (Unix seconds), and resolution (1s to 60s). Resolution controls the time granularity of returned data.
When start_ts and end_ts are omitted, the endpoint returns the full lifecycle of the market from open to resolution. When provided, only the data within the specified window is returned.
Resolution is a string: "1s" for second-level granularity, "5s" for 5-second, "1m" for minute-level. At 1s resolution, a 5-minute market returns approximately 300 snapshots.
Error handling
The API uses standard HTTP status codes. 200 for success, 400 for bad requests (missing or invalid parameters), 401 for unauthorized (missing or invalid API key), 404 for not found (invalid slug), and 429 for rate limited.
Error responses have a consistent JSON structure: {"error": "<message>"}. Parse this to surface meaningful messages to your users or logs.
On 429, the Retry-After header tells you how many seconds to wait before retrying. Implement exponential backoff with jitter rather than immediate retry.
Network errors and timeouts should trigger automatic retries with backoff. Use a library-level retry mechanism or a wrapper function. Never retry on 400 or 401 because these indicate a problem with your code, not the server.
Code examples
import requests
BASE = "https://api.polyorderbooks.com/v1"
HEADERS = {"X-API-Key": "your-key"}
# 1. Discover markets
markets = requests.get(
f"{BASE}/markets",
headers=HEADERS,
params={"coin": "btc", "limit": 5},
).json()
# 2. For each market, pull books, prices, and metrics
slug = markets[0]["slug"]
books = requests.get(f"{BASE}/markets/{slug}/books", headers=HEADERS, params={"resolution": "1s"}).json()
prices = requests.get(f"{BASE}/markets/{slug}/prices", headers=HEADERS, params={"resolution": "1s"}).json()
metrics = requests.get(f"{BASE}/markets/{slug}/metrics", headers=HEADERS, params={"resolution": "1s"}).json()
print(f"{slug}: {len(books)} books, {len(prices)} prices, {len(metrics)} metrics")Free tier
The Starter plan is free, includes order books, prices, and metrics at 1-second 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 is the base URL?
https://api.polyorderbooks.com/v1. All endpoints are relative to this base. There is no versioning beyond v1; breaking changes will get a v2 path.
How do I authenticate?
Include an X-API-Key header on every request. Get your key from the dashboard after signing up. There is no OAuth or token refresh flow.
What format are the responses?
All responses are JSON. Error responses have a consistent {"error": "<message>"} structure. Success responses are arrays or objects depending on the endpoint.
What happens on a bad request?
The API returns HTTP 400 with a JSON error message explaining what went wrong. Common causes: missing required parameters, invalid slug, or out-of-range time values.