Exports
Deliver a list as a file.
Starts one file job for a filter and reserves the quota without charging it. The job counts the filter itself. POST /contacts/count is free and tells you the price before you pay it. One export runs per account: a second call while one runs returns 409 export.running with the running id. A job delivers at most 50,000 rows. Near a cap the job is truncated to the contact credits left under the cap that runs out first, and a warning gives the reason and the reset time. On the free plan the cap is the lifetime pool: the reason is monthly_cap, resets_at is 9999-12-31T23:59:59.000Z, and the hint says the pool does not reset. When the count passes its budget, the server checks for one matching row. A filter that matches nothing still answers 400 export.no_matches, because that check finds no row, and no job starts. A started job then has rows_available null and a count_unavailable warning.
The file
One export job. The file is UTF-8. A CSV file is RFC 4180: the header row equals the API column names, id comes first, a null is empty, a date is RFC 3339 UTC, and the name is {export_id}.csv.gz. CSV keeps arrays and objects as JSON text in one cell. A JSONL file uses the same names, one object a line. A JSONL line holds native JSON values, so an array or an object stays an array or an object.
| Property | Value |
|---|---|
| Formats | csvjsonl, gzipped |
| Rows per job | 50,000 |
| Signed link life | 24 hours |
The job
Statuses: queuedrunningcompletedfailed.
True when max_rows, the 50,000 row job limit or a contact credit cap made rows_to_export smaller than the rows the filter gives. A per-company cap alone does not set it. The export_truncated warning names the reason and the reset time. Reasons: daily_capmonthly_capjob_row_limitmax_rows.
Docs for agents: llms.txt