Light Mode Dark Mode
ParheliaWeb

Email Validation API Documentation

Email validation for developers and global teams: validate single or bulk addresses with syntax, domain, MX, and SMTP checks, then use structured results in CRM, signup, and email-marketing workflows.

View Email Validation API Pricing Start Free

Base URL: https://parheliaweb.com

All requests must include an API key in the x-api-key header. Responses are in JSON. Review our data methodology to understand the verification stages, caching, SMTP limitations, and risk states.

🚀 Quick Start (Free):
  1. Subscribe free at /register — no card required
  2. Get your universal API key in the portal
  3. Query this API — 100/month free
  4. Upgrade anytime — same key, more quota, advanced features unlocked
🗝️ Universal API Key: Your ParheliaWeb key works across all six APIs — this one, Funding, Layoffs, Fines, Acquisitions, and IPOs. A free tier is available for each of these APIs. Manage usage for all APIs in the portal.

💶 Pricing & Currency

All prices are listed in Euros (EUR). Your card will be charged in your local currency at the prevailing exchange rate. We use Stripe for secure payment processing, which supports 135+ currencies and local payment methods including iDEAL, Bancontact, and SEPA Direct Debit.

EU-Based: ParheliaWeb is built and hosted in the Netherlands. We design data processing around applicable data-protection requirements. Email addresses are not used in plain text for operational monitoring; related monitoring uses SHA-256 hashes. Our servers are located in Dutch data centers. See our Privacy Policy for scope and user responsibilities; this page is not legal advice or an absolute compliance guarantee.

🔐 Authentication

Pass your secret API key as an HTTP header on every request:

x-api-key: YOUR_API_KEY

If the key is missing or invalid, you'll receive a 401 Unauthorized or 403 Forbidden.

📡 Rate Limits & Access

Your daily quota depends on your subscription tier, while the rate limit exists to prevent abuse (e.g. using the API as a DDoS bot). The two are independent: exhausting your daily quota requires waiting until the next day, whereas exceeding the rate limit only requires a short cooldown.

PlanPriceRate LimitMonthly QuotaVerification DepthSupport
FreeFree60 requests / minute100 verificationsSyntax + Domain checks + SMTP (5s timeout)—
Starter€31/month60 requests / minute5,000 verificationsFull SMTP verification (10s timeout) + Batch validationEmail support
Pro€63/month60 requests / minute25,000 verificationsFull suite + Catch-all detection + Priority modesPriority email
Business€143/month60 requests / minute100,000 verificationsFull verification suite + Custom SLAsDedicated support

When the request rate exceeds the rate limit, the API returns 429 Too Many Requests. Simply retry after a short wait — this does not consume your daily quota.

📦 Batch validation limits: Starter 100/batch · Pro 500/batch · Business 2,500/batch
🔄 Concurrent requests: The number of simultaneous validations allowed depends on your plan: 1 (Free), 2 (Starter), 3 (Pro), 10 (Business). Additional requests will receive an immediate error response. For higher concurrency needs, contact us for Enterprise.
Why our free tier isn't like others: Most email APIs give free users basic syntax checks, greylisting, or 14-day trials that expire mid-project. We give you the same live SMTP verification pipeline our paying customers use — 100 queries/month, forever, on the same infrastructure. You only pay when you need the higher quota and detailed diagnostics.
🛡️ Zero-Domain Leakage SMTP Probing
SMTP handshakes originate from ParheliaWeb. The target mail server will generally see ParheliaWeb’s IP and domain rather than your infrastructure as the probing source.

Why it matters: Many cost-conscious teams expanding internationally attempt to self-host their own validation scripts to save API costs. Probing directly from your IP easily triggers Google/Microsoft anti-spam mechanisms, blacklisting your main domain and paralyzing outreach. Using the ParheliaWeb API can separate SMTP probing from your infrastructure and reduce the risk of direct probing affecting your mail systems; no validation service can guarantee 100% deliverability or domain reputation protection.

📦 Endpoint: Validate an Email Address

POST /v1/email/validate

Validates a single email address through our multi-phase verification pipeline. Currently monitoring thousands of blacklisted domains with continuously updated pattern detection for emerging spam techniques.

By default, responses are returned in English. For Chinese-language status values, risk factors, messages, blacklist details, and checks, pass lang: "zh" in the request body. English field names remain unchanged; only the values are translated.

Request Body

FieldTypeRequiredDescription
emailstringYesThe email address to validate
langstringNoResponse language. Use zh for Chinese translations of status, risk factors, messages, blacklist details, and checks. Defaults to en (English).

