First file in under a minute.
Time-to-first-file is the metric. Get a key, list released days, stream one, verify its hash.
1 · Get a key
Keys are created in the portal and prefixed pmk_. The token is shown once at creation and stored only as a hash. Set it in your shell:
$ export PM_KEY=pmk_your_token
2 · The three curls
"$PM_API/v1/availability?source=binance_spot" | jq .days
$ curl -sH "Authorization: Bearer $PM_KEY" -o trades.parquet \
"$PM_API/v1/download?source=binance_spot&channel=crypto_trades&scope=BTC&day=2026-07-14"
$ curl -sH "Authorization: Bearer $PM_KEY" -o trades.manifest.json \
"$PM_API/v1/manifest?source=binance_spot&channel=crypto_trades&scope=BTC&day=2026-07-14"
$ shasum -a 256 trades.parquet # == .sha256 in the manifest
3 · Read the parquet
# or in python:
import duckdb; duckdb.sql("select * from 'trades.parquet' limit 5")
That is the whole loop. Every file you pull is a released day; unreleased days simply are not there to fetch.
Four endpoints, released days only.
Base URL https://api.promethean.markets. Bearer auth; keys are prefixed pmk_, shown once at creation, stored hashed at rest. Every key has a daily request budget (default 20,000); exceeding it returns 429 and never charges. Unauthorized requests never consume budget.
GET /v1/datasets
Machine-readable catalog: sources, channels, scopes, schema info.
GET /v1/availability
| Param | Required | Description |
|---|---|---|
| source | yes | Source id, e.g. binance_spot. |
{ "inception": "2026-07-13", "latest": "2026-07-14", "gapless": true, "days": 2 }
GET /v1/download & /v1/manifest
| Param | Required | Description |
|---|---|---|
| source | yes | Source id. |
| channel | yes | Channel, e.g. crypto_trades. |
| scope | yes | Coin or tier, e.g. BTC. |
| day | yes | UTC day YYYY-MM-DD. Must be released. |
/v1/download streams the day's Parquet; /v1/manifest returns the same file's manifest JSON.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | invalid_key | Missing or unknown bearer token. Does not consume budget. |
| 404 | not_found | Unknown day or object — e.g. a day that is not released. |
| 429 | daily_budget_exceeded | Key over its daily budget. Resets at 00:00 UTC. |
Columns, per channel.
Two representative channels below. Columns are marked identity (what the row is) or quality (freshness / lineage metadata).
binance_spot · crypto_trades
| Column | Type | Null | Description |
|---|---|---|---|
| ts_ms | int64 | no | Exchange event time, ms UTC. identity |
| receive_ms | int64 | no | Receive time; always ≥ ts_ms. quality |
| price | double | no | Trade price. |
| amount | double | no | Trade quantity. |
| trade_id | string | no | Stable row id; unique per scope/day. |
polymarket_updown · updown_book_snapshot_100ms
| Column | Type | Null | Description |
|---|---|---|---|
| bucket_ms | int64 | no | 100ms grid timestamp. identity |
| source_ts_ms | int64 | no | Timestamp of the source snapshot used. quality |
| source_lag_ms | int64 | no | bucket_ms − source_ts_ms; the true freshness. quality |
| freshness_state | string | no | Per-row freshness classification. quality |
| bid_prices | list<double> | no | Top-20 bid prices; sizes are in bid_sizes. |
One file, one manifest.
Layout
Day-partitioned Parquet, one file per source / channel / scope / day, each with a sibling manifest:
{source}/{channel}/{scope}/{day}.manifest.json
Manifest fields
| Field | Description |
|---|---|
| sha256 | Hash of the Parquet file. Re-hash yours; it must match. |
| row_count | Exact row count. Recompute to confirm. |
| schema_fingerprint | SHA256 schema fingerprint; released sample 4f8b025ecbc7c9cc7b246eda92ff863437722d4c06af919760ff2e0d8cd2d7fc. |
| min_event_ts_ms | Minimum event timestamp in the file. |
| max_event_ts_ms | Maximum event timestamp in the file. |
Re-verify
$ shasum -a 256 trades.parquet
$ jq -r .sha256 trades.manifest.json # must be identical
$ duckdb -c "select count(*) from 'trades.parquet'" # == row_count Limits Auth, budgets, fair use.
Auth model
Bearer tokens prefixed pmk_. Shown once at creation, stored only as a hash. Rotate by creating a new key and revoking the old one; revoked keys stay listed for audit.
Budgets
Each key carries a daily request budget (default 20,000). Authorized requests count; 401s do not. Over budget returns 429 daily_budget_exceeded; the counter resets at 00:00 UTC.
Requesting a raise
Email your key label and expected daily volume. Desk plans carry higher, custom budgets and per-key overrides.
Changelog Reverse-chronological.
2026-07-14 RELEASE Released 2026-07-14. The gapless run holds at 2 days from inception 2026-07-13. 2026-07-14 API Per-key daily request budgets are live — over-budget requests return 429 daily_budget_exceeded. 2026-07-13 RELEASE Inception: the first certified day across all six sources. 2026-07-13 CORRECTION Re-incepted at 2026-07-13 after 2026-07-12 carried Up/Down windows the venue never created. see the ledger → 2026-07-13 DOCS Documented the venue_unlisted disposition: a venue-side missing window is disclosed as a venue fact, backed by recorded evidence.