<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PolyOrderbooks</title>
    <description>The latest articles on DEV Community by PolyOrderbooks (@polyorderbooks).</description>
    <link>https://dev.to/polyorderbooks</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4062818%2F7e1ac792-4ac8-432d-a0d9-6ca0c708fb8c.png</url>
      <title>DEV Community: PolyOrderbooks</title>
      <link>https://dev.to/polyorderbooks</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/polyorderbooks"/>
    <language>en</language>
    <item>
      <title>Polymarket Price History: How to Download Historical Prices with Python</title>
      <dc:creator>PolyOrderbooks</dc:creator>
      <pubDate>Sun, 09 Aug 2026 16:41:38 +0000</pubDate>
      <link>https://dev.to/polyorderbooks/polymarket-price-history-how-to-download-historical-prices-with-python-27ll</link>
      <guid>https://dev.to/polyorderbooks/polymarket-price-history-how-to-download-historical-prices-with-python-27ll</guid>
      <description>&lt;p&gt;If you want &lt;strong&gt;Polymarket price history&lt;/strong&gt; in a notebook or CSV, you do not need a paid data vendor to get started. Polymarket documents a public &lt;code&gt;/prices-history&lt;/code&gt; endpoint on the CLOB API — no API key, no signup. This article shows how to download &lt;strong&gt;Polymarket historical prices&lt;/strong&gt; with Python using that official path first, then when a hosted archive is worth considering.&lt;/p&gt;

&lt;p&gt;That order matters. Many researchers only need implied-probability time series for charts or signal work. Others eventually need unified &lt;strong&gt;Polymarket price data&lt;/strong&gt; alongside metrics or historical L2 depth. We will cover both — without skipping the free option.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Polymarket price history actually is
&lt;/h2&gt;

