#1. Get started
This page walks you from zero to your first downloaded data file in three steps.
Step 1 — Create an API key
Sign in, open Settings → API Keys, and generate a key. Keys look like do_XXXXXXXX_XXXXXXXX and are shown only once — copy and store it safely.
Every request carries the key in a header:
x-api-key: do_YOUR_KEY
Step 2 — Discover what's available
The catalog is browsed one level at a time with /info. Start at the top and drill down: md_type → exchange → ticker → timeframe → date → files.
curl -H "x-api-key: do_YOUR_KEY" "https://api.convexlake.com/info"
→ {"folders": ["orderbook/", "trades/", "candles/", "surface/", "bbo/"], ...}
curl -H "x-api-key: do_YOUR_KEY" "https://api.convexlake.com/info?md_type=orderbook&exchange=kalshi&ticker=btc&timeframe=15&date=2026-05-21"
→ {"objects": [{"key": "...", "slug": "KXBTC15M-26MAY211945", "size": 812430, ...}], ...}
Each object includes a ready-to-use slug — the filename without its format extension.
Step 3 — Download a file
Pass the same parameters plus the slug to the matching download endpoint:
curl -O -J -H "x-api-key: do_YOUR_KEY" "https://api.convexlake.com/orderbook?exchange=kalshi&ticker=btc&timeframe=15&date=2026-05-21&slug=KXBTC15M-26MAY211945"
The response is the raw file; curl -O -J saves it under its real name (format resolved automatically).
Python example:
import requests
KEY = "do_YOUR_KEY"
BASE = "https://api.convexlake.com"
H = {"x-api-key": KEY}
# Find files for a date
info = requests.get(f"{BASE}/info", headers=H, params={
"md_type": "candles", "exchange": "polymarket",
"ticker": "btc", "timeframe": "5", "date": "2026-06-10",
}).json()
for obj in info.get("objects", []):
r = requests.get(f"{BASE}/candles", headers=H, params={
"exchange": "polymarket", "ticker": "btc", "timeframe": "5",
"date": "2026-06-10", "slug": obj["slug"],
})
r.raise_for_status()
name = r.headers["Content-Disposition"].split("filename=")[-1].strip('"')
open(name, "wb").write(r.content)
print("saved", name)JavaScript example:
const KEY = "do_YOUR_KEY";
const BASE = "https://api.convexlake.com";
const info = await fetch(
`${BASE}/info?md_type=trades&exchange=polymarket&ticker=btc&timeframe=5&date=2026-06-10`,
{ headers: { "x-api-key": KEY } },
).then(r => r.json());
const slug = info.objects[0].slug;
const file = await fetch(
`${BASE}/trades?exchange=polymarket&ticker=btc&timeframe=5&date=2026-06-10&slug=${slug}`,
{ headers: { "x-api-key": KEY } },
);
const blob = await file.blob(); // save or parse as neededRate limits: Free 60 req/min · Research 300 req/min · Pro 1,000 req/min. Exceeding the limit returns HTTP 429 with a Retry-After header.
Using an AI assistant instead? The same data is available through our MCP server — see the MCP section on the API Keys page.
