Export volume is tier-gated: the Free tier includes 5,000 exported rows /
month; Pro is unlimited. See Pricing.
The export flow
1
Create the job
POST /v1/exports returns an export_id and a poll_url.2
Poll until complete
GET /v1/exports/{export_id} until status is completed (or failed).3
Download
A completed job carries a
signed_url — fetch it before expires_at.Create an export
POST /v1/exports — application/json body:
curl
202 Accepted
Poll an export
GET /v1/exports/{export_id} — status is one of pending, running,
completed, failed.
completed
pending/running, signed_url and the size/count fields are null.
On failed, error_message explains why. Poll with a few seconds of backoff;
most exports complete in well under a minute.
List your exports
GET /v1/exports?limit=&before_id= — most recent first, keyset-paginated.
next_before_id back as before_id to page older.
Warehouse-native delivery
GET /v1/exports/warehouse/latest returns a manifest of the latest full-dataset
drop — Parquet + gzipped CSV files with signed R2 URLs, for loading straight
into Snowflake / BigQuery / a lake. This is the bulk alternative to per-query
exports.
preserves_tristate_dq_flags marks files that carry PermitCore’s
true/false/unknown data-quality flags intact (rather than collapsing unknown to
false) — so the honesty semantics survive the round-trip into your warehouse.
Errors
Exports use the standard RFC 9457 problem+json shape. Acohort,
metros, or date_range your key/tier can’t export returns 403
(tier-restricted) or 400; an unknown export_id returns 404 (not-found).