Skip to main content
Exports turn a filtered slice of permit data into a downloadable CSV or XLSX file. They run asynchronously: you create a job, poll until it’s ready, then download a short-lived signed URL.
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/exportsapplication/json body:
curl
202 Accepted

Poll an export

GET /v1/exports/{export_id}status is one of pending, running, completed, failed.
completed
While 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.
Pass 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. A cohort, metros, or date_range your key/tier can’t export returns 403 (tier-restricted) or 400; an unknown export_id returns 404 (not-found).