&lt;p&gt;Each Polymarket outcome trades as a token on the CLOB. Historical prices are stored per &lt;em&gt;token ID&lt;/em&gt; (the asset id in Polymarket's docs), not per market slug. A binary market has two series — typically YES and NO — and each point is a timestamp &lt;code&gt;t&lt;/code&gt; plus an implied probability &lt;code&gt;p&lt;/code&gt; between 0 and 1.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;Polymarket price data&lt;/strong&gt; suited to time-series analysis: repricing before events, correlation across markets, coarse backtests. It is not the same as an archived order book — you get a price line, not bid/ask ladders with size at each level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: resolve token IDs with the Gamma API
&lt;/h2&gt;

&lt;p&gt;The CLOB &lt;code&gt;/prices-history&lt;/code&gt; endpoint requires a token ID. The Gamma API exposes market metadata, including &lt;code&gt;clobTokenIds&lt;/code&gt; — a JSON-encoded array of outcome token IDs for each market.&lt;/p&gt;

&lt;p&gt;Typical flow: search or list markets on Gamma, pick one, parse &lt;code&gt;clobTokenIds&lt;/code&gt;, then pass the YES (or NO) token id to &lt;code&gt;/prices-history&lt;/code&gt;. Polymarket's &lt;a href="https://docs.polymarket.com/market-data/prices-order-books" rel="noopener noreferrer"&gt;prices and order books docs&lt;/a&gt; walk through the same pattern in more detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: download history from Polymarket's CLOB API
&lt;/h2&gt;

&lt;p&gt;The documented endpoint is &lt;code&gt;GET https://clob.polymarket.com/prices-history&lt;/code&gt;. Important parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;market&lt;/strong&gt; (required) — outcome token ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;interval&lt;/strong&gt; — relative window such as &lt;code&gt;1h&lt;/code&gt;, &lt;code&gt;1d&lt;/code&gt;, &lt;code&gt;1w&lt;/code&gt;, or &lt;code&gt;max&lt;/code&gt;. Mutually exclusive with an absolute range.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;startTs&lt;/strong&gt; / &lt;strong&gt;endTs&lt;/strong&gt; — Unix timestamps for a fixed window (use these when you need a specific date range).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fidelity&lt;/strong&gt; — sampling interval in minutes (default 1). Higher fidelity means more points.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The response shape is &lt;code&gt;{"history": [{"t": ..., "p": ...}, ...]}&lt;/code&gt;. Public access — Polymarket applies IP-based rate limits and throttling, so pace bulk downloads and design for backoff rather than hammering the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python example: official Polymarket price history
&lt;/h2&gt;

&lt;p&gt;This script uses only Polymarket's public Gamma + CLOB APIs. Install &lt;code&gt;requests&lt;/code&gt; if you need it (&lt;code&gt;pip install requests&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;GAMMA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://gamma-api.polymarket.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;CLOB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://clob.polymarket.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Resolve a market and its outcome token IDs (Gamma — public, no API key)
&lt;/span&gt;&lt;span class="n"&gt;markets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;GAMMA&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/markets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;closed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;market&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;token_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;market&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;clobTokenIds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;yes_token_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token_ids&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;market&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YES token:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yes_token_id&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Pull Polymarket price history (CLOB /prices-history — public, no API key)
&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;CLOB&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/prices-history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;market&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;yes_token_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;interval&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# or use startTs + endTs for an absolute window
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fidelity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;# minutes between points
&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;implied prob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Export to CSV (polymarket price data download)
# with open("prices.csv", "w") as f:
#     f.write("timestamp,price\n")
#     for point in points:
#         f.write(f"{point['t']},{point['p']}\n")
&lt;/span&gt;
&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# pace yourself — IP-based rate limits apply
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Practical tips:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For long windows at fine &lt;code&gt;fidelity&lt;/code&gt;, chunk with &lt;code&gt;startTs&lt;/code&gt; / &lt;code&gt;endTs&lt;/code&gt; instead of relying on &lt;code&gt;interval=max&lt;/code&gt; alone — community reports suggest very fine granularity on resolved markets can return sparse data unless you bound the range explicitly.&lt;/li&gt;
&lt;li&gt;Loop one request per outcome token (YES and NO) if you need both sides.&lt;/li&gt;
&lt;li&gt;Add a short &lt;code&gt;sleep&lt;/code&gt; between markets when downloading many series — respect documented rate limits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When the official API is enough
&lt;/h2&gt;

&lt;p&gt;Stay on Polymarket's &lt;code&gt;/prices-history&lt;/code&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are exploring one market or a small set of markets.&lt;/li&gt;
&lt;li&gt;You need implied probability over time, not full book depth.&lt;/li&gt;
&lt;li&gt;You are fine resolving token IDs through Gamma yourself.&lt;/li&gt;
&lt;li&gt;Hourly or daily fidelity is sufficient for the question.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many charting and research tasks, that is the right stopping point — and it costs nothing beyond your time.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a historical archive helps
&lt;/h2&gt;

&lt;p&gt;A third-party archive (or your own recorder) becomes useful when &lt;strong&gt;Polymarket historical data&lt;/strong&gt; needs to look like a product API rather than a script that stitches Gamma + CLOB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unified queries&lt;/strong&gt; — discover markets by slug and pull &lt;code&gt;/prices&lt;/code&gt;, &lt;code&gt;/metrics&lt;/code&gt;, or &lt;code&gt;/books&lt;/code&gt; on the same &lt;code&gt;start_ts&lt;/code&gt; / &lt;code&gt;end_ts&lt;/code&gt; window without token-id plumbing each time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Both outcomes in one response&lt;/strong&gt; — archive APIs often key price series by outcome label (YES / NO) for a market slug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Historical L2 order books&lt;/strong&gt; — if price history stops being enough and you need bid/ask ladders, see &lt;a href="https://polyorderbooks.com/blog/historical-polymarket-order-book-data-backtesting" rel="noopener noreferrer"&gt;How to Get Historical Polymarket Order Book Data for Backtesting&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulk polymarket data download&lt;/strong&gt; — warehouse exports (Parquet, CSV) or scheduled pulls across hundreds of markets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the broader map of prices vs trades vs books vs API access, see &lt;a href="https://polyorderbooks.com/blog/polymarket-historical-data-download-prices-trades-order-books" rel="noopener noreferrer"&gt;Polymarket Historical Data: Prices, Trades, Order Books, and API Access&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional: same window through an archive API
&lt;/h2&gt;

&lt;p&gt;If you already use a hosted historical API, the shape is similar — market discovery, then a prices route — but keyed by slug and paginated. Example with PolyOrderbooks (requires a free API key from the dashboard):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.polyorderbooks.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-API-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POLYORDERBOOKS_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="n"&gt;markets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/markets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bitcoin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/markets/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/prices&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start_ts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+00:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_ts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+00:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;resolution&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;60s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;series&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;series&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;points&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is optional. Start with Polymarket's official endpoint; move here when unified history, metrics, or book depth justify it. Docs: &lt;a href="https://docs.polyorderbooks.com/quickstart" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt; and &lt;a href="https://docs.polyorderbooks.com/historical/overview" rel="noopener noreferrer"&gt;historical overview&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Polymarket price history&lt;/strong&gt; is available today through documented public APIs: resolve token IDs on Gamma, call &lt;code&gt;/prices-history&lt;/code&gt; on the CLOB, export the series. That covers a large share of &lt;strong&gt;polymarket historical prices&lt;/strong&gt; and &lt;strong&gt;polymarket price data&lt;/strong&gt; use cases with no vendor lock-in.&lt;/p&gt;

&lt;p&gt;Reach for an archive when you need one interface for prices, metrics, and stored L2 books — or when IP limits and multi-market orchestration become the bottleneck. Either way, you are downloading real market history, not guessing from live quotes alone.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://polyorderbooks.com/blog/polymarket-price-history-download-python" rel="noopener noreferrer"&gt;PolyOrderbooks&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>polymarket</category>
      <category>python</category>
      <category>api</category>
      <category>data</category>
    </item>
    <item>
      <title>Polymarket Historical Data: Prices, Trades, Order Books, and API Access</title>
      <dc:creator>PolyOrderbooks</dc:creator>
      <pubDate>Fri, 07 Aug 2026 09:58:41 +0000</pubDate>
      <link>https://dev.to/polyorderbooks/polymarket-historical-data-prices-trades-order-books-and-api-access-5fii</link>
      <guid>https://dev.to/polyorderbooks/polymarket-historical-data-prices-trades-order-books-and-api-access-5fii</guid>
      <description>&lt;p&gt;If you are researching Polymarket, the first practical question is usually where to find &lt;strong&gt;Polymarket historical data&lt;/strong&gt; — prices, trades, and order books — and how to download it for analysis. The answer depends on what you are building. Charting how a market repriced last month is a different problem than simulating whether a $2,000 order would have filled against the bid stack.&lt;/p&gt;

&lt;p&gt;This guide walks through what Polymarket exposes on its own, what you need an archive for, when price history is enough, when full book depth is required — and a short Python example to pull a time series.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Polymarket provides directly
&lt;/h2&gt;

&lt;p&gt;Polymarket splits public data across a few surfaces. None of them is a complete historical archive for every research use case, but each covers part of the picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Historical prices&lt;/strong&gt; — Polymarket exposes historical price-series endpoints, including batch price history. These are useful for probability and time-series analysis, but they are not equivalent to archived L2 order-book snapshots.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gamma API&lt;/strong&gt; — discovery and metadata: events, markets, tags, current outcomes, volume, and liquidity fields useful for browsing. Good for finding what exists and what is active today.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLOB API&lt;/strong&gt; — trading and live market structure: placing and canceling orders, recent trade activity, and the documented order-book endpoint, which returns the &lt;em&gt;current&lt;/em&gt; book for a token. Real-time book updates stream over the WebSocket; neither replaces a historical L2 archive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-chain settlement&lt;/strong&gt; — outcome resolution and token mechanics live on Polygon. That layer confirms final states; it is not a convenient historical prices API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are looking for a &lt;strong&gt;Polymarket order book API&lt;/strong&gt;, the official CLOB API gives you the current book, while a historical archive is needed for past L2 snapshots.&lt;/p&gt;

&lt;p&gt;In practice, teams that only call Polymarket directly can answer "what is the market quoting right now?" and "what traded recently?" Polymarket provides historical price-series endpoints, but researchers still need a separate archive if they want to replay full historical L2 bid/ask ladders at arbitrary past timestamps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is the Polymarket API free? Rate limits and what you actually get
&lt;/h2&gt;

&lt;p&gt;Developers often ask &lt;strong&gt;is Polymarket API free&lt;/strong&gt;. Polymarket provides public API access to market metadata, historical prices, and live market data. Usage is subject to documented rate limits, and this access is not the same as a historical L2 archive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Polymarket API rate limits&lt;/strong&gt; still apply. Polymarket applies IP-based rate limits and throttling across its APIs, so high-volume collectors need to respect the documented limits and design for backoff and pacing. Those constraints are aimed at live apps and market makers, not unattended bulk backfills across thousands of markets.&lt;/p&gt;

&lt;p&gt;The documented order-book endpoint returns the current book for a token; the WebSocket streams real-time updates. Neither offers a way to page through archived L2 depth from six months ago. For stored snapshots, you either run your own recorder or query a hosted historical API with &lt;code&gt;/books&lt;/code&gt; and &lt;code&gt;/prices&lt;/code&gt; routes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What requires an archive
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;archive&lt;/strong&gt; (your own pipeline or a hosted historical API) stores snapshots over time so you can query the past on demand. You typically need one when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want prices, metrics, and books from one queryable archive — consistent schemas and pagination — without stitching separate Polymarket endpoints or pacing around IP limits.&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;historical order book data&lt;/strong&gt; — multiple price levels with size, not just the last print or a single mid.&lt;/li&gt;
&lt;li&gt;You are backtesting across many markets and want consistent schemas, pagination, and API keys instead of ad-hoc CSV dumps.&lt;/li&gt;
&lt;li&gt;You want bulk export for a warehouse (some providers also offer Enterprise S3 drops in Parquet, CSV, or JSON).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recording everything yourself is possible: websocket feeds, token-id normalization, deduplication, and cold storage add up fast. Most research teams eventually buy time back by querying someone else's store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prices, trades, and order books — three different downloads
&lt;/h2&gt;

&lt;p&gt;These terms get used interchangeably in search, but they answer different questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prices&lt;/strong&gt; — time series of implied probability (per outcome token), usually derived from the top of book or last trade. Lightweight, ideal for charts, correlation studies, and coarse signal research.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trades&lt;/strong&gt; — discrete prints: size, price, side, timestamp. Answers "what actually exchanged hands?" Useful for volume profiles and trade-based backtests, but incomplete for limit-order strategies that might never have traded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order books (L2)&lt;/strong&gt; — bid and ask ladders: price and size at each level. Answers "what was available to hit or join?" Required when spread, depth, and queue position matter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A hosted archive API often exposes all three (or prices + books + derived metrics) over the same &lt;code&gt;start_ts&lt;/code&gt; / &lt;code&gt;end_ts&lt;/code&gt; window so you can align series in one notebook.&lt;/p&gt;

&lt;h2&gt;
  
  
  When prices and trades are enough
&lt;/h2&gt;

&lt;p&gt;Start with price history when your question is about direction or level, not execution quality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plotting how a market repriced before an election, macro print, or sports result.&lt;/li&gt;
&lt;li&gt;Comparing implied probabilities across related markets.&lt;/li&gt;
&lt;li&gt;Training models where fills are assumed at mid or at last trade (know the limitation).&lt;/li&gt;
&lt;li&gt;Screening hundreds of markets for volatility or drift without per-market book storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trade history extends that when you care about &lt;em&gt;observed&lt;/em&gt; activity — how much size cleared and at which prices — but you are still okay ignoring orders that rested on the book without filling.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you need order book depth
&lt;/h2&gt;

&lt;p&gt;Move to full L2 ladders — &lt;strong&gt;Polymarket order book data&lt;/strong&gt; with size at each level — when assumptions about liquidity stop being harmless:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estimating slippage for sizes larger than the top of book.&lt;/li&gt;
&lt;li&gt;Modeling limit orders that join the bid and may or may not fill.&lt;/li&gt;
&lt;li&gt;Measuring spread and depth over time, not just midpoint.&lt;/li&gt;
&lt;li&gt;Serious backtests where "fill at mid" would overstate edge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper walkthrough of that gap — why mids and prints are not enough — see &lt;a href="https://polyorderbooks.com/blog/historical-polymarket-order-book-data-backtesting" rel="noopener noreferrer"&gt;How to Get Historical Polymarket Order Book Data for Backtesting&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python example: pull historical prices
&lt;/h2&gt;

&lt;p&gt;The script below uses a read-only archive API (no live Polymarket calls on the read path). Set &lt;code&gt;POLYORDERBOOKS_API_KEY&lt;/code&gt; from your &lt;a href="https://polyorderbooks.com/signup" rel="noopener noreferrer"&gt;dashboard&lt;/a&gt; after signup.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Discover a market with &lt;code&gt;GET /v1/markets&lt;/code&gt; (search, status, category filters).&lt;/li&gt;
&lt;li&gt;Pull &lt;code&gt;GET /v1/markets/{slug}/prices&lt;/code&gt; with &lt;code&gt;start_ts&lt;/code&gt;, &lt;code&gt;end_ts&lt;/code&gt;, and &lt;code&gt;resolution&lt;/code&gt; (e.g. &lt;code&gt;60s&lt;/code&gt; on Starter).&lt;/li&gt;
&lt;li&gt;Parse &lt;code&gt;data&lt;/code&gt; keyed by outcome label; each point has &lt;code&gt;t&lt;/code&gt; (timestamp) and &lt;code&gt;p&lt;/code&gt; (price). Paginate with &lt;code&gt;metadata.next_cursor&lt;/code&gt; for longer windows.&lt;/li&gt;
&lt;li&gt;For book depth on the same window, call &lt;code&gt;/v1/markets/{slug}/books&lt;/code&gt; instead — same time parameters, ladders in &lt;code&gt;b&lt;/code&gt; / &lt;code&gt;a&lt;/code&gt; arrays.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.polyorderbooks.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POLYORDERBOOKS_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-API-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Pick a market
&lt;/span&gt;&lt;span class="n"&gt;markets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/markets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bitcoin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Pull a day of historical prices
&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/markets/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/prices&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start_ts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+00:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_ts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+00:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;resolution&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;60s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;buckets:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Need L2 depth? Same window, swap to /books
# books = requests.get(f"{BASE}/v1/markets/{slug}/books", params={...}, headers=HEADERS)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Export to CSV by writing &lt;code&gt;points&lt;/code&gt; rows in your loop, or use the official &lt;a href="https://pypi.org/project/polyorderbooks/" rel="noopener noreferrer"&gt;Python SDK on PyPI&lt;/a&gt; if you prefer a typed client. Parameter details and response shapes are in the &lt;a href="https://docs.polyorderbooks.com/quickstart" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt; and &lt;a href="https://docs.polyorderbooks.com/historical/overview" rel="noopener noreferrer"&gt;historical overview&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing your path
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Polymarket historical data&lt;/strong&gt; spans more than one source. Use Polymarket's own APIs — including documented historical price endpoints — for discovery, trading, and probability time series; use an archive when you need stored order book snapshots, unified exports, or full L2 replay at scale.&lt;/p&gt;

&lt;p&gt;A practical workflow: pull prices for the question you have today, validate the signal, then upgrade to &lt;code&gt;/books&lt;/code&gt; only if execution realism matters. A free Starter tier is enough to prototype on recent crypto markets — expand resolution or lookback when the research justifies it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I work on &lt;a href="https://polyorderbooks.com" rel="noopener noreferrer"&gt;PolyOrderbooks&lt;/a&gt;, a hosted historical Polymarket data API. This post reflects how we think about the problem space — not affiliated with Polymarket.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>polymarket</category>
      <category>python</category>
      <category>backtesting</category>
      <category>fintech</category>
    </item>
    <item>
      <title>How to Get Historical Polymarket Order Book Data for Backtesting</title>
      <dc:creator>PolyOrderbooks</dc:creator>
      <pubDate>Tue, 04 Aug 2026 16:27:23 +0000</pubDate>
      <link>https://dev.to/polyorderbooks/how-to-get-historical-polymarket-order-book-data-for-backtesting-olc</link>
      <guid>https://dev.to/polyorderbooks/how-to-get-historical-polymarket-order-book-data-for-backtesting-olc</guid>
      <description>&lt;p&gt;If you are building a strategy on Polymarket, you eventually need more than the current quote. Live APIs expose what the book looks like &lt;em&gt;right now&lt;/em&gt;. Backtests need what it looked like &lt;em&gt;then&lt;/em&gt; — repeatedly, at known timestamps, for every outcome in a market.&lt;/p&gt;

&lt;p&gt;That gap is harder than it sounds. Order books are ephemeral. Unless you capture and store snapshots yourself, the depth that was available before a news event or resolution is gone. This article explains why that matters, what historical L2 data unlocks, and how to pull a time series with Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Polymarket provides live order books and historical price data, but its public APIs do not offer a first-class archive for retrieving full historical L2 bid-and-ask ladders at arbitrary past timestamps. You can read current depth and place orders through the CLOB, but there is no documented "give me the full ladder from last Tuesday" endpoint on the public trading surface.&lt;/p&gt;

&lt;p&gt;Researchers and builders who want historical depth typically face three unattractive options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Record it yourself&lt;/strong&gt; — run collectors 24/7, normalize token ids, handle reconnects, and store terabytes of deltas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxy with trades or mid prices&lt;/strong&gt; — faster to wire up, but you lose information about size at each level and whether your size could have traded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a third-party archive&lt;/strong&gt; — someone else has already paid the storage and ingestion cost; you query snapshots over HTTP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The third path is what most teams want once they are serious about simulation. The hard part is finding a source that stores &lt;strong&gt;L2 ladders&lt;/strong&gt; (price and size per level), not just last trade or midpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why trade history isn't enough
&lt;/h2&gt;

&lt;p&gt;Trade prints answer "what traded?" They do not fully answer "what could I have traded, and at what cost?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spread.&lt;/strong&gt; The gap between best bid and best ask changes through the day. A backtest that fills at the mid price assumes you capture half the spread on every entry and exit — optimistic for any strategy that crosses the book.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Liquidity.&lt;/strong&gt; A level might show a tight quote with only $50 of size. Your model might assume a $5,000 fill at that price because the mid moved there once. Order-book snapshots show cumulative depth so you can cap fills by available size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slippage.&lt;/strong&gt; Walking the ask (or bid) to complete a larger order produces worse average prices than the top of book. You need the ladder — multiple price levels with sizes — to estimate impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Realistic fills.&lt;/strong&gt; Many strategies only work if you can model limit-order placement: join the bid, get hit when flow arrives, or never fill when the market moves away. That requires book state, not just a price chart.&lt;/p&gt;

&lt;p&gt;Mid prices and volume bars are fine for exploratory charts. They are a weak foundation for execution research on prediction markets, where spreads are wide relative to equities and liquidity is concentrated around a few levels.&lt;/p&gt;

&lt;h2&gt;
  
  
  What historical order-book data enables
&lt;/h2&gt;

&lt;p&gt;Once you have timestamped L2 snapshots per outcome token, several classes of analysis become straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backtesting&lt;/strong&gt; — replay decisions on the book state at decision time; apply fill rules that respect depth and spread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Liquidity analysis&lt;/strong&gt; — measure how much size sat within 1¢, 2¢, or 5¢ of the mid over hours or days; compare events or market types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market microstructure research&lt;/strong&gt; — study how books thin before resolution, how informed flow shows up on one side, or how crypto-linked markets behave around macro prints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution simulation&lt;/strong&gt; — test TWAP/VWAP-style logic, queue position heuristics, or "would this limit have filled?" without risking capital.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common thread is &lt;strong&gt;path dependency&lt;/strong&gt;: outcomes depend on the sequence of book states, not a single summary statistic per candle.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Python example using a historical archive API
&lt;/h2&gt;

&lt;p&gt;The workflow below uses a read-only HTTP API that serves stored snapshots (no live Polymarket calls on the read path). You will need an API key from the provider's signup flow; set &lt;code&gt;POLYORDERBOOKS_API_KEY&lt;/code&gt; in your environment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Discover a market slug with &lt;code&gt;GET /v1/markets&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Request books with &lt;code&gt;GET /v1/markets/{slug}/books&lt;/code&gt;, passing &lt;code&gt;start_ts&lt;/code&gt;, &lt;code&gt;end_ts&lt;/code&gt;, and &lt;code&gt;resolution&lt;/code&gt; (e.g. &lt;code&gt;60s&lt;/code&gt; on free tiers, &lt;code&gt;1s&lt;/code&gt; on paid plans).&lt;/li&gt;
&lt;li&gt;Parse each bucket's &lt;code&gt;b&lt;/code&gt; (bids) and &lt;code&gt;a&lt;/code&gt; (asks) as &lt;code&gt;[price, size]&lt;/code&gt; ladders keyed by outcome label. PolyOrderbooks returns both ladders best-price first (bids descending, asks ascending).
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.polyorderbooks.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POLYORDERBOOKS_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-API-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Find a market to study
&lt;/span&gt;&lt;span class="n"&gt;markets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/markets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bitcoin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;markets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Pull historical L2 books (60s buckets on Starter)
&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/markets/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/books&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start_ts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+00:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_ts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+00:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;resolution&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;60s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;bids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;asks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;best_bid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bids&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bids&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="n"&gt;best_ask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;asks&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;best_bid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ask&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;best_ask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paginate with &lt;code&gt;metadata.next_cursor&lt;/code&gt; if your window returns more than one page. For single-token depth on wide markets, use &lt;code&gt;/v1/tokens/{token_id}/books&lt;/code&gt;. Pair book pulls with &lt;code&gt;/prices&lt;/code&gt; or &lt;code&gt;/metrics&lt;/code&gt; on the same window if you need volume or spread time series alongside ladders.&lt;/p&gt;

&lt;p&gt;Full parameter reference and response shapes are in the &lt;a href="https://docs.polyorderbooks.com/quickstart" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt; and &lt;a href="https://docs.polyorderbooks.com/historical/overview" rel="noopener noreferrer"&gt;historical order book docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Historical Polymarket research needs archived order books, not just prices that traded. Spreads, depth, and ladder shape determine whether a strategy is tradable at all. Recording that data yourself is possible but operationally heavy; an archive API lets you spend time on simulation logic instead of ingestion.&lt;/p&gt;

&lt;p&gt;Start with a narrow question — liquidity around resolution, or fill quality for a fixed size — pull one market's &lt;code&gt;/books&lt;/code&gt; window, and validate your assumptions on real depth before scaling up. The &lt;a href="https://docs.polyorderbooks.com" rel="noopener noreferrer"&gt;PolyOrderbooks documentation&lt;/a&gt; covers authentication, resolutions, and pagination; a free tier is enough to prototype on recent crypto markets.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://polyorderbooks.com/blog/historical-polymarket-order-book-data-backtesting" rel="noopener noreferrer"&gt;polyorderbooks.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>polymarket</category>
      <category>python</category>
      <category>api</category>
      <category>backtesting</category>
    </item>
  </channel>
</rss>