Example Requests

# Validate a single email address
curl -X POST https://parheliaweb.com/v1/email/validate \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_KEY" \
  -d '{"email": "user@example.com"}'

# Validate a known disposable domain
curl -X POST https://parheliaweb.com/v1/email/validate \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_KEY" \
  -d '{"email": "test@mailinator.com"}'

# Validate with Chinese response values
curl -X POST https://parheliaweb.com/v1/email/validate \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_KEY" \
  -d '{"email": "test@spidernet.nl", "lang": "zh"}'

Example Response — Valid Email

{
  "status": "ok",
  "result": {
    "email": "user@example.com",
    "status": "valid",
    "confidence": 90,
    "deliverability_score": 95,
    "is_role_based": false,
    "cached": false,
    "first_seen": "2026-06-15 21:45:00",
    "syntax_valid": true,
    "domain_check": {
      "passed": true,
      "whitelisted": false,
      "blacklisted": false,
      "blacklist_match": null,
      "dynamic_match": null,
      "no_probe": false,
      "checks_performed": [
        "blacklist_clean",
        "numeric_prefix_clean",
        "double_tld_clean"
      ]
    },
    "mx_valid": true,
    "mx_servers": ["mail.example.com"],
    "smtp_check": {
      "performed": true,
      "result": true,
      "code": 250,
      "message": "Mailbox accepted (code 250)"
    },
    "risk_factors": [],
    "performance_ms": {
      "total": 1847.32,
      "phases": {
        "syntax": 0.03,
        "domain_check": 1.48,
        "dns": 45.12,
        "smtp": 1800.69
      }
    }
  }
}

Example Response — Risky (Catch-All Domain)

{
  "status": "ok",
  "result": {
    "email": "info@company.com",
    "status": "risky",
    "confidence": 45,
    "deliverability_score": 40,
    "is_role_based": false,
    "cached": false,
    "first_seen": "2026-06-15 21:45:00",
    "syntax_valid": true,
    "domain_check": {
      "passed": true,
      "whitelisted": false,
      "blacklisted": false,
      "blacklist_match": null,
      "dynamic_match": null,
      "no_probe": false,
      "checks_performed": [
        "blacklist_clean",
        "numeric_prefix_clean",
        "double_tld_clean"
      ]
    },
    "mx_valid": true,
    "mx_servers": ["mail.company.com"],
    "smtp_check": {
      "performed": true,
      "result": true,
      "code": 250,
      "message": "Mailbox accepted (code 250)"
    },
    "catch_all": {
      "detected": true,
      "message": "Domain accepts all 2 test addresses — likely catch-all"
    },
    "risk_factors": [
      {"factor": "catch_all_domain", "severity": "medium"}
    ],
    "performance_ms": {
      "total": 3215.67,
      "phases": {
        "syntax": 0.02,
        "domain_check": 1.52,
        "dns": 38.41,
        "smtp": 2847.33,
        "catch_all": 328.39
      }
    }
  }
}

Example Response — Invalid (Blacklisted Domain)

{
  "status": "ok",
  "result": {
    "email": "spam@mailinator.com",
    "status": "invalid",
    "confidence": 95,
    "deliverability_score": 0,
    "is_role_based": false,
    "cached": false,
    "first_seen": "2026-06-15 21:45:00",
    "syntax_valid": true,
    "domain_check": {
      "passed": false,
      "whitelisted": false,
      "blacklisted": true,
      "blacklist_match": {
        "type": "static_domain",
        "domain": "mailinator.com",
        "reason": "Disposable email service",
        "category": "disposable",
        "severity": 10
      },
      "dynamic_match": null,
      "no_probe": false,
      "checks_performed": ["blacklist_hit"]
    },
    "mx_valid": false,
    "mx_servers": [],
    "smtp_check": {
      "performed": false,
      "result": null,
      "code": null,
      "message": "Skipped: domain rejected"
    },
    "risk_factors": [
      {
        "factor": "domain_rejected",
        "severity": "critical",
        "detail": {
          "type": "static_domain",
          "domain": "mailinator.com",
          "reason": "Disposable email service",
          "category": "disposable",
          "severity": 10
        }
      }
    ],
    "performance_ms": {
      "total": 1.54,
      "phases": {
        "syntax": 0.02,
        "domain_check": 1.48
      }
    }
  }
}

Example Response — Chinese (lang=zh)

