Batch & File Verification
Verify large lists of emails asynchronously. Submit batches or upload CSV/TXT files. The per-batch cap is plan-dependent: 100 emails on Free, up to 10,000 on Enterprise.
Batch Verification
POST
/v1/verify/batchSubmit an array of emails for asynchronous verification. Returns a job ID to track progress.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
emails | string[] | Yes | Array of email addresses. Plan-dependent cap: 100 (Free), 1,000 (Starter), 5,000 (Professional/Business), 10,000 (Enterprise) |
options | object | No | Verification options (e.g. deep_verify, include_ai) |
webhook_url | string | No | HTTPS URL to receive the completion notification |
webhook_secret | string | No | HMAC key used to sign the completion webhook (X-Kawaa-Signature). Requires webhook_url; max 256 characters |
include_activity | boolean | No | Include activity data in per-email results when available |
Example Request
curl -X POST https://api.kawaa.com/v1/verify/batch \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": [
"user1@example.com",
"user2@example.com",
"user3@example.com"
],
"webhook_url": "https://your-app.com/webhook",
"webhook_secret": "your-signing-secret"
}'Response
{
"success": true,
"data": {
"job_id": "9f8f6d2e-4c1b-4f6e-9a3b-2d1e5c7a8b90",
"status": "processing",
"total_submitted": 3,
"duplicates_removed": 0,
"invalid_emails_skipped": 0,
"unique_emails": 3,
"estimated_time_seconds": 6,
"credits_used": 3,
"credits_remaining": 4997,
"message": "Batch verification started. Use GET /v1/jobs/{job_id} to check status."
}
}File Upload
POST
/v1/verify/fileUpload a CSV or TXT file containing email addresses for verification. File verification is a two-step JSON flow: request a presigned upload URL, PUT your file to it, then start processing with the returned file_key.
Step 1: Request an Upload URL
curl -X POST https://api.kawaa.com/v1/verify/file \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "get_upload_url",
"filename": "emails.csv"
}'
# Response
{
"success": true,
"data": {
"upload_url": "https://kawaa-uploads.s3.amazonaws.com/uploads/...",
"file_key": "uploads/user_abc123/2c9c1f8e-.../emails.csv",
"expires_in_seconds": 900,
"next_step": "Upload file to upload_url using PUT, then call this endpoint with action=process and file_key"
}
}Step 2: Upload the File
curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
--data-binary @emails.csvStep 3: Start Processing
curl -X POST https://api.kawaa.com/v1/verify/file \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "process",
"file_key": "uploads/user_abc123/2c9c1f8e-.../emails.csv",
"webhook_url": "https://your-app.com/webhook"
}'
# Response (202 Accepted)
{
"success": true,
"data": {
"job_id": "9f8f6d2e-4c1b-4f6e-9a3b-2d1e5c7a8b90",
"status": "processing",
"total_submitted": 1000,
"duplicates_removed": 12,
"invalid_emails_skipped": 3,
"unique_emails": 985,
"credits_used": 985,
"credits_remaining": 4015,
"message": "File verification started. 12 duplicate(s) removed. Use GET /v1/jobs/{job_id} to check status."
}
}Supported Formats & Limits
- CSV: Comma-separated with optional headers
- TXT: One email per line
- Max file size: 50MB (all plans)
- Max emails per file: your plan's batch cap — 100 (Free) up to 10,000 (Enterprise)
- Upload URL expiry: 15 minutes
Check Job Status
GET
/v1/jobs/{job_id}Response
{
"success": true,
"data": {
"job_id": "9f8f6d2e-4c1b-4f6e-9a3b-2d1e5c7a8b90",
"status": "completed",
"total_emails": 1000,
"processed_emails": 1000,
"progress_percent": 100,
"summary": {
"valid": 800,
"invalid": 100,
"risky": 50,
"unknown": 50
},
"created_at": "2026-02-03T14:30:00.000Z",
"updated_at": "2026-02-03T14:35:42.000Z",
"completed_at": "2026-02-03T14:35:42.000Z",
"credits_used": 1000,
"credits_refunded": 0,
"billing_status": "charged"
}
}Job Status Values
processing- Verification in progresscompleted- All emails verifiedfailed- Job failed (checkerror_message)enqueue_unknown- Some emails have unconfirmed queue status; credits are held and reconciled automatically
Download Results
GET
/v1/jobs/{job_id}/downloadQuery Parameters
format-csvorjson(default: csv)filter- Filter by status:all,valid,invalid,risky,unknown,spam_trap,disposable,role,catch_all(default: all)
Example
curl -X GET "https://api.kawaa.com/v1/jobs/9f8f6d2e-4c1b-4f6e-9a3b-2d1e5c7a8b90/download?format=csv&filter=valid" \
-H "X-Api-Key: YOUR_API_KEY" \
-o results.csvList All Jobs
GET
/v1/jobsList all verification jobs for your account with pagination.
Query Parameters
limit- Number of results (default: 50, max: 100)offset- Opaque pagination cursor. Pass thenext_offsetvalue from the previous page; the response also includeshas_morestatus- Filter by job status
Credits
- 1 credit per email in batch
- Credits deducted upfront when job is created
- Emails that cannot be queued are refunded automatically; cached results are billed at 0.5 credits (the discount is reconciled on completion)
- Credits held for emails the workers never process are refunded by job reconciliation