Skip to content
14 days of Pro, free.Sign up with your work email for 100 extra credits.Start free trial

Enrich CSV files via API

Upload a CSV of up to 100,000 rows and get back an enriched CSV with verified emails, phone numbers, titles, firmographics, and ICP scores appended as new columns. No code required. Processing 10K rows takes under 2 minutes.

An example call: POST to the csv_row endpoint with a work email, the waterfall tries providers in cost order, and the response returns 12 fields.

  • 1 creditA verified work email, however many providers it took to find it.
  • 11 creditsEmail and phone number together, on the same call.
  • 25+ providersQueried in cost order. The waterfall stops at the first deliverable result.
  • 98% / 85%Verified work emails and phone numbers found on our 500-lead benchmark.

10,000+ users, from founders to full sales teams

  • Switched fromZoomInfo
  • Case study
  • HackerOneSwitched fromApollo
  • Switched fromClay
  • Case study
  • Sumo LogicSwitched fromClay
  • Switched fromApollo
  • Case study
  • Switched fromZoomInfo
  • Switched fromZoomInfo

What one call returns. Up to 12 fields.

A sample response for one csv row lookup, beside every field the record can carry.

Response200 OK · csv_row
{
  "id": "ev_b8v2mn6",
  "status": "completed",
  "csv_row": {
    "row_id": 1,
    "input_email": "alex@startup.io",
    "input_name": "Alex Rivera",
    "enriched_email_status": "valid",
    "enriched_title": "CTO",
    "enriched_seniority": "c_level",
    "enriched_company": "Startup.io",
    "enriched_industry": "SaaS",
    "enriched_size": "11-50",
    "enriched_phone": "+1-650-555-0173",
    "enriched_linkedin": "https://linkedin.com/in/alexrivera",
    "icp_score": 72
  },
  "meta": {
    "credits_used": 11,
    "providers_queried": 25,
    "providers_matched": 5,
    "confidence": 0.88,
    "row_number": 1,
    "total_rows": 500
  }
}
Field reference12 fields
  • row_idintegerRow number from the original CSV (1-indexed). Preserves original row ordering.
  • input_emailstringThe email address from the original CSV used as the primary lookup key.
  • input_namestringName from the original CSV, used as a secondary identifier when email matching fails.
  • enriched_email_statusenumVerification result for the input email: valid, invalid, risky, catch-all, disposable, role-based, unknown.
  • enriched_titlestringCurrent job title, normalized to standard form.
  • enriched_seniorityenumSeniority level classification: entry through c_level.
  • enriched_companystringCurrent employer name.
  • enriched_industrystringIndustry classification.
  • enriched_sizestringCompany employee count range.
  • enriched_phonestringOffice or mobile phone number.
  • enriched_linkedinstringLinkedIn profile URL.
  • icp_scoreinteger0-100 ICP fit score, if ICP criteria are configured.

Call it from curl, Node or Python. Pay for what comes back.

It's one POST request. Credits come out of one wallet the whole team shares, and a call that finds nothing costs nothing.

RequestPOST · csv_row

curl

curl -X POST https://api.cleanlist.ai/v1/enrich/csv_row \
  -H "Authorization: Bearer $CLEANLIST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "jane@acme.com"}'

Node.js

const response = await fetch("https://api.cleanlist.ai/v1/enrich/csv_row", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CLEANLIST_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ email: "jane@acme.com" }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());

Python

import os
import requests

response = requests.post(
    "https://api.cleanlist.ai/v1/enrich/csv_row",
    headers={"Authorization": f"Bearer {os.environ['CLEANLIST_API_KEY']}"},
    json={"email": "jane@acme.com"},
)
response.raise_for_status()
print(response.json())
What a call costsper csv_row
  • SearchFree, unlimited
  • Verified work email1 credit
  • Phone number10 credits
  • Email and phone number11 credits
  • Validation0.5 credits
  • AI qualification5 credits
  • A call that finds nothing0

What teams do with it.

  1. Event lead enrichment

    Export badge scans from a conference as CSV. Upload to Cleanlist, get back enriched records with verified emails, titles, and company data within hours, ready to import into your CRM or sequencer.

  2. Purchased list cleaning

    Before importing a purchased lead list into your CRM, upload the CSV for enrichment. Invalid emails are flagged, missing fields are filled, and every record gets an ICP score so you only import qualified leads.

  3. Quarterly CRM export cleanup

    Export your CRM contacts as CSV, run through enrichment to catch job changes, verify stale emails, and fill field gaps. Re-import the enriched CSV to bring your database back to 90%+ completeness.

  4. Agency client onboarding

    When a new client hands you a prospect CSV, enrich it in bulk before building campaigns. Deliver a clean, scored, verified list on day one instead of spending a week on manual research.

The questions that come up first.

What CSV format does the endpoint accept?

The endpoint accepts standard CSV files with headers. At minimum, include an 'email' column. Additional columns like 'first_name', 'last_name', 'company', and 'linkedin_url' improve match rates. Cleanlist auto-detects column names and maps them to input fields. UTF-8 encoding is required.

What happens to rows where enrichment finds no match?

Unmatched rows are returned in the output CSV with empty enrichment columns and a status of 'not_found'. No credits are charged for unmatched rows. The original input data is always preserved so you never lose source information.

How large can a CSV upload be?

The API accepts CSV files up to 100,000 rows per upload. Files under 10,000 rows process synchronously and return results immediately. Larger files process asynchronously: you receive a job_id and poll it until processing completes. There is no file size limit beyond the row count.

Can I choose which fields to enrich?

Yes. Use the 'fields' parameter to specify which enrichment fields you want. Requesting email-only fields costs 1 credit per row. Adding phone fields costs 11 credits per row. You can also skip ICP scoring if you do not need it. This lets you control costs for different use cases.

Enrich CSV files in production.

The public API starts on Pro, and a call that returns nothing is never charged.

14 days of Pro, free.