{
  "status": "ok",
  "result": {
    "email": "test@spidernet.nl",
    "status": "无效",
    "confidence": 95,
    "deliverability_score": 0,
    "is_role_based": false,
    "domain_check": {
      "blacklist_match": {
        "type": "static_domain",
        "domain": "spidernet.nl",
        "reason": "从旧版黑名单迁移",
        "category": "垃圾邮件"
      },
      "checks_performed": ["黑名单命中"]
    },
    "risk_factors": [
      {
        "factor": "域名已拒绝",
        "severity": "严重",
        "detail": {
          "reason": "从旧版黑名单迁移",
          "category": "垃圾邮件"
        }
      }
    ]
  }
}

Response Fields

FieldTypeDescription
emailstringThe email address that was validated
statusstringOverall assessment: valid, invalid, risky, or unknown
confidenceinteger Confidence score 0–100. Meaning depends on the status:

For valid: 90 = mailbox confirmed by SMTP server. Always high confidence when valid.
For invalid: Indicates which phase caught the problem:
  • 100 = Syntax invalid (missing @, consecutive dots)
  • 95 = Domain rejected (blacklisted or dynamic pattern match)
  • 90 = No MX records (domain has no mail server)
  • 0 = SMTP server explicitly rejected the mailbox (code 550)
For risky: Higher = less risky. 60 = minor issue (temporary failure), 55 = catch-all domain, 45–50 = multiple concerns, 35 = high risk.
For unknown: Always 30 = could not obtain any answer (domain blocks probes, rate-limited, network issues).
deliverability_scoreintegerSimple 0–100 score indicating whether the email is safe to send. 95+ = safe, 40–70 = use caution, below 40 = do not send. Distilled from status, confidence, and risk factors for non-technical users and CRM rules.
is_role_basedbooleanTrue if the email is a role-based address (admin@, info@, support@). These are often auto-filtered by CRMs or ignored by real humans. Also appears as a role_based_account risk factor with low severity.
langstringRequest parameter. Use zh for Chinese translations of status, risk factors, messages, blacklist details, and checks. Defaults to en (English).
cachedbooleanTrue if the result was served from cache (instant), false if a fresh SMTP verification was performed
X-Cache (HTTP header)stringHIT if the result was served from cache, MISS if fresh verification was performed. Check this header to determine cache status without parsing the JSON body.
first_seenstring|nullISO 8601 timestamp of when this email hash was first encountered by our system. null on the first validation
syntax_validbooleanWhether the email passes RFC 5322 syntax validation
domain_check.passedbooleanWhether the domain passed all blacklist and pattern checks
domain_check.whitelistedbooleanTrue if the email or domain is on the trusted whitelist
domain_check.blacklistedbooleanTrue if the domain is on the static blacklist (disposable, spam, etc.)
domain_check.blacklist_matchobject|nullDetails about the blacklist match if applicable
domain_check.dynamic_matchobject|nullDetails about dynamic pattern match (numeric prefix, double TLD, etc.)
domain_check.no_probebooleanTrue if the domain is known to reject SMTP probes
domain_check.checks_performedarrayList of all domain-level checks executed and their outcomes
mx_validbooleanWhether the domain has valid MX records
mx_serversarrayList of MX server hostnames (up to 5, sorted by priority)
smtp_check.performedbooleanWhether SMTP verification was attempted
smtp_check.resultboolean|nullTrue = mailbox accepted, False = rejected, null = could not determine
smtp_check.codeinteger|nullSMTP response code (250, 550, etc.)
smtp_check.messagestringHuman-readable explanation of the SMTP result
catch_all.detectedboolean|nullPro tier: Whether the domain appears to be a catch-all
catch_all.messagestringPro tier: Details about catch-all detection
risk_factorsarrayList of risk factors with severity levels (critical, high, medium)
performance_ms.totalfloatTotal validation time in milliseconds
performance_ms.phasesobjectPer-phase timing breakdown (syntax, domain_check, dns, smtp, catch_all)

Status Values Explained

StatusMeaningRecommended Action
validEmail syntax is correct, domain exists, and SMTP server confirmed the mailboxSafe to send
invalidEmail failed syntax, domain, or SMTP checks with high confidenceDo not send — will bounce
riskyEmail could not be fully verified (catch-all domain, greylisting, suspicious patterns)Send with caution for marketing; avoid for transactional email
unknownCould not determine (rate-limited by provider, domain blocks probes, network issues)Retry later or verify through other means
🎯 Priority Modes (Pro & Business tiers): Control the balance between speed and accuracy by setting the X-Priority header on your requests:

If no header is set, balanced mode is used automatically.

