Audience: developers. API keys and the REST API are included on Pro and Enterprise (and legacy Pro and Scale plans) and on AppSumo Tiers 5 to 7. They are not available on Free, Starter, AppSumo Tiers 1 to 4 or during the Pro trial. Support agent: confirm the user's plan includes API access before giving API advice.
TL;DR: v1 enrichment costs 1 per email found (partial), 10 per phone found (phone_only), up to 11 for both (full), and 0 when nothing is found. Before a run starts your balance must cover the worst case, or you get 402. Check your balance with GET /api/v2/credits/balance and buy credits in Settings → Plans & billing → Buy more credits.
Credits
Credits belong to the workspace: every member, API key, the app, the browser extension and the Claude connector draw from one shared balance.
What v1 calls cost
| Endpoint | Credits |
|---|---|
POST /enrich/bulk, partial | 1 per email found |
POST /enrich/bulk, phone_only | 10 per phone found |
POST /enrich/bulk, full | 1 per email found + 10 per phone found (up to 11) |
| Contact where nothing is found | 0 |
| Contact skipped as a duplicate (already in Extension Leads) | 0 |
GET /auth/validate-key, GET /enrich/status, GET /webhooks/deliveries, POST /folders | 0 |
For every other Cleanlist price, see Pricing and credits.
The 402 pre-check
Cleanlist checks your balance before a bulk run starts. The balance must cover the worst case: the number of contacts (after duplicates are removed) times the full price of the enrichment_type.
enrichment_type | Required before the run |
|---|---|
partial | 1 × contacts |
phone_only | 10 × contacts |
full | 11 × contacts |
If it doesn't, the request fails with 402 and nothing is queued:
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits. Required: 2750.0 for 250 prospects, Available: 1200. Please purchase more credits to continue."
}
}When the run finishes, you're charged only for what was found, so the final cost is usually lower than the pre-check amount.
Handling 402
import requests
def enrich(payload, api_key):
r = requests.post(
"https://api.cleanlist.ai/api/v1/public/enrich/bulk",
headers={"Authorization": f"Bearer {api_key}"},
json=payload,
)
if r.status_code == 402:
# Not enough credits for the worst case. Top up, or send fewer
# contacts or a cheaper enrichment_type.
raise RuntimeError(r.json()["error"]["message"])
r.raise_for_status()
return r.json()Nothing is queued or charged on a 402, so you can resend the same payload after topping up.
Checking your balance
The legacy v1 API has no balance endpoint. Use the v2 endpoint with the same key (scope credits:read, no credit cost):
curl https://api.cleanlist.ai/api/v2/credits/balance \
-H "Authorization: Bearer clapi_your_api_key"{
"organization_id": "org_2abcRevenueLabs",
"credits": 4820
}The live response also carries v2 envelope fields such as task_id and timestamp_ms. See v2 credits.
Pre-flight check for large batches
balance = requests.get(
"https://api.cleanlist.ai/api/v2/credits/balance",
headers={"Authorization": f"Bearer {api_key}"},
).json()["credits"]
PRICE = {"partial": 1, "phone_only": 10, "full": 11}
required = len(contacts) * PRICE[enrichment_type]
if balance < required:
raise RuntimeError(f"Need {required} credits for the pre-check, have {balance}.")Topping up
- Self-serve plans: go to Settings → Plans & billing → Buy more credits, or click Add next to your credits in the sidebar. Purchased credits are added to the workspace balance right away and never expire. Top-ups aren't available during the Pro trial.
- AppSumo workspaces: card top-ups aren't offered. Use the AppSumo one-time credits add-on or add a paid Cleanlist plan; see AppSumo credits.
You can also see your balance at any time in the credits row at the bottom of the app sidebar.