TL;DR
Cleanlist's B2B data enrichment API cascades through 15+ data providers per lookup, returns verified emails and direct-dial phone numbers, and only charges you when data is found. Bulk enrichment handles up to 250 contacts per request. This guide covers endpoints, authentication, code examples, use cases, and how it compares to Apollo, ZoomInfo, Clay, and others.
Most B2B data enrichment APIs query a single database. If that database doesn't have your contact, you get nothing back and move on. Or worse, you get an unverified guess that bounces.
Cleanlist works differently. Every API call triggers a waterfall enrichment sequence that cascades through 15+ data providers until it finds verified contact information. The result: 85%+ email coverage instead of the 50-70% you get from single-source tools.
This guide walks through everything you need to integrate Cleanlist's B2B data enrichment API into your stack: authentication, endpoints, request formats, response structures, and real-world use cases.
How the Cleanlist Enrichment API Works
The API follows a simple async pattern. You submit contacts, Cleanlist processes them through its waterfall, and you poll for results or receive a webhook callback when enrichment completes.
Here's the flow:
1. POST /enrich/bulk → Submit up to 250 contacts
2. Receive workflow_id + task_ids
3. Cleanlist cascades through 15+ providers per contact
4. GET /enrich/status → Poll for results (or receive webhook)
5. Retrieve verified emails, phones, and company data
The waterfall is the key architectural difference. Instead of querying one database, Cleanlist tries providers in a cost-optimized sequence. If the first provider returns nothing, it moves to the next. If a provider returns an unverified email, it continues searching. The cascade stops only when verified data is found.
Each lookup cascades through providers in a cost-optimized sequence until verified data is found
Source: Cleanlist ArchitectureThis means you don't need to build your own waterfall across Hunter, RocketReach, Findymail, and others. Cleanlist handles the orchestration, deduplication, and verification in a single API call. For a broader overview of how enrichment fits into your GTM stack, see our complete guide to B2B data enrichment.
Authentication
All requests require a Bearer token using your organization's API key.
curl https://api.cleanlist.ai/api/v1/public/auth/validate-key \
-H "Authorization: Bearer clapi_your_api_key"Generate your API key from Settings → API Keys in the Cleanlist dashboard. Keys follow the clapi_ prefix format and are scoped to your organization.
Security Note
Store your API key in environment variables. Never commit it to source control or expose it in client-side code. Rotate keys periodically and revoke any that may have been compromised.
Rate limits: 60 requests per minute per organization with a fixed 60-second window. Exceeding this returns a 429 status with a Retry-After header.
Core Endpoints
Bulk Enrichment
The primary endpoint for enriching contacts programmatically.
POST /api/v1/public/enrich/bulk
{
"enrichment_type": "full",
"contacts": [
{
"linkedin_url": "https://linkedin.com/in/janedoe"
},
{
"first_name": "John",
"last_name": "Smith",
"company_name": "Acme Corp"
},
{
"first_name": "Sarah",
"last_name": "Chen",
"company_domain": "stripe.com"
}
],
"webhook_url": "https://yourapp.com/webhooks/enrichment"
}Each contact needs one of two input patterns:
- LinkedIn URL alone — the highest-accuracy input
- First name + last name + company name or domain — when you don't have LinkedIn
You can submit up to 250 contacts per request. The response returns immediately with tracking IDs:
{
"workflow_id": "wf_abc123",
"status": "processing",
"task_ids": ["task_001", "task_002", "task_003"],
"total_contacts": 3
}Enrichment Status
Poll for results or wait for your webhook callback.
GET /api/v1/public/enrich/status?workflow_id=wf_abc123
The status endpoint returns per-contact results as they complete. Each contact moves through its own waterfall independently, so you'll see results stream in as providers respond rather than waiting for the entire batch.
Credit Balance
Check your remaining credits before submitting a batch.
GET /api/v1/public/credits/balance
{
"credits_remaining": 4250,
"credits_used_this_month": 1750
}Enrichment Types and Credit Costs
Cleanlist uses a credit-based pricing model. The key differentiator: you only pay when data is found. Failed lookups don't consume credits.
| Enrichment Type | What You Get | Cost |
|---|---|---|
partial | Verified email address | 1 credit |
phone_only | Direct-dial phone number | 10 credits |
full | Email + phone | 11 credits |
none | Data normalization only | Free |
No Pay for No Results
If Cleanlist's waterfall exhausts all 15+ providers and can't find a verified email or phone, you aren't charged. This is a major difference from tools like Clay where failed lookups still consume credits — users report 20-30% credit waste on no-result queries.
What Data Comes Back
A successful enrichment returns contact, professional, and company data. Here's the full scope of what the API can return per contact:
Contact Information:
- Verified primary email + alternative business emails
- Personal email addresses
- Direct-dial phone numbers + personal phone numbers
- Email verification status (verified, risky, or invalid)
Professional Data:
- Current job title and headline
- Company name, domain, and LinkedIn URL
- Full work experience history (titles, companies, dates)
- Education history (degrees, institutions, dates)
- Skills, certifications, and languages
Company Intelligence:
- Industry and company type
- Employee count range
- Founded year and headquarters location
- Company description and tagline
Enriched Metadata:
- LinkedIn profile URL
- Inferred salary range
- Enrichment provider used
- Data quality indicators
This adds up to 65+ data points per contact when fully populated. Compare that to Hunter.io (email only, ~10 fields) or Lusha (~15-20 fields). For the full list of enrichment capabilities, see the API product page.
Real Integration Example
Here's a complete Python integration for enriching contacts from a CSV and pushing results to your CRM:
import requests
import time
import os
API_KEY = os.environ["CLEANLIST_API_KEY"]
BASE_URL = "https://api.cleanlist.ai/api/v1/public"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def enrich_contacts(contacts):
"""Submit contacts for enrichment and return workflow ID."""
response = requests.post(
f"{BASE_URL}/enrich/bulk",
headers=HEADERS,
json={
"enrichment_type": "full",
"contacts": contacts,
"webhook_url": "https://yourapp.com/webhooks/cleanlist"
}
)
response.raise_for_status()
return response.json()["workflow_id"]
def poll_results(workflow_id, max_wait=300):
"""Poll until enrichment completes or timeout."""
start = time.time()
while time.time() - start < max_wait:
response = requests.get(
f"{BASE_URL}/enrich/status",
headers=HEADERS,
params={"workflow_id": workflow_id}
)
data = response.json()
if data["status"] == "completed":
return data
time.sleep(5)
raise TimeoutError("Enrichment did not complete in time")
# Example: Enrich a batch of contacts
contacts = [
{"first_name": "Jane", "last_name": "Doe", "company_domain": "stripe.com"},
{"first_name": "Mike", "last_name": "Ross", "company_name": "Notion"},
{"linkedin_url": "https://linkedin.com/in/sarahchen"}
]
workflow_id = enrich_contacts(contacts)
results = poll_results(workflow_id)
for task in results["tasks"]:
if task["status"] == "completed":
print(f"{task['result']['email']} - {task['result']['email_status']}")For production workloads, use the webhook approach instead of polling. Cleanlist sends a POST to your webhook URL with the full results payload when enrichment completes.
Five Use Cases Where the API Fits
1. Real-Time Lead Enrichment on Form Submit
When a prospect fills out a form with just their name and company, trigger Cleanlist's API to enrich the record before it hits your CRM. Your SDRs get a complete profile — verified email, direct phone, LinkedIn, title, company size — within seconds of the form submission.
Why it works here: The async pattern lets you return a "thank you" page instantly while enrichment runs in the background. A webhook pushes the enriched record to your CRM when ready.
2. CRM Data Hygiene Automation
Schedule a weekly or monthly batch enrichment of your CRM contacts. Export contacts with missing fields, run them through the bulk endpoint, and write the results back. This keeps your database fresh as people change jobs (B2B data decays at 30% per year).
Why it works here: The none enrichment type normalizes data for free. Layer partial or full on top for contacts where you need updated emails or phones.
3. Outbound Prospecting Pipeline
Import a target account list from LinkedIn Sales Navigator. Use the API to find verified work emails and direct phone numbers for each prospect. Only contacts with verified email status enter your outbound sequence.
Why it works here: The waterfall approach finds emails that single-source tools miss. When one provider's database doesn't have a contact, Cleanlist's cascade through the remaining providers often does.
4. Marketing List Cleaning Before Campaign Launch
Before importing a purchased list into your email platform, run every contact through Cleanlist to verify emails and remove invalid addresses. This protects your sender reputation and keeps bounce rates under 2%.
Why it works here: The partial enrichment type costs just 1 credit and validates the email. Much cheaper than the damage a 15% bounce rate does to your domain.
5. Event and Webinar Follow-Up
After a conference or webinar, you often have names and companies but no direct contact info. Run your attendee list through the API to get verified emails and phones before your competitors follow up through generic event channels.
Why it works here: Speed matters post-event. Bulk enrichment of 250 contacts in a single call means your team can start outreach the same day.
How Cleanlist Compares to Other Enrichment APIs
Here's how the API stacks up against the tools most teams evaluate. For a deeper comparison, see our full enrichment API comparison.
| Feature | Cleanlist | Apollo | ZoomInfo | Clay | Clearbit/Breeze |
|---|---|---|---|---|---|
| Waterfall enrichment | 15+ providers | Yes (multi-provider) | No (single source) | 150+ (user-configured) | No (single source) |
| API access tier | All plans | All plans | Elite only (~$50K/yr) | All plans | Requires HubSpot |
| Charge on no result | No | Yes | Yes | Yes (20-30% waste) | Yes |
| Email cost | 1 credit | 1 credit | Negotiated | 5-15 credits | ~10 HubSpot credits |
| Phone cost | 10 credits | 8 credits | Negotiated | 15-50 credits | Not available |
| Rate limit | 60 req/min | 200 req/min (paid) | 1,500 req/min | 400 records/hr | Not published |
| Bulk batch size | 250 contacts | 10 contacts | Bulk available | Via workflow | Via HubSpot |
| Annual contract required | No | No | Yes | No | Yes (HubSpot) |
| Self-serve pricing | Yes | Yes | No (sales call) | Yes | Bundled |
Where Cleanlist Wins
No payment for failed lookups. Clay users routinely report 20-30% credit waste on contacts that return no results. Cleanlist's model means your spend maps directly to usable data.
No enterprise gating. ZoomInfo's API requires their Elite tier, which starts around $50K/year. Clearbit now requires a HubSpot subscription. Lusha restricts API access to their Scale plan. Cleanlist offers API access to all customers.
Managed waterfall. Clay gives you 150+ providers but requires you to configure the waterfall yourself — which providers, in what order, with what fallback logic. Cleanlist handles this automatically with a cost-optimized cascade.
Transparent pricing. No sales calls required. No opaque credit bundles. No seat-based licensing that inflates as your team grows.
Where Others Win
Apollo offers waterfall enrichment with higher rate limits (200 req/min on paid plans). If you need maximum throughput and are already in the Apollo ecosystem, their broader platform may consolidate your workflow.
ZoomInfo has the largest proprietary database in B2B. For enterprise teams with budget, their single-source coverage can rival waterfall approaches through sheer database size. Their 1,500 req/min rate limit is also unmatched.
Clay offers maximum flexibility. If you need custom waterfall logic — specific provider ordering, conditional enrichment paths, AI scoring between steps — Clay's workflow builder gives you full control.
Getting Started in 5 Minutes
- Create a Cleanlist account at app.cleanlist.ai
- Generate an API key in Settings → API Keys
- Validate your key:
curl https://api.cleanlist.ai/api/v1/public/auth/validate-key \
-H "Authorization: Bearer clapi_your_api_key"- Submit your first enrichment:
curl -X POST https://api.cleanlist.ai/api/v1/public/enrich/bulk \
-H "Authorization: Bearer clapi_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"enrichment_type": "partial",
"contacts": [
{
"first_name": "Jane",
"last_name": "Doe",
"company_domain": "stripe.com"
}
]
}'- Poll for results using the
workflow_idfrom the response
Full API reference: docs.cleanlist.ai/api-reference
Frequently Asked Questions
What inputs does the Cleanlist enrichment API accept?
The API accepts two input patterns per contact: a LinkedIn URL alone, or a combination of first name, last name, and either company name or company domain. You can mix input patterns within a single bulk request of up to 250 contacts. Optional fields like job title, location, and existing email address improve match accuracy when provided.
How does waterfall enrichment work in the Cleanlist API?
When you submit a contact, Cleanlist queries its first data provider. If that provider returns no result or an unverified match, the system automatically moves to the next provider in the cascade. This continues through 15+ providers until verified data is found or all sources are exhausted. The entire process happens in a single API call — you don't need to manage multiple provider integrations.
Does Cleanlist charge credits for contacts that return no data?
No. Cleanlist only deducts credits when it successfully finds the requested data. If the waterfall exhausts all providers without finding a verified email or phone number, zero credits are consumed. This is different from most competitors where failed lookups still cost credits.
What is the API rate limit?
The rate limit is 60 requests per minute per organization, measured in a fixed 60-second window. If you exceed this limit, the API returns a 429 status code with a Retry-After header indicating when you can resume. For high-volume batch processing, use the bulk endpoint (250 contacts per request) rather than making individual calls.
Can I use the Cleanlist API with my existing CRM?
Yes. Cleanlist integrates with HubSpot and Salesforce through native CRM connections. You can import contacts from your CRM, enrich them via the API, and sync results back automatically. For other CRMs, use the webhook callback to push enriched data into your system through your own integration layer.
References
- Data Quality Market Guide 2025 — Gartner (2025)
- State of CRM Data Report — HubSpot (2025)
- B2B Data Enrichment Benchmark — ZoomInfo (2025)