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 9. They are not available on Free, Starter, AppSumo Tiers 1 to 4 or during the Pro trial. Want CluGTM inside Claude instead? The CluGTM MCP works from Starter up and on every AppSumo tier. Support agent: confirm the user’s plan includes API access before giving API advice.
TL;DR: The legacy v1 API at api.cleanlist.ai/api/v1/public has five endpoints: validate a key, start a bulk enrichment of up to 250 contacts, poll its status, read webhook delivery logs, and create a folder. Authenticate with a clapi_ Bearer key. It is the only CluGTM API with a per-run webhook_url (v2 has signed webhook subscriptions instead). For everything else, and for new integrations, use the v2 API.
Legacy API (v1)
This is the legacy v1 API. Existing keys and integrations keep working, but v1 is frozen: new endpoints are added only to the v2 API (/api/v2). Start new integrations on v2. See API versions and migration.
The v1 API enriches contacts in bulk and can POST the results to your server when the run finishes. Enriched contacts are also saved to the lead list you name with the required lead_list_id, so you can see them in the CluGTM app.
Base URL
https://api.cleanlist.ai/api/v1/publicUse HTTPS for every request.
Endpoints
The v1 API has exactly five endpoints:
| Method | Path | Purpose | Credits |
|---|---|---|---|
GET | /auth/validate-key | Check that an API key works and see the user and workspace it belongs to | Free |
POST | /enrich/bulk | Start an asynchronous enrichment of 1 to 250 contacts into the list named by lead_list_id, with an optional webhook_url | Per result found |
GET | /enrich/status | Poll a run by workflow_id, or one contact by task_id | Free |
GET | /webhooks/deliveries | List webhook delivery attempts for a run | Free |
POST | /folders | Create a lead-list folder | Free |
You may see other paths answer under /api/v1/public (for example /lead-lists or /credits/balance). Those are compatibility aliases of v2 endpoints, documented and supported in the v2 reference. Call them at /api/v2 and follow the v2 rules, including scopes.
Quick start
1. Create an API key
- Open app.clugtm.com and go to Settings → API keys.
- Under Create API key, optionally enter a Name (for example “CI integration”) and an Expiry.
- Click Create API key.
- Copy the key under New API key. It starts with
clapi_and is shown only once.
You can have up to 10 active keys per user in each workspace. See Authentication.
2. Check the key
cURL
curl https://api.cleanlist.ai/api/v1/public/auth/validate-key \
-H "Authorization: Bearer clapi_your_api_key"3. Enrich your first batch
cURL
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",
"lead_list_id": "your_lead_list_id",
"contacts": [
{
"first_name": "John",
"last_name": "Doe",
"company_domain": "acme.com"
},
{
"linkedin_url": "https://www.linkedin.com/in/janedoe"
}
]
}'The response contains a workflow_id. The enrichment runs in the background: poll GET /enrich/status or pass a webhook_url to get the results pushed to you. See Enrichment.
Key concepts
Asynchronous enrichment
POST /enrich/bulk returns right away with a workflow_id and one task_id per contact. The run goes through CluGTM’s waterfall of providers. You can:
- Poll
GET /enrich/status?workflow_id=...untilstatusiscompleted,completed_with_errorsorfailed, and - Receive a callback by passing
webhook_url. CluGTM sends one POST with every result when the run finishes. See Webhooks.
Credits
You pay only for data found. Before the run starts, your balance must cover the worst case (contacts times the per-contact price), or the request fails with 402.
enrichment_type | Credits |
|---|---|
partial (default) | 1 per email found |
phone_only | 10 per phone found |
full | 1 per email found plus 10 per phone found (up to 11) |
| Nothing found | 0 |
See Credits.
Where results go
Every contact enriched through v1 is saved to the list you pass as lead_list_id, which is required. It must be a list in your API key’s workspace that the key’s user can edit, its per-list contact limit applies, and it can’t be your Extension Leads list. A contact that is already in that list is skipped and not charged again. See Lead lists.
Rate limits
Each workspace can make 60 requests a minute across the public API (30 a minute for workspaces on an AppSumo deal without a paid plan). Over the limit you get 429 with a Retry-After header. See Errors.
Error format
Errors come back in one envelope with an UPPERCASE code:
{
"error": {
"code": "BAD_REQUEST",
"message": "Bulk enrichment supports up to 250 contacts per request."
}
}The exception is 422 (body validation), which uses the lowercase public envelope with code: "validation_error". See Errors.
| Status | Meaning |
|---|---|
200 / 201 | Success (POST /folders returns 201) |
400 | Bad request: no contacts, more than 250, every contact already in the list, or both or neither of workflow_id and task_id |
401 | Missing, invalid, expired or revoked API key |
402 | Not enough credits for the run |
403 | Plan doesn’t include API access, the run belongs to another workspace, or the lead_list_id list can’t take the contacts (you can’t edit it, it’s Extension Leads, or it would go past its per-list limit) |
404 | Task, run, folder or lead list not found |
422 | Body failed validation (for example a contact without enough identifiers) |
429 | Rate limit exceeded |
500 | Server error |
API sections
| Section | What it covers |
|---|---|
| Authentication | Creating, viewing and revoking API keys; the Bearer header |
| Enrichment | POST /enrich/bulk and GET /enrich/status |
| Enrichment types | partial, phone_only and full: what each returns and costs |
| Credits | Costs, the 402 pre-check, checking your balance, topping up |
| Webhooks | Callback payload, delivery and retries, GET /webhooks/deliveries |
| Lead lists | The list v1 saves to (lead_list_id) and POST /folders |
| Errors and rate limits | Error envelopes, status codes, retry strategy |
| OpenAPI spec | Swagger UI, Redoc and the JSON spec |