⚠️ About major email providers: Verification accuracy varies by provider. Gmail provides real responses and can be verified reliably. Microsoft (Outlook, Hotmail, Live) accepts all addresses during SMTP verification, so results for these domains may be uncertain. Yahoo and some other providers block verification probes entirely. For domains where we cannot get a definitive answer, we return risky with a clear explanation rather than guessing. We believe in transparency — you deserve to know what we can and can't verify.
⏱️ About validation speed: Most validations complete in under 2 seconds. Some providers, particularly Gmail, may take 5–10 seconds to respond to SMTP probes. This is normal — Gmail deliberately introduces slight delays as part of their anti-spam measures. We wait for a real answer rather than guessing or returning early. Every response includes per-phase timing in performance_ms so you can see exactly where the time was spent.
How Verification Works: Our pipeline runs three phases:
(1) RFC 5322 syntax validation,
(2) domain checks against — blacklisted domains and dynamic spam patterns, and
(3) SMTP handshake verification. Each phase must pass before proceeding to the next. Results include per-phase timing so you can see exactly what happened.

🎯 How ParheliaWeb Compares

Not all email validators do the same thing. Here's how common approaches compare — and what each one misses.

Approach Catches syntax errors Catches disposable domains Catches nonexistent mailboxes Protects your sender IP Handles catch-all
Regex only ✅ ❌ ❌ N/A ❌
Regex + MX lookup ✅ ⚠️ Partial ❌ N/A ❌
Self-hosted SMTP probe ✅ ⚠️ Partial ✅ ❌ Your IP is exposed ❌
ParheliaWeb Email Validation API ✅ ✅ Thousands, auto-updated ✅ Real SMTP handshake ✅ Only ParheliaWeb's IP is visible ✅ Pro tier+

The table above isn't marketing — it's the actual engineering trade-off. If you only need to catch obvious typos, a regex is fine. But if email deliverability matters to your business, you need real SMTP verification with IP isolation, or you'll risk your corporate domain getting flagged as a probing source.

📦 Endpoint: Batch Validation

POST /v1/email/validate/batch

Validate multiple email addresses in a single request. Batch limits vary by tier:

Batches of 6+ emails are processed asynchronously — you'll receive an immediate response with a batch_id and can poll for results. Large batches may take several minutes to complete. Each batch is assigned a unique batch_id tracked in your validation logs.

⏱️ Batch processing: Large batches are processed asynchronously in the background across multiple workers. Submit your batch, receive a batch_id immediately, and poll the status endpoint to retrieve results when complete. Cached results return instantly, making repeat batches significantly faster.

Request Body

FieldTypeRequiredDescription
emailsarray of stringsYesList of email addresses to validate. Limit depends on your tier: Starter=100, Pro=500, Business=2500.
langstringNoResponse language. Use zh for Chinese translations of status, risk factors, messages, blacklist details, and checks. Defaults to en (English).

Example Request

curl -X POST https://parheliaweb.com/v1/email/validate/batch \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_KEY" \
  -d '{
    "emails": [
      "user@example.com",
      "spam@mailinator.com",
      "info@catchall-domain.com"
    ],
    "lang": "zh"
  }'

Example Response — Small Batch (Synchronous)

{
  "status": "ok",
  "result": {
    "batch_id": "dbb2b6bc8cc9",
    "total_emails": 3,
    "total_ms": 28.37,
    "results": [
      {
        "email": "user@example.com",
        "status": "有效",
        "confidence": 90,
        "deliverability_score": 95,
        "is_role_based": false,
        "cached": false,
        "first_seen": "2026-06-15 21:45:00"
      },
      {
        "email": "spam@mailinator.com",
        "status": "无效",
        "confidence": 95,
        "deliverability_score": 0,
        "is_role_based": false,
        "cached": false,
        "first_seen": "2026-06-15 21:45:01"
      },
      {
        "email": "info@catchall-domain.com",
        "status": "有风险",
        "confidence": 45,
        "deliverability_score": 40,
        "is_role_based": false,
        "cached": false,
        "first_seen": "2026-06-15 21:45:02"
      }
    ]
  }
}

Example Response — Large Batch (Async)

{
  "status": "ok",
  "result": {
    "batch_id": "23f6e6244854",
    "total_emails": 2500,
    "status": "processing",
    "message": "Batch queued for processing. Poll GET /v1/email/validate/batch/23f6e6244854 for results."
  }
}

📦 Endpoint: Poll Batch Results

GET /v1/email/validate/batch/{batch_id}

Poll for the results of an asynchronously processed batch. Returns the batch status and, when complete, the full results array.

Example Request

curl -H "x-api-key: YOUR_KEY" https://parheliaweb.com/v1/email/validate/batch/23f6e6244854

