Skip to main content
POST
/
api
/
v1
/
email-verification
/
batch
Batch Verify
curl --request POST \
  --url https://api.example.com/api/v1/email-verification/batch \
  --header 'Content-Type: application/json' \
  --data '
{
  "emails": [
    "<string>"
  ]
}
'
import requests

url = "https://api.example.com/api/v1/email-verification/batch"

payload = { "emails": ["<string>"] }
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({emails: ['<string>']})
};

fetch('https://api.example.com/api/v1/email-verification/batch', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/email-verification/batch",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'emails' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.example.com/api/v1/email-verification/batch"

payload := strings.NewReader("{\n \"emails\": [\n \"<string>\"\n ]\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/email-verification/batch")
.header("Content-Type", "application/json")
.body("{\n \"emails\": [\n \"<string>\"\n ]\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/api/v1/email-verification/batch")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"emails\": [\n \"<string>\"\n ]\n}"

response = http.request(request)
puts response.read_body
{
  "verificationId": "<string>",
  "totalEmails": 123,
  "creditsDeducted": 123,
  "status": "<string>",
  "results": [
    {}
  ]
}
Submit a batch of email addresses for verification. For large batches, results are processed asynchronously - use the verification ID to poll for results.

Request Body

emails
string[]
required
Array of email addresses to verify. Maximum 1000 emails per batch.

Examples

import { MailBreeze } from "mailbreeze";

const mailbreeze = new MailBreeze({ apiKey: "sk_live_xxx" });

// Submit batch for verification
const batch = await mailbreeze.verification.batch({
  emails: [
    "user1@example.com",
    "user2@example.com",
    "user3@example.com",
  ],
});

console.log(`Batch ID: ${batch.verificationId}`);
console.log(`Status: ${batch.status}`);
console.log(`Credits deducted: ${batch.creditsDeducted}`);

// If all emails were cached, results are immediate
if (batch.results) {
  console.log("All results from cache:");
  for (const result of batch.results) {
    console.log(`${result.email}: ${result.result}`);
  }
} else {
  // Poll for results
  let status = await mailbreeze.verification.get(batch.verificationId);

  while (status.status === "processing") {
    await new Promise(r => setTimeout(r, 2000)); // Wait 2 seconds
    status = await mailbreeze.verification.get(batch.verificationId);
    console.log(`Progress: ${status.processedEmails}/${status.totalEmails}`);
  }

  console.log("Results:", status.results);
  console.log("Analytics:", status.analytics);
}
import asyncio
from mailbreeze import MailBreeze

client = MailBreeze(api_key="sk_live_xxx")

# Submit batch for verification
batch = await client.verification.batch(
    emails=[
        "user1@example.com",
        "user2@example.com",
        "user3@example.com",
    ]
)

print(f"Batch ID: {batch.verification_id}")
print(f"Status: {batch.status}")
print(f"Credits deducted: {batch.credits_deducted}")

# If all emails were cached, results are immediate
if batch.results:
    print("All results from cache:")
    for result in batch.results:
        print(f"{result.email}: {result.result}")
else:
    # Poll for results
    status = await client.verification.get(batch.verification_id)

    while status.status == "processing":
        await asyncio.sleep(2)  # Wait 2 seconds
        status = await client.verification.get(batch.verification_id)
        print(f"Progress: {status.processed_emails}/{status.total_emails}")

    print("Results:", status.results)
    print("Analytics:", status.analytics)
client := mailbreeze.NewClient("sk_live_xxx")

// Submit batch for verification
batch, err := client.Verification.Batch(ctx, &mailbreeze.BatchVerifyParams{
    Emails: []string{
        "user1@example.com",
        "user2@example.com",
        "user3@example.com",
    },
})
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Batch ID: %s\n", batch.VerificationID)
fmt.Printf("Status: %s\n", batch.Status)
fmt.Printf("Credits deducted: %d\n", batch.CreditsDeducted)

// If all emails were cached, results are immediate
if batch.Results != nil {
    fmt.Println("All results from cache:")
    for _, result := range batch.Results {
        fmt.Printf("%s: %s\n", result.Email, result.Result)
    }
} else {
    // Poll for results
    for {
        status, _ := client.Verification.Get(ctx, batch.VerificationID)
        if status.Status != "processing" {
            fmt.Println("Results:", status.Results)
            break
        }
        fmt.Printf("Progress: %d/%d\n", status.ProcessedEmails, status.TotalEmails)
        time.Sleep(2 * time.Second)
    }
}
$mailbreeze = new MailBreeze('sk_live_xxx');

// Submit batch for verification
$response = $mailbreeze->verification->batch([
    'emails' => [
        'user1@example.com',
        'user2@example.com',
        'user3@example.com',
    ],
]);
$batch = $response['data'];

echo "Batch ID: " . $batch['verificationId'] . "\n";
echo "Status: " . $batch['status'] . "\n";
echo "Credits deducted: " . $batch['creditsDeducted'] . "\n";

// If all emails were cached, results are immediate
if (isset($batch['results'])) {
    echo "All results from cache:\n";
    foreach ($batch['results'] as $result) {
        echo $result['email'] . ": " . $result['result'] . "\n";
    }
} else {
    // Poll for results
    do {
        sleep(2);
        $statusResponse = $mailbreeze->verification->get($batch['verificationId']);
        $status = $statusResponse['data'];
        echo "Progress: " . $status['processedEmails'] . "/" . $status['totalEmails'] . "\n";
    } while ($status['status'] === 'processing');

    print_r($status['results']);
}
let client = Client::new("sk_live_xxx");

// Submit batch for verification
let batch = client.verification().batch(BatchVerifyParams {
    emails: vec![
        "user1@example.com".to_string(),
        "user2@example.com".to_string(),
        "user3@example.com".to_string(),
    ],
}).await?;

println!("Batch ID: {}", batch.verification_id);
println!("Status: {}", batch.status);
println!("Credits deducted: {}", batch.credits_deducted);

// If all emails were cached, results are immediate
if let Some(results) = batch.results {
    println!("All results from cache:");
    for result in results {
        println!("{}: {}", result.email, result.result);
    }
} else {
    // Poll for results
    loop {
        let status = client.verification().get(&batch.verification_id).await?;
        if status.status != "processing" {
            println!("Results: {:?}", status.results);
            break;
        }
        println!("Progress: {}/{}", status.processed_emails, status.total_emails);
        tokio::time::sleep(Duration::from_secs(2)).await;
    }
}
curl -X POST https://api.mailbreeze.com/api/v1/email-verification/batch \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      "user1@example.com",
      "user2@example.com",
      "user3@example.com"
    ]
  }'

