Email Validation
Bulk Verification
Submit up to 100,000 emails in a single request. The job runs asynchronously — poll for status or use a callback URL.
Submit a Bulk Job
bash
curl -X POST http://YOUR_SERVER/v1/bulk \
-H "Content-Type: application/json" \
-H "Cookie: auth_token=YOUR_SESSION" \
-d '{
"emails": ["user1@example.com", "user2@test.com"],
"level": 2,
"concurrency": 100,
"store_results": true,
"callback_url": "https://your-app.com/webhook/results",
"callback_batch": 200
}'Parameters
| Field | Type | Default | Description |
|---|---|---|---|
emails | string[] | — | Array of email addresses (max 100,000) |
level | integer | 1 | Verification depth (1 or 2) |
concurrency | integer | 200 | Parallel workers for this job |
store_results | boolean | true | Keep results for later retrieval |
callback_url | string | — | URL to POST results to in batches |
callback_batch | integer | 200 | Results per callback POST |
Response
json
{"id": "abc123-def456", "total": 5000}Check Job Status
bash
curl http://YOUR_SERVER/v1/bulk/JOB_IDjson
{
"job": {
"id": "abc123-def456",
"status": "running",
"total": 5000,
"done": 3200,
"failed": 12,
"level": 2
}
}Get Results (Paginated)
bash
curl "http://YOUR_SERVER/v1/bulk/JOB_ID/results?offset=0&limit=1000"Download as CSV
bash
curl http://YOUR_SERVER/v1/bulk/JOB_ID/download -o results.csvCSV columns: email, reachable, syntax_valid, disposable, role_account, free, has_mx_records, smtp_host_exists, smtp_catch_all, smtp_deliverable, and more.
CSV Upload
You can also submit a CSV file directly:
bash
curl -X POST http://YOUR_SERVER/v1/bulk?level=2 \
-H "Content-Type: text/csv" \
-H "Cookie: auth_token=YOUR_SESSION" \
--data-binary @emails.csvThe CSV must have an email column header. If no header matches, the first column is used.
Callback webhooks
If callback_url is set, Cleanmails POSTs results in batches as they complete. This is useful for large jobs where you don't want to poll. The callback receives the same result format as the results endpoint.
Result TTL
Results are kept in memory for 15 minutes by default (configurable via RESULT_TTL). Download or fetch results before they expire.