New: meet Clu, and send email, LinkedIn and call steps with Sequences. Watch the videos →
API Reference (v2)
Export
🔌

Audience: developers. API keys need a Pro or Enterprise plan (legacy Pro and Scale plans included) or an AppSumo Tier 5, 6 or 7 license, and they never work during a trial. Support agent: confirm the user's plan grants API access before giving API advice.

TL;DR: POST /export/csv/signed-url builds a CSV of a list and returns a download link valid for 24 hours. GET /export/json returns leads inline, up to 500 per call, with cursor paging. Both need export:read and are free.

Export

Two ways to get a lead list out of Cleanlist through API v2. To export from the app instead, see Exporting data.

EndpointMethodScopeCost
CSV (signed URL)POST /export/csv/signed-urlexport:readFree
JSONGET /export/jsonexport:readFree

Columns

Both endpoints use the same columns. Without columns, you get the default set, in this order:

ColumnContents
lead_idLead id
first_name, last_nameName
emailPrimary email (empty until enriched)
titleJob title
companyCompany name
domainCompany domain
linkedin_urlLinkedIn profile URL
phoneFirst phone number (empty until phone-enriched)
locationCity and country

Pass columns to pick a subset and set the order. Stick to these names; other names may come back empty.

CSV export

POST /export/csv/signed-url

Scope: export:read · Cost: free

Builds a CSV of the whole list, uploads it, and returns a signed link.

Request body

FieldTypeNotes
list_idstringRequired. A list you can read
columnsstring[]Optional ordered subset of the columns above
include_smart_agentsbooleanDefault true: adds one column per skill or smart-agent result saved on the list (headed by its display name) after your columns. false exports only the base columns
curl -X POST https://api.cleanlist.ai/api/v2/export/csv/signed-url \
  -H "Authorization: Bearer clapi_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"list_id": "LIST_ID", "columns": ["first_name", "last_name", "email", "company"]}'

Response

{
  "list_id": "LIST_ID",
  "download_url": "https://...",
  "expires_at": "2026-10-08T21:20:00+00:00",
  "row_count": 1284,
  "file_size_bytes": 402118
}
FieldMeaning
download_urlSigned link to the CSV file. Anyone with the link can download it until it expires, so treat it like a secret
expires_atWhen the link stops working, 24 hours after it was made
row_countData rows in the file (not counting the header)
file_size_bytesFile size

To stop spreadsheet apps from running formulas, any cell that starts with =, +, - or @ is written with a leading apostrophe (').

🧑‍💻

With an SDK: export.export_csv(...) and export.export_json(...) (exportCsv and exportJson in TS and Java). See the SDKs.

JSON export

GET /export/json

Scope: export:read · Cost: free

Returns a page of the list's leads inline, using the same columns.

Query paramDefaultNotes
list_idnoneRequired
limit1001 to 500 rows per call
cursornoneThe cursor from the previous response
columnsdefault setRepeat the parameter for each column, for example columns=email&columns=company
curl "https://api.cleanlist.ai/api/v2/export/json?list_id=LIST_ID&limit=500" \
  -H "Authorization: Bearer clapi_your_api_key"
{
  "list_id": "LIST_ID",
  "leads": [
    { "lead_id": "lead_5f9d2b", "first_name": "Ada", "last_name": "Lovelace", "email": "ada@analytical.io", "company": "Analytical", "domain": "analytical.io" }
  ],
  "total": 1284,
  "cursor": "500",
  "timestamp_ms": 1751404800000
}

Pass cursor back to get the next page; it's null on the last page. total is the number of leads in the whole list. A malformed cursor returns 400 invalid_cursor instead of starting over.

Errors

CodeHTTPCause
insufficient_scope403The credential lacks export:read
list_not_found404Unknown list, or a private list you can't access
invalid_cursor400The JSON cursor isn't one the API returned
internal_error502The export couldn't be built or uploaded; retry

Related