Response

verificationId
string
Unique ID for polling batch status.
totalEmails
integer
Total number of emails in the batch.
creditsDeducted
integer
Number of credits deducted (cached emails are free).
status
string
Current batch status:
  • pending - Batch submitted, not yet started
  • processing - Verification in progress
  • completed - All emails verified
  • failed - Batch verification failed
results
array
Only populated when all emails were cached. Contains array of verification results.
Example Response
{
  "success": true,
  "data": {
    "totalEmails": 2,
    "creditsDeducted": 4,
    "status": "completed",
    "analytics": {
      "cleanCount": 0,
      "dirtyCount": 2,
      "unknownCount": 0,
      "cleanPercentage": 0
    },
    "results": {
      "clean": [],
      "dirty": [
        "test1@example.com",
        "test2@example.com"
      ],
      "unknown": []
    }
  },
  "meta": {
    "timestamp": "2025-12-27T13:39:38.819Z",
    "requestId": "5e1686a9-05dd-4693-bc5d-fd596fb16bdf",
    "path": "/api/v1/email-verification/batch"
  }
}
The response is wrapped in an envelope with success, data, and meta fields. SDKs automatically extract the data object.

Limits

LimitValue
Max emails per batch1,000
Max concurrent batches5
Processing time~1-2 seconds per email

Credits

  • New emails: 1 credit per email
  • Cached emails: 0 credits (cached 24 hours)
  • Credits are deducted upfront when batch is submitted

Errors

CodeHTTP StatusDescription
BATCH_TOO_LARGE400More than 1000 emails in batch
INSUFFICIENT_CREDITS402Not enough credits for batch
TOO_MANY_BATCHES429Too many concurrent batches
VALIDATION_ERROR400Invalid email format in batch