Example Response — Still Processing

{
  "status": "ok",
  "result": {
    "batch_id": "23f6e6244854",
    "total_emails": 2500,
    "completed_emails": 0,
    "status": "processing",
    "total_ms": null
  }
}

Example Response — Completed

{
  "status": "ok",
  "result": {
    "batch_id": "23f6e6244854",
    "total_emails": 2500,
    "completed_emails": 2500,
    "status": "completed",
    "total_ms": 45230.67,
    "results": [
      {
        "email": "user@example.com",
        "status": "valid",
        "confidence": 90,
        "deliverability_score": 95,
        "is_role_based": false,
        "cached": false,
        "first_seen": "2026-06-15 21:45:00"
      },
      {
        "email": "spam@mailinator.com",
        "status": "invalid",
        "confidence": 95,
        "deliverability_score": 0,
        "is_role_based": false,
        "cached": false,
        "first_seen": "2026-06-15 21:45:01"
      }
    ]
  }
}

💻 Code Snippets

Python

import requests

headers = {
    "Content-Type": "application/json",
    "x-api-key": "YOUR_API_KEY"
}
data = {"email": "user@example.com"}
resp = requests.post("https://parheliaweb.com/v1/email/validate", headers=headers, json=data)
result = resp.json()["result"]
print(f"Status: {result['status']}, Confidence: {result['confidence']}%")

# With Chinese response values
data_zh = {"email": "user@example.com", "lang": "zh"}
resp_zh = requests.post("https://parheliaweb.com/v1/email/validate", headers=headers, json=data_zh)
result_zh = resp_zh.json()["result"]
print(f"状态: {result_zh['status']}, 置信度: {result_zh['confidence']}%")

PHP

<?php

$api_key = 'YOUR_API_KEY';
$email = 'user@example.com';

$ch = curl_init('https://parheliaweb.com/v1/email/validate');

curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 15,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'x-api-key: ' . $api_key
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'email' => $email
        // Add 'lang' => 'zh' for Chinese response values
    ])
]);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http_code === 200) {
    $data = json_decode($response, true);
    $result = $data['result'];

    echo "Status: " . $result['status'] . "\n";
    echo "Confidence: " . $result['confidence'] . "%\n";
    echo "Deliverability: " . $result['deliverability_score'] . "%\n";
} else {
    echo "API error (HTTP " . $http_code . ")\n";
}

JavaScript (fetch)

fetch("https://parheliaweb.com/v1/email/validate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": "YOUR_API_KEY"
  },
  body: JSON.stringify({ email: "user@example.com" })
})
.then(res => res.json())
.then(data => console.log(data.result.status));

// With Chinese response values
fetch("https://parheliaweb.com/v1/email/validate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": "YOUR_API_KEY"
  },
  body: JSON.stringify({ email: "user@example.com", lang: "zh" })
})
.then(res => res.json())
.then(data => console.log(data.result.status)); // "有效" or "无效"

cURL

# Linux / macOS
curl -X POST https://parheliaweb.com/v1/email/validate \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{"email": "user@example.com"}'

# Windows 11 PowerShell
curl.exe -X POST https://parheliaweb.com/v1/email/validate -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" -d '{\"email\": \"user@example.com\"}'

# Windows 10 PowerShell
curl.exe -X POST https://parheliaweb.com/v1/email/validate -H "Content-Type: application/json" -H "x-api-key: YOUR_API_KEY" -d "{""email"": ""user@example.com""}"

# With Chinese response values (Linux / macOS)
curl -X POST https://parheliaweb.com/v1/email/validate \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{"email": "user@example.com", "lang": "zh"}'

🗝️ Your Key Works Across All ParheliaWeb APIs

Your API key isn't limited to this API. Use it across our full platform:

APIEndpoint BaseFree TierPro Tier
Email Validation/v1/email/validate100/mo25,000/mo
Funding Rounds/v1/funding100/day1,000/day
Layoffs/v1/layoffs100/day1,000/day
Regulatory Fines/v1/fines100/day1,000/day
Acquisitions/v1/acquisitions100/day1,000/day
IPOs/v1/ipos100/day1,000/day

Quotas are per-API. Upgrade each API independently based on your needs. Why different quotas? Email validation performs live SMTP handshakes — per-check infrastructure cost. Data APIs query our cached database — lower marginal cost.

📬 Support

If you run into any issues or have feature suggestions, email us at info@parheliaweb.com.

Email Validator API by ParheliaWeb · Built in the Netherlands · Terms · Privacy · Data Methodology · Why Choose Us · Contact