Download Snapshots
curl --request GET \
--url https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download \
--header 'X-API-Key: <x-api-key>'import requests
url = "https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download"
headers = {"X-API-Key": "<x-api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<x-api-key>'}};
fetch('https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<x-api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download")
.header("X-API-Key", "<x-api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<x-api-key>'
response = http.request(request)
puts response.read_body{
"market": {},
"format": "<string>",
"url": "<string>",
"expires_at": "<string>",
"expires_in": 123,
"size_bytes": 123,
"sha256": "<string>",
"row_count": 123
}Polymarket
Download Snapshots
Get a download link for a market’s full snapshot history as a Parquet file
GET
/
v1
/
markets
/
{slug}
/
snapshots
/
download
Download Snapshots
curl --request GET \
--url https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download \
--header 'X-API-Key: <x-api-key>'import requests
url = "https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download"
headers = {"X-API-Key": "<x-api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<x-api-key>'}};
fetch('https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<x-api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download")
.header("X-API-Key", "<x-api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<x-api-key>'
response = http.request(request)
puts response.read_body{
"market": {},
"format": "<string>",
"url": "<string>",
"expires_at": "<string>",
"expires_in": 123,
"size_bytes": 123,
"sha256": "<string>",
"row_count": 123
}Download Snapshots
Returns a short-lived download link to one market’s complete snapshot history as a single Parquet file. Every snapshot of the market is in the file, with full order books, so you don’t need to page through Get Snapshots.Requires a Pro, Suite, or Enterprise plan. The market must also be inside your plan’s data window.
Request
https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download
Headers
string
required
Your API key. See Authentication.
Path parameters
string
required
The market slug, e.g.
btc-updown-5m-1788140100Response
object
The market object (same as Get Market)
string
File format. Always
parquet.string
Download link for the file. It works without your API key and expires at
expires_at. The file downloads as {slug}.parquet.string
When the link stops working (ISO 8601)
integer
Seconds until the link expires (currently 600, i.e. 10 minutes)
integer
File size in bytes
string
SHA-256 checksum of the file (hex), for verifying the download
integer
Number of snapshots in the file
Examples
Get the link and download the file
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.polyhistorical.com/v1/markets/btc-updown-5m-1788140100/snapshots/download" \
| python3 -c "import sys, json; print(json.load(sys.stdin)['url'])" \
| xargs curl -s -o btc-updown-5m-1788140100.parquet
import hashlib
import requests
slug = "btc-updown-5m-1788140100"
info = requests.get(
f"https://api.polyhistorical.com/v1/markets/{slug}/snapshots/download",
headers={"X-API-Key": API_KEY},
).json()
# The link is pre-authorized: don't send your API key to it
data = requests.get(info["url"]).content
assert hashlib.sha256(data).hexdigest() == info["sha256"]
with open(f"{slug}.parquet", "wb") as f:
f.write(data)
Response
{
"market": {
"slug": "btc-updown-5m-1788140100",
"winner": "Up",
"market_type": "5m",
"start_time": "2026-08-31T01:35:00Z",
"end_time": "2026-08-31T01:40:00Z",
"coin_price_start": 77701.92547161,
"coin_price_end": 77844.44,
...
},
"format": "parquet",
"url": "https://hel1.your-objectstorage.com/polyhistorical/snapshots/v1/coin=btc/type=5m/date=2026-08-31/btc-updown-5m-1788140100.parquet?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=600&X-Amz-Signature=...",
"expires_at": "2026-11-01T10:10:00Z",
"expires_in": 600,
"size_bytes": 178278,
"sha256": "3b1f0c6e2a...",
"row_count": 2630
}
market is truncated here; it has all the fields from Get Market. Treat url as an opaque link: its host and format can change.Request the link right before you download. If it has expired, call this endpoint again for a fresh one. Downloading the file itself doesn’t count against your rate limit.
Errors
| Code | HTTP Status | When |
|---|---|---|
BAD_REQUEST | 400 | The slug isn’t a BTC, ETH, or SOL market |
UNAUTHORIZED | 401 | Missing or invalid API key |
TIER_ACCESS_DENIED | 403 | Your plan doesn’t include downloads |
EXTENDED_DATA_ACCESS_REQUIRED | 403 | The market is older than your Pro data window; a longer window gives access |
DATA_ACCESS_WINDOW_EXCEEDED | 403 | The market is outside your plan’s data window |
RESOURCE_NOT_FOUND | 404 | No market with this slug |
ARCHIVE_NOT_AVAILABLE | 404 | The market’s file isn’t ready yet (or the market has no snapshots). Use Get Snapshots meanwhile. |
ARCHIVE_UNAVAILABLE | 503 | Downloads are temporarily unavailable. Retry later. |