Black Friday: 50% OFF with code BF2025!Sign Up

Validation Jobs

Validation jobs allow you to validate large batches of email addresses asynchronously. Instead of waiting for immediate results, you can upload a file or provide a list of emails, and the validation will be processed in the background. This is ideal for validating thousands or millions of email addresses.

When to Use Validation Jobs

Use validation jobs when:

  • Validating more than 100 emails at once
  • Processing large CSV or Excel files
  • You don’t need immediate results
  • You want to download filtered results (e.g., only valid emails)

Use the direct validation endpoint when:

  • Validating 100 or fewer emails
  • You need immediate, synchronous results
  • Integrating real-time validation into forms or applications

Create Validation Job

Create a new validation job to process a batch of email addresses asynchronously.

Endpoint

POST https://api.campaignkit.cc/v1/email/validate/job

Authentication

Include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Request

This endpoint accepts multipart/form-data for file uploads.

Request Parameters

ParameterTypeRequiredDescription
labelstringNoA descriptive label for this job (e.g., “Q1 Marketing List”)
sourcestringYesSource type: file, input, or excel
filebinaryConditionalFile to upload (required if source is file or excel)
inputstringConditionalComma-separated or newline-separated emails (required if source is input)
integrationintegerNoIntegration ID if importing from a connected service

Example Request

Upload a CSV File

curl -X POST https://api.campaignkit.cc/v1/email/validate/job \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "label=Newsletter Subscribers" \
  -F "source=file" \
  -F "file=@emails.csv"

Provide Emails Directly

curl -X POST https://api.campaignkit.cc/v1/email/validate/job \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "label=Quick Validation" \
  -F "source=input" \
  -F "input=user1@example.com,user2@example.com,user3@example.com"

Supported file formats: CSV (.csv), Excel (.xlsx, .xls). Files should contain email addresses in the first column or have a column header named “email”.

Response

201 Created

The API returns the ID of the created job:

{
  "id": 123
}

The job will begin processing in the background. Use the returned job ID with the Get Job or Get Job Results endpoints to check the status and retrieve results.

Code Examples

JavaScript (Node.js)

const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');
 
async function createValidationJob(filePath, label) {
  const form = new FormData();
  form.append('label', label);
  form.append('source', 'file');
  form.append('file', fs.createReadStream(filePath));
 
  const response = await fetch('https://api.campaignkit.cc/v1/email/validate/job', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    },
    body: form
  });
 
  if (response.ok) {
    const data = await response.json();
    console.log(`Job created successfully with ID: ${data.id}`);
    return data.id;
  } else {
    console.error('Failed to create job:', response.statusText);
    return null;
  }
}
 
// Usage
createValidationJob('./emails.csv', 'Marketing List 2024')
  .then(jobId => {
    if (jobId) {
      console.log(`Monitor job at: /v1/email/validate/job/${jobId}`);
    }
  });

Python

import requests
 
def create_validation_job(file_path, label):
    url = 'https://api.campaignkit.cc/v1/email/validate/job'
    headers = {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
    files = {
        'file': open(file_path, 'rb')
    }
    data = {
        'label': label,
        'source': 'file'
    }
 
    response = requests.post(url, headers=headers, files=files, data=data)
 
    if response.status_code == 201:
        job_id = response.json()['id']
        print(f'Job created successfully with ID: {job_id}')
        return job_id
    else:
        print(f'Failed to create job: {response.status_code}')
        return None
 
# Usage
job_id = create_validation_job('emails.csv', 'Marketing List 2024')
if job_id:
    print(f'Monitor job at: /v1/email/validate/job/{job_id}')

PHP

<?php
 
function createValidationJob($filePath, $label) {
    $url = 'https://api.campaignkit.cc/v1/email/validate/job';
 
    $cfile = new CURLFile($filePath);
    $data = [
        'label' => $label,
        'source' => 'file',
        'file' => $cfile
    ];
 
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer YOUR_API_KEY'
    ]);
 
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
 
    if ($httpCode == 201) {
        $data = json_decode($response, true);
        $jobId = $data['id'];
        echo "Job created successfully with ID: $jobId\n";
        return $jobId;
    } else {
        echo "Failed to create job: $httpCode\n";
        return null;
    }
}
 
// Usage
$jobId = createValidationJob('emails.csv', 'Marketing List 2024');
if ($jobId) {
    echo "Monitor job at: /v1/email/validate/job/$jobId\n";
}
?>

List Validation Jobs

Get a list of all your validation jobs, including their current status and summary statistics.

Endpoint

GET https://api.campaignkit.cc/v1/email/validate/job

Authentication

