Email Validation
The Email Validation endpoint allows you to verify the deliverability and quality of email addresses. Use this endpoint to validate single or multiple emails in one request.
Endpoint
POST https://api.campaignkit.cc/v1/email/validateAuthentication
Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEYRequest
Request Body
Send a JSON object with an array of email addresses to validate:
| Parameter | Type | Required | Description |
|---|---|---|---|
emails | array | Yes | Array of email addresses to validate (minimum 1 email) |
Example Request
curl -X POST https://api.campaignkit.cc/v1/email/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": [
"valid@example.com",
"invalid@fake-domain.xyz",
"admin@company.com"
]
}'You can validate up to 100 email addresses in a single API request. For larger batches, consider breaking them into multiple requests or using batch validation features.
Response
Response Format
The API returns a JSON object with a results array containing validation data for each email, and the total credits used:
{
"creditsUsed": 3,
"results": [
{
"email": "valid@example.com",
"contextId": "ctx_abc123",
"result": {
"syntax": "pass",
"mx": "pass",
"mailbox": "pass",
"score": 10,
"classifier": "valid",
"description": [],
"smtpResponse": "250 OK"
}
},
{
"email": "invalid@fake-domain.xyz",
"contextId": "ctx_def456",
"result": {
"syntax": "pass",
"mx": "fail",
"mailbox": "n/a",
"score": 0,
"classifier": "invalid",
"description": ["invalid_mx"],
"smtpResponse": ""
}
},
{
"email": "admin@company.com",
"contextId": "ctx_ghi789",
"result": {
"syntax": "pass",
"mx": "pass",
"mailbox": "n/a",
"score": 5,
"classifier": "risky",
"description": ["role_email"],
"smtpResponse": ""
}
}
]
}Response Fields
The top-level response contains:
| Field | Type | Description |
|---|---|---|
creditsUsed | integer | Number of validation credits consumed by this request |
results | array | Array of validation results for each email |
Each item in the results array contains:
| Field | Type | Description |
|---|---|---|
email | string | The email address that was validated |
contextId | string | Unique identifier for this validation result |
result | object | Validation result details |
Validation Result Object
| Field | Type | Values | Description |
|---|---|---|---|
syntax | string | pass, fail, n/a | Whether the email syntax is valid |
mx | string | pass, fail, n/a | Whether the domain has valid MX records |
mailbox | string | pass, fail, n/a | Whether the mailbox exists (n/a if server doesn’t allow checking) |
score | integer | 0-10 | Deliverability score (10 = best, 0 = will bounce) |
classifier | string | valid, risky, invalid | Overall classification of the email |
description | array | strings | Detailed validation flags (see below) |
smtpResponse | string | - | SMTP server response message (if available) |
Score Interpretation
The score field provides a quick assessment of email quality:
- 10: Email is valid and safe to send
- 7-9: Email is likely valid but has minor issues
- 4-6: Email is risky (role-based, catch-all, or disposable)
- 1-3: Email is likely invalid or undeliverable
- 0: Email will definitely bounce
Emails with scores below 7 should be reviewed carefully. Consider excluding scores below 4 from your sending lists.
Classifier Field
The classifier field provides a simple, categorical assessment of email quality:
- valid: Email is safe to send (typically score 7-10)
- risky: Email may have issues but could be valid (typically score 4-6)
- invalid: Email is undeliverable and will bounce (typically score 0-3)
Use classifier for quick filtering and routing decisions, and score for more nuanced quality assessment.
Description Flags
The description array contains detailed validation flags:
| Flag | Meaning |
|---|---|
role_email | Role-based email (admin@, info@, support@, etc.) |
disposable | Disposable/temporary email address |
catchall | Domain accepts all emails (catch-all server) |
blacklist | Email or domain is on a known blacklist |
invalid_syntax | Email format is invalid |
invalid_mx | Domain has no valid mail servers |
mailbox_full | Recipient’s mailbox is full |
mailbox_disabled | Mailbox exists but is disabled |
Code Examples
JavaScript (Node.js)
const fetch = require('node-fetch');
async function validateEmails(emails) {
const response = await fetch('https://api.campaignkit.cc/v1/email/validate', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ emails })
});
const data = await response.json();
return data;
}
// Usage
validateEmails(['test@example.com'])
.then(data => {
console.log(`Credits used: ${data.creditsUsed}`);
data.results.forEach(item => {
console.log(`${item.email}: ${item.result.classifier} (Score: ${item.result.score}/10)`);
});
})
.catch(error => console.error('Error:', error));Python
import requests
def validate_emails(emails):
url = 'https://api.campaignkit.cc/v1/email/validate'
headers = {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
}
data = {'emails': emails}
response = requests.post(url, json=data, headers=headers)
return response.json()
# Usage
data = validate_emails(['test@example.com'])
print(f"Credits used: {data['creditsUsed']}")
for item in data['results']:
result = item['result']
print(f"{item['email']}: {result['classifier']} (Score: {result['score']}/10)")PHP
<?php
function validateEmails($emails) {
$url = 'https://api.campaignkit.cc/v1/email/validate';
$data = json_encode(['emails' => $emails]);
$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',
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// Usage
$data = validateEmails(['test@example.com']);
echo "Credits used: {$data['creditsUsed']}\n";
foreach ($data['results'] as $item) {
$result = $item['result'];
echo "{$item['email']}: {$result['classifier']} (Score: {$result['score']}/10)\n";
}
?>Error Responses
401 Unauthorized
Invalid or missing API key:
{
"error": {
"code": "unauthorized",
"message": "Invalid API key"
}
}400 Bad Request
Invalid request format:
{
"error": {
"code": "invalid_request",
"message": "The 'emails' field is required and must be an array"
}
}429 Too Many Requests
Rate limit exceeded:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please wait before making more requests"
}
}Best Practices
Filter by Classifier
Use the classifier field for simple, reliable filtering:
const data = await validateEmails(emailList);
const results = data.results;
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}`);
console.log(`Total credits used: ${data.creditsUsed}`);Filter by Score
For more granular control, use the score:
const results = data.results;
const highQuality = results.filter(r => r.result.score >= 8);
const acceptable = results.filter(r => r.result.score >= 6 && r.result.score < 8);
const questionable = results.filter(r => r.result.score >= 4 && r.result.score < 6);
const invalid = results.filter(r => r.result.score < 4);
console.log(`High: ${highQuality.length}, Acceptable: ${acceptable.length}, Questionable: ${questionable.length}, Invalid: ${invalid.length}`);Check Specific Flags
Look for specific issues in the description array:
results.forEach(item => {
const { email, result } = item;
if (result.description.includes('disposable')) {
console.log(`${email} is a disposable email address`);
}
if (result.description.includes('role_email')) {
console.log(`${email} is a role-based email (may have low engagement)`);
}
});Handle Catch-All Domains
Catch-all domains accept all emails, making verification difficult:
const hasCatchAll = result.description.includes('catchall');
if (hasCatchAll && result.score < 7) {
// Consider this email risky since we can't verify the mailbox
console.log('Catch-all domain detected - mailbox verification unavailable');
}Batch Processing
For large lists, process in batches of 100:
async function validateLargeList(emails) {
const batchSize = 100;
const allResults = [];
let totalCreditsUsed = 0;
for (let i = 0; i < emails.length; i += batchSize) {
const batch = emails.slice(i, i + batchSize);
const data = await validateEmails(batch);
allResults.push(...data.results);
totalCreditsUsed += data.creditsUsed;
// Optional: Add delay to respect rate limits
await new Promise(resolve => setTimeout(resolve, 1000));
}
return {
results: allResults,
totalCreditsUsed
};
}
// Usage
const { results, totalCreditsUsed } = await validateLargeList(largeEmailList);
console.log(`Validated ${results.length} emails using ${totalCreditsUsed} credits`);Validation Credits
Each email validation consumes one credit from your account. The API response includes a creditsUsed field showing how many credits were consumed by the request.
const data = await validateEmails(['email1@example.com', 'email2@example.com']);
console.log(`Credits used: ${data.creditsUsed}`); // Output: Credits used: 2You can also check your remaining credits in the CampaignKit dashboard.
Duplicate emails in the same request are deduplicated automatically and only consume one credit per unique email address. The creditsUsed field reflects the actual number of credits consumed after deduplication.
Need Help?
If you encounter any issues or have questions about email validation:
- Check the API Overview for authentication and general information
- Review Webhooks documentation for asynchronous validation notifications
- Contact support at support@campaignkit.cc