POST/api/v1/bulk

Bulk Verification

Verify multiple email addresses in a single request. Ideal for cleaning email lists or batch processing.

How Bulk Verification Works

  1. 1. Submit a list of emails to the bulk endpoint
  2. 2. Receive a job ID for tracking progress
  3. 3. Poll the status endpoint or wait for webhook notification
  4. 4. Download results when processing is complete

Create Bulk Verification Job

Request

ParameterTypeRequiredDescription
emailsstring[]YesArray of email addresses (max 10,000 per request)
webhookUrlstringNoURL to receive completion notification
namestringNoOptional name for the verification job

Example Request

curl -X POST https://validmail.io/api/v1/bulk \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      "john@example.com",
      "jane@example.com",
      "bob@test.org"
    ],
    "webhookUrl": "https://yoursite.com/webhook",
    "name": "Marketing List Q4"
  }'

Response

{
  "jobId": "bulk_abc123xyz",
  "name": "Marketing List Q4",
  "status": "processing",
  "totalEmails": 3,
  "processedEmails": 0,
  "createdAt": "2024-01-15T10:30:00Z",
  "estimatedCompletion": "2024-01-15T10:35:00Z"
}

Check Job Status

GET/api/v1/bulk/{jobId}

Example Request

curl https://validmail.io/api/v1/bulk/bulk_abc123xyz \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "jobId": "bulk_abc123xyz",
  "name": "Marketing List Q4",
  "status": "completed",
  "totalEmails": 3,
  "processedEmails": 3,
  "createdAt": "2024-01-15T10:30:00Z",
  "completedAt": "2024-01-15T10:32:15Z",
  "summary": {
    "valid": 2,
    "invalid": 1,
    "risky": 0,
    "unknown": 0
  },
  "downloadUrl": "https://validmail.io/api/v1/bulk/bulk_abc123xyz/download"
}

Job Statuses

StatusDescription
pendingJob is queued and waiting to start
processingJob is actively verifying emails
completedAll emails have been verified, results available
failedJob failed due to an error

Download Results

GET/api/v1/bulk/{jobId}/download

Downloads the verification results as JSON. Only available when job status is "completed".

Response

{
  "jobId": "bulk_abc123xyz",
  "results": [
    {
      "email": "john@example.com",
      "status": "valid",
      "score": 95,
      "checks": {
        "syntax": { "valid": true },
        "dns": { "valid": true },
        "disposable": false
      }
    },
    {
      "email": "jane@example.com",
      "status": "valid",
      "score": 88,
      "checks": { ... }
    },
    {
      "email": "bob@test.org",
      "status": "invalid",
      "score": 0,
      "checks": { ... }
    }
  ],
  "summary": {
    "valid": 2,
    "invalid": 1,
    "risky": 0,
    "unknown": 0
  }
}

Webhook Notifications

If you provide a webhookUrl, we'll send a POST request when the job completes:

// POST to your webhookUrl
{
  "event": "bulk.completed",
  "jobId": "bulk_abc123xyz",
  "status": "completed",
  "summary": {
    "valid": 2,
    "invalid": 1,
    "risky": 0,
    "unknown": 0
  },
  "downloadUrl": "https://validmail.io/api/v1/bulk/bulk_abc123xyz/download",
  "timestamp": "2024-01-15T10:32:15Z"
}
Webhook Verification: We sign all webhook requests with a signature header. Verify this signature to ensure the request is from ValidMail.

Code Examples

JavaScript - Full Workflow
async function verifyBulkEmails(emails) {
  const API_KEY = process.env.VALIDMAIL_API_KEY;
  const BASE_URL = 'https://validmail.io/api/v1';

  // 1. Create the bulk job
  const createResponse = await fetch(`${BASE_URL}/bulk`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ emails }),
  });

  const { jobId } = await createResponse.json();
  console.log(`Job created: ${jobId}`);

  // 2. Poll for completion
  let status = 'processing';
  while (status === 'processing' || status === 'pending') {
    await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds

    const statusResponse = await fetch(`${BASE_URL}/bulk/${jobId}`, {
      headers: { 'Authorization': `Bearer ${API_KEY}` },
    });

    const job = await statusResponse.json();
    status = job.status;
    console.log(`Progress: ${job.processedEmails}/${job.totalEmails}`);
  }

  // 3. Download results
  const resultsResponse = await fetch(`${BASE_URL}/bulk/${jobId}/download`, {
    headers: { 'Authorization': `Bearer ${API_KEY}` },
  });

  return resultsResponse.json();
}

// Usage
const results = await verifyBulkEmails([
  'john@example.com',
  'jane@example.com',
  'bob@test.org',
]);

console.log(results.summary);
Python - With Webhook
import requests
import os

def create_bulk_job(emails, webhook_url=None):
    response = requests.post(
        'https://validmail.io/api/v1/bulk',
        headers={
            'Authorization': f'Bearer {os.environ["VALIDMAIL_API_KEY"]}',
            'Content-Type': 'application/json',
        },
        json={
            'emails': emails,
            'webhookUrl': webhook_url,
        }
    )

    response.raise_for_status()
    return response.json()

# Usage - results will be sent to your webhook
job = create_bulk_job(
    emails=['john@example.com', 'jane@example.com'],
    webhook_url='https://yoursite.com/validmail-webhook'
)

print(f"Job ID: {job['jobId']}")

Limits & Best Practices

Max emails per request:10,000
Processing speed:~1,000 emails per minute
Results retention:30 days

Tips

  • • Use webhooks instead of polling for large jobs
  • • Remove obvious duplicates before submitting
  • • Split very large lists into multiple jobs
  • • Download and store results before retention expires