Include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Example Request

curl -X GET https://api.campaignkit.cc/v1/email/validate/job \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

[
  {
    "id": 123,
    "label": "Newsletter Subscribers",
    "state": "done",
    "emailCount": 5000,
    "source": "file",
    "integration": null,
    "summary": {
      "totalEmails": 5000,
      "deliverableCount": 4250,
      "undeliverableCount": 500,
      "riskyCount": 250
    },
    "createdAt": "2024-01-15T10:30:00Z",
    "finishedAt": "2024-01-15T11:45:00Z"
  },
  {
    "id": 124,
    "label": "Q1 Marketing List",
    "state": "running",
    "emailCount": 10000,
    "source": "excel",
    "integration": null,
    "summary": {
      "totalEmails": 10000,
      "deliverableCount": 3200,
      "undeliverableCount": 150,
      "riskyCount": 80
    },
    "createdAt": "2024-01-15T14:20:00Z",
    "finishedAt": null
  }
]

Response Fields

Each job object contains:

FieldTypeDescription
idintegerUnique job identifier
labelstringJob label/description
statestringCurrent state: pending, running, paused, failed, or done
emailCountintegerTotal number of emails in this job
sourcestringSource type: file, input, hubspot, mailjet, mailchimp, excel, or api
integrationobjectIntegration details if job was created from a connected service
summaryobjectValidation summary statistics (see below)
createdAtstringISO 8601 timestamp when job was created
finishedAtstringISO 8601 timestamp when job completed (null if still running)

Summary Object

FieldTypeDescription
totalEmailsintegerTotal emails processed so far
deliverableCountintegerCount of valid/deliverable emails
undeliverableCountintegerCount of invalid/undeliverable emails
riskyCountintegerCount of risky emails (role-based, catch-all, etc.)

Job States

StateDescription
pendingJob is queued and waiting to start
runningJob is currently being processed
pausedJob has been paused by the user
failedJob encountered an error and could not complete
doneJob completed successfully

Jobs in the running state will have their summary object updated in real-time as emails are processed. Poll this endpoint to track progress.

Code Examples

JavaScript (Node.js)

const fetch = require('node-fetch');
 
async function listJobs() {
  const response = await fetch('https://api.campaignkit.cc/v1/email/validate/job', {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  });
 
  const jobs = await response.json();
 
  jobs.forEach(job => {
    console.log(`Job ${job.id}: ${job.label}`);
    console.log(`  State: ${job.state}`);
    console.log(`  Progress: ${job.summary.totalEmails}/${job.emailCount} emails`);
 
    if (job.state === 'done') {
      console.log(`  Deliverable: ${job.summary.deliverableCount}`);
      console.log(`  Risky: ${job.summary.riskyCount}`);
      console.log(`  Undeliverable: ${job.summary.undeliverableCount}`);
    }
    console.log('');
  });
}
 
listJobs();

Python

import requests
 
def list_jobs():
    url = 'https://api.campaignkit.cc/v1/email/validate/job'
    headers = {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
 
    response = requests.get(url, headers=headers)
    jobs = response.json()
 
    for job in jobs:
        print(f"Job {job['id']}: {job['label']}")
        print(f"  State: {job['state']}")
        print(f"  Progress: {job['summary']['totalEmails']}/{job['emailCount']} emails")
 
        if job['state'] == 'done':
            print(f"  Deliverable: {job['summary']['deliverableCount']}")
            print(f"  Risky: {job['summary']['riskyCount']}")
            print(f"  Undeliverable: {job['summary']['undeliverableCount']}")
        print()
 
list_jobs()

PHP

<?php
 
function listJobs() {
    $url = 'https://api.campaignkit.cc/v1/email/validate/job';
 
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer YOUR_API_KEY'
    ]);
 
    $response = curl_exec($ch);
    curl_close($ch);
 
    $jobs = json_decode($response, true);
 
    foreach ($jobs as $job) {
        echo "Job {$job['id']}: {$job['label']}\n";
        echo "  State: {$job['state']}\n";
        echo "  Progress: {$job['summary']['totalEmails']}/{$job['emailCount']} emails\n";
 
        if ($job['state'] == 'done') {
            echo "  Deliverable: {$job['summary']['deliverableCount']}\n";
            echo "  Risky: {$job['summary']['riskyCount']}\n";
            echo "  Undeliverable: {$job['summary']['undeliverableCount']}\n";
        }
        echo "\n";
    }
}
 
listJobs();
?>

Get Single Job

Retrieve details for a specific validation job by its ID.

Endpoint

GET https://api.campaignkit.cc/v1/email/validate/job/{id}

Authentication

Include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Parameters

ParameterTypeRequiredDescription
idintegerYesJob ID (in URL path)

Example Request

curl -X GET https://api.campaignkit.cc/v1/email/validate/job/123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "id": 123,
  "label": "Newsletter Subscribers",
  "state": "done",
  "emailCount": 5000,
  "source": "file",
  "integration": null,
  "summary": {
    "totalEmails": 5000,
    "deliverableCount": 4250,
    "undeliverableCount": 500,
    "riskyCount": 250
  },
  "createdAt": "2024-01-15T10:30:00Z",
  "finishedAt": "2024-01-15T11:45:00Z"
}

Response Fields

See the List Validation Jobs section for detailed field descriptions.

Code Examples

JavaScript (Node.js)

const fetch = require('node-fetch');
 
async function getJob(jobId) {
  const response = await fetch(`https://api.campaignkit.cc/v1/email/validate/job/${jobId}`, {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  });
 
  if (!response.ok) {
    if (response.status === 404) {
      console.error('Job not found');
      return null;
    }
    throw new Error(`HTTP error ${response.status}`);
  }
 
  const job = await response.json();
 
  console.log(`Job ${job.id}: ${job.label}`);
  console.log(`State: ${job.state}`);
 
  if (job.state === 'done') {
    console.log(`Results: ${job.summary.deliverableCount} valid, ${job.summary.riskyCount} risky, ${job.summary.undeliverableCount} invalid`);
  } else if (job.state === 'running') {
    console.log(`Progress: ${job.summary.totalEmails}/${job.emailCount} emails processed`);
  }
 
  return job;
}
 
// Usage
getJob(123);

Python

import requests
 
def get_job(job_id):
    url = f'https://api.campaignkit.cc/v1/email/validate/job/{job_id}'
    headers = {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
 
    response = requests.get(url, headers=headers)
 
    if response.status_code == 404:
        print('Job not found')
        return None
 
    response.raise_for_status()
    job = response.json()
 
    print(f"Job {job['id']}: {job['label']}")
    print(f"State: {job['state']}")
 
    if job['state'] == 'done':
        summary = job['summary']
        print(f"Results: {summary['deliverableCount']} valid, {summary['riskyCount']} risky, {summary['undeliverableCount']} invalid")
    elif job['state'] == 'running':
        print(f"Progress: {job['summary']['totalEmails']}/{job['emailCount']} emails processed")
 
    return job
 
# Usage
get_job(123)

PHP

<?php
 
function getJob($jobId) {
    $url = "https://api.campaignkit.cc/v1/email/validate/job/$jobId";
 
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer YOUR_API_KEY'
    ]);
 
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
 
    if ($httpCode == 404) {
        echo "Job not found\n";
        return null;
    }
 
    if ($httpCode != 200) {
        echo "HTTP error: $httpCode\n";
        return null;
    }
 
    $job = json_decode($response, true);
 
    echo "Job {$job['id']}: {$job['label']}\n";
    echo "State: {$job['state']}\n";
 
    if ($job['state'] == 'done') {
        $summary = $job['summary'];
        echo "Results: {$summary['deliverableCount']} valid, {$summary['riskyCount']} risky, {$summary['undeliverableCount']} invalid\n";
    } elseif ($job['state'] == 'running') {
        echo "Progress: {$job['summary']['totalEmails']}/{$job['emailCount']} emails processed\n";
    }
 
    return $job;
}
 
// Usage
getJob(123);
?>

Get Job Results

Retrieve validation results for a specific job. Results are returned in pages for easy consumption.

Endpoint

GET https://api.campaignkit.cc/v1/email/validate/job/{id}/result

Authentication

Include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Parameters

ParameterTypeRequiredDescription
idintegerYesJob ID (in URL path)
posintegerNoStarting position for pagination (default: 0)

Example Request

# Get first page of results
curl -X GET https://api.campaignkit.cc/v1/email/validate/job/123/result \
  -H "Authorization: Bearer YOUR_API_KEY"
 
# Get results starting from position 1000
curl -X GET https://api.campaignkit.cc/v1/email/validate/job/123/result?pos=1000 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

[
  {
    "email": "valid@example.com",
    "result": {
      "syntax": "pass",
      "mx": "pass",
      "mailbox": "pass",
      "score": 10,
      "classifier": "valid",
      "description": [],
      "smtpResponse": "250 OK"
    }
  },
  {
    "email": "invalid@fake-domain.xyz",
    "result": {
      "syntax": "pass",
      "mx": "fail",
      "mailbox": "n/a",
      "score": 0,
      "classifier": "invalid",
      "description": ["invalid_mx"],
      "smtpResponse": ""
    }
  },
  {
    "email": "admin@company.com",
    "result": {
      "syntax": "pass",
      "mx": "pass",
      "mailbox": "n/a",
      "score": 5,
      "classifier": "risky",
      "description": ["role_email"],
      "smtpResponse": ""
    }
  }
]

Results are returned in batches of up to 1000 emails per request. Use the pos parameter to paginate through large result sets.

Response Fields

Each result object contains:

FieldTypeDescription
emailstringThe email address that was validated
resultobjectValidation result details

For detailed information about the validation result object, see the Email Validation documentation.

Code Examples

JavaScript (Node.js)

const fetch = require('node-fetch');
 
async function getJobResults(jobId, position = 0) {
  const url = `https://api.campaignkit.cc/v1/email/validate/job/${jobId}/result?pos=${position}`;
 
  const response = await fetch(url, {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  });
 
  const results = await response.json();
 
  // Filter results by classifier
  const valid = results.filter(r => r.result.classifier === 'valid');
  const risky = results.filter(r => r.result.classifier === 'risky');
  const invalid = results.filter(r => r.result.classifier === 'invalid');
 
  console.log(`Valid: ${valid.length}, Risky: ${risky.length}, Invalid: ${invalid.length}`);
 
  return results;
}
 
// Get all results by paginating
async function getAllJobResults(jobId) {
  let position = 0;
  let allResults = [];
 
  while (true) {
    const results = await getJobResults(jobId, position);
 
    if (results.length === 0) break;
 
    allResults.push(...results);
    position += results.length;
 
    console.log(`Fetched ${allResults.length} results so far...`);
  }
 
  return allResults;
}
 
// Usage
getAllJobResults(123).then(results => {
  console.log(`Total results: ${results.length}`);
});

Python

import requests
 
def get_job_results(job_id, position=0):
    url = f'https://api.campaignkit.cc/v1/email/validate/job/{job_id}/result'
    params = {'pos': position}
    headers = {
        'Authorization': 'Bearer YOUR_API_KEY'
    }
 
    response = requests.get(url, headers=headers, params=params)
    results = response.json()
 
    # Filter results by classifier
    valid = [r for r in results if r['result']['classifier'] == 'valid']
    risky = [r for r in results if r['result']['classifier'] == 'risky']
    invalid = [r for r in results if r['result']['classifier'] == 'invalid']
 
    print(f"Valid: {len(valid)}, Risky: {len(risky)}, Invalid: {len(invalid)}")
 
    return results
 
def get_all_job_results(job_id):
    position = 0
    all_results = []
 
    while True:
        results = get_job_results(job_id, position)
 
        if not results:
            break
 
        all_results.extend(results)
        position += len(results)
 
        print(f"Fetched {len(all_results)} results so far...")
 
    return all_results
 
# Usage
results = get_all_job_results(123)
print(f"Total results: {len(results)}")

PHP

<?php
 
function getJobResults($jobId, $position = 0) {
    $url = "https://api.campaignkit.cc/v1/email/validate/job/$jobId/result?pos=$position";
 
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer YOUR_API_KEY'
    ]);
 
    $response = curl_exec($ch);
    curl_close($ch);
 
    $results = json_decode($response, true);
 
    // Filter results by classifier
    $valid = array_filter($results, fn($r) => $r['result']['classifier'] === 'valid');
    $risky = array_filter($results, fn($r) => $r['result']['classifier'] === 'risky');
    $invalid = array_filter($results, fn($r) => $r['result']['classifier'] === 'invalid');
 
    echo "Valid: " . count($valid) . ", Risky: " . count($risky) . ", Invalid: " . count($invalid) . "\n";
 
    return $results;
}
 
function getAllJobResults($jobId) {
    $position = 0;
    $allResults = [];
 
    while (true) {
        $results = getJobResults($jobId, $position);
 
        if (empty($results)) break;
 
        $allResults = array_merge($allResults, $results);
        $position += count($results);
 
        echo "Fetched " . count($allResults) . " results so far...\n";
    }
 
    return $allResults;
}
 
// Usage
$results = getAllJobResults(123);
echo "Total results: " . count($results) . "\n";
?>

Download Job Results

Download validation results as a CSV file, optionally filtered by validation status.

Endpoint

GET https://api.campaignkit.cc/v1/email/validate/job/{id}/download

Authentication

Include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Parameters

ParameterTypeRequiredDescription
idintegerYesJob ID (in URL path)
filtersarrayNoFilter results by classifier: valid, risky, invalid

Example Request

# Download all results
curl -X GET https://api.campaignkit.cc/v1/email/validate/job/123/download \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o results.csv
 
# Download only valid emails
curl -X GET "https://api.campaignkit.cc/v1/email/validate/job/123/download?filters=valid" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o valid-emails.csv
 
# Download valid and risky emails
curl -X GET "https://api.campaignkit.cc/v1/email/validate/job/123/download?filters=valid&filters=risky" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o deliverable-emails.csv

Response

The response is a CSV file with the following columns:

email,syntax,mx,mailbox,score,classifier,description,smtpResponse
valid@example.com,pass,pass,pass,10,valid,,250 OK
invalid@fake-domain.xyz,pass,fail,n/a,0,invalid,invalid_mx,
admin@company.com,pass,pass,n/a,5,risky,role_email,
⚠️

The download endpoint streams the entire result set. For very large jobs (millions of emails), consider using the paginated Get Job Results endpoint instead.

Delete Validation Job

Delete a validation job and all its associated results.

Endpoint

DELETE https://api.campaignkit.cc/v1/email/validate/job/{id}

Authentication

Include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Parameters

ParameterTypeRequiredDescription
idintegerYesJob ID to delete (in URL path)

Example Request

curl -X DELETE https://api.campaignkit.cc/v1/email/validate/job/123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

200 OK

The job and all its results have been deleted.

⚠️

Deleting a job is permanent and cannot be undone. Make sure you’ve downloaded any results you need before deleting.

Error Responses

400 Bad Request

Invalid request parameters:

{
  "error": "Invalid source type"
}

401 Unauthorized

Invalid or missing API key:

{
  "error": "Unauthorized"
}

404 Not Found

Job not found:

{
  "error": "Job not found"
}

500 Internal Server Error

Server error during processing:

{
  "error": "Internal server error"
}

Best Practices

Polling for Job Completion

When creating a job, use the single job endpoint to poll for completion:

async function waitForJobCompletion(jobId, checkInterval = 5000) {
  while (true) {
    const response = await fetch(`https://api.campaignkit.cc/v1/email/validate/job/${jobId}`, {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    });
 
    if (!response.ok) {
      if (response.status === 404) {
        throw new Error('Job not found');
      }
      throw new Error(`HTTP error ${response.status}`);
    }
 
    const job = await response.json();
 
    if (job.state === 'done') {
      console.log('Job completed!');
      console.log(`Deliverable: ${job.summary.deliverableCount}`);
      console.log(`Risky: ${job.summary.riskyCount}`);
      console.log(`Undeliverable: ${job.summary.undeliverableCount}`);
      return job;
    }
 
    if (job.state === 'failed') {
      throw new Error('Job failed');
    }
 
    console.log(`Progress: ${job.summary.totalEmails}/${job.emailCount} emails processed`);
    await new Promise(resolve => setTimeout(resolve, checkInterval));
  }
}

Consider using Webhooks to receive automatic notifications when jobs complete instead of polling.

Efficient Result Pagination

When fetching large result sets, use pagination efficiently:

async function processJobResults(jobId, batchSize = 1000) {
  let position = 0;
 
  while (true) {
    const results = await fetch(
      `https://api.campaignkit.cc/v1/email/validate/job/${jobId}/result?pos=${position}`,
      { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
    ).then(r => r.json());
 
    if (results.length === 0) break;
 
    // Process this batch
    await processBatch(results);
 
    position += results.length;
  }
}

Filtering Downloads

Use the filters parameter to download only the emails you need:

# Download only deliverable emails (valid + risky might be acceptable)
curl "https://api.campaignkit.cc/v1/email/validate/job/123/download?filters=valid&filters=risky" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o deliverable.csv
 
# Download only high-quality emails (valid only)
curl "https://api.campaignkit.cc/v1/email/validate/job/123/download?filters=valid" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o high-quality.csv

File Upload Best Practices

When uploading files:

  • Ensure your CSV has email addresses in the first column or has an “email” column header
  • Remove duplicates before uploading to save credits
  • For Excel files, use the first sheet with emails in the first column
  • Maximum file size may vary based on your plan

Job vs. Direct Validation

Choose the right endpoint for your use case:

Use CaseRecommended Endpoint
Real-time form validationDirect validation (/email/validate)
Batch of 1-100 emailsDirect validation (/email/validate)
Batch of 100+ emailsValidation job (/email/validate/job)
File upload (CSV/Excel)Validation job (/email/validate/job)
Need to download filtered resultsValidation job with download
Integration with third-party platformValidation job (check for integration support)

Need Help?

If you encounter any issues or have questions about validation jobs: