The bulk verification API lets you submit large lists of email addresses for verification. Lists of 50 or fewer emails are processed synchronously (you get results immediately). Lists of more than 50 emails are processed asynchronously (you poll for results or use webhooks).
POST /api/v1/verify/bulkHeaders:
Header | Required | Description |
|---|---|---|
Authorization | Yes |
|
Content-Type | Yes |
|
Idempotency-Key | No | UUID for retry safety |
Body:
{
"emails": [
"user1@example.com",
"user2@example.com",
"user3@example.com"
]
}Limits:
Maximum 10,000 emails per job
Maximum 1 concurrent job per account
Maximum request body size: 25 MB
200 OK:
{
"id": "job_abc123",
"status": "completed",
"totalCount": 3,
"processedCount": 3,
"results": [
{
"email": "user1@example.com",
"status": "deliverable",
"reason": "valid_mailbox"
},
{
"email": "user2@example.com",
"status": "undeliverable",
"reason": "mailbox_not_found"
},
{
"email": "user3@example.com",
"status": "risky",
"reason": "catch_all"
}
],
"creditsUsed": 3
}202 Accepted:
{
"id": "job_abc123",
"status": "pending",
"totalCount": 5000,
"processedCount": 0,
"progress": 0,
"createdAt": "2026-01-15T10:30:00Z",
"resultExpiresAt": "2026-01-29T10:30:00Z"
}GET /api/v1/verify/bulk/:jobIdResponse:
{
"id": "job_abc123",
"status": "processing",
"totalCount": 5000,
"processedCount": 2500,
"progress": 50,
"createdAt": "2026-01-15T10:30:00Z",
"resultExpiresAt": "2026-01-29T10:30:00Z"
}Job statuses:
Status | Meaning |
|---|---|
| Job is queued and waiting to start |
| Job is being processed |
| All emails have been verified |
| Job failed (check error field) |
GET /api/v1/verify/bulk/:jobId/resultsOnly available when the job status is completed.
Response:
{
"results": [
{
"email": "user1@example.com",
"status": "deliverable",
"reason": "valid_mailbox"
},
{
"email": "user2@example.com",
"status": "undeliverable",
"reason": "mailbox_not_found"
}
]
}For moderate-sized lists where you want immediate results:
POST /api/v1/verify/batchBody:
{
"emails": [
"user1@example.com",
"user2@example.com"
]
}Limits: Maximum 100 emails per request.
Response (200):
{
"results": [
{
"email": "user1@example.com",
"status": "deliverable",
"reason": "valid_mailbox"
}
],
"creditsUsed": 2,
"requestId": "req_xyz789"
}Submit the job via POST /api/v1/verify/bulk
Poll for status via GET /api/v1/verify/bulk/:jobId every 5-10 seconds
Download results via GET /api/v1/verify/bulk/:jobId/results when status is completed
Or, use webhooks to get notified when the job completes instead of polling.
Bulk job results are stored for 14 days after completion. After that, results are automatically deleted. Make sure to download results before they expire.
// Step 1: Submit bulk job
const submitResponse = await fetch('https://api.emailkit.dev/api/v1/verify/bulk', {
method: 'POST',
headers: {
'Authorization': 'Bearer ek_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
emails: ['user1@example.com', 'user2@example.com', /* ... */]
}),
});
const job = await submitResponse.json();
// Step 2: Poll for completion
let status = job.status;
while (status !== 'completed' && status !== 'failed') {
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
const statusResponse = await fetch(
`https://api.emailkit.dev/api/v1/verify/bulk/${job.id}`,
{ headers: { 'Authorization': 'Bearer ek_your_api_key' } }
);
const statusData = await statusResponse.json();
status = statusData.status;
console.log(`Progress: ${statusData.progress}%`);
}
// Step 3: Get results
const resultsResponse = await fetch(
`https://api.emailkit.dev/api/v1/verify/bulk/${job.id}/results`,
{ headers: { 'Authorization': 'Bearer ek_your_api_key' } }
);
const results = await resultsResponse.json();