Official Python SDK for the MailCheck.dev email verification API. Verify email addresses, detect disposable addresses, check DNS/SPF/DKIM/DMARC authentication, and bulk verify email lists with high accuracy.
- β Single Email Verification - Verify individual email addresses
- π Bulk Email Verification - Verify up to 100 emails in one request
- π Email Authentication - Check SPF, DKIM, and DMARC records
- π« Disposable Email Detection - Identify temporary email services
- π Detailed Results - Get comprehensive verification data
- β‘ Fast & Reliable - Built on proven infrastructure
- π‘οΈ Type Safe - Full type hints for better development experience
pip install mailcheck-devfrom mailcheck import MailCheck, MailCheckError
# Initialize client
mc = MailCheck("sk_live_your_api_key")
try:
# Verify a single email
result = mc.verify("user@example.com")
print(f"Email: {result['email']}")
print(f"Valid: {result['valid']}")
print(f"Score: {result['score']}")
print(f"Credits remaining: {result['credits_remaining']}")
except MailCheckError as e:
print(f"Error: {e}")Get your API key from the MailCheck.dev dashboard. The SDK supports both test and live keys:
- Secret keys:
sk_live_...(for server-side use) - Public keys:
pk_live_...(for client-side widget use, domain-restricted)
from mailcheck import MailCheck
# Basic configuration
mc = MailCheck("sk_live_your_api_key")
# Custom configuration
mc = MailCheck("sk_live_your_api_key", {
"base_url": "https://api.mailcheck.dev", # Custom API endpoint
"timeout": 30 # Request timeout in seconds (default: 30)
})Verify individual email addresses with detailed analysis:
result = mc.verify("user@example.com")
# Response structure
{
"email": "user@example.com",
"valid": True,
"score": 85, # 0-100 confidence score
"reason": "Valid email address",
"checks": {
"syntax": "pass", # Email format validation
"disposable": "pass", # Disposable email detection
"mx": "pass", # MX record check
"smtp": "pass", # SMTP server validation
"role": "skip", # Role account detection
"free_provider": False # Free email provider flag
},
"details": {
"mxHost": "mail.example.com",
"isDisposable": False,
"catchAll": None,
"risk_level": "low",
"is_role": False,
"is_free_provider": False,
# ... additional details
},
"cached": False,
"credits_remaining": 99
}Verify multiple email addresses in a single request:
emails = [
"user1@example.com",
"user2@example.com",
"invalid@nonexistent.com"
]
# Basic bulk verification
job = mc.bulk.verify(emails)
# With webhook notification
job = mc.bulk.verify(emails, {
"webhook_url": "https://your-site.com/webhook"
})
print(f"Job ID: {job['job_id']}")
print(f"Results: {len(job['results'])}")
print(f"Credits remaining: {job['credits_remaining']}")Check SPF, DKIM, and DMARC authentication for email security:
# From email headers
auth_result = mc.verify_auth({
"headers": "From: sender@example.com\nTo: recipient@test.com\n..."
})
# From raw email content
auth_result = mc.verify_auth({
"raw_email": "Full email content including headers and body"
})
# With trusted domains (won't flag as suspicious)
auth_result = mc.verify_auth({
"headers": "From: sender@example.com\n...",
"trusted_domains": ["example.com", "yourcompany.com"]
})
# Response structure
{
"trust_score": 85, # 0-100 trust score
"verdict": "trusted", # "trusted", "suspicious", or "dangerous"
"from_": {
"address": "sender@example.com",
"display_name": "John Doe",
"domain": "example.com"
},
"authentication": {
"spf": {
"result": "pass",
"domain": "example.com"
},
"dkim": {
"result": "present",
"has_public_key": True
},
"dmarc": {
"has_policy": True,
"policy": "quarantine"
}
},
"anomalies": [],
"lookalike": {
"is_lookalike": False
},
"privacy": {
"body_processed": False,
"headers_only": True
},
"credits_remaining": 98
}The SDK raises MailCheckError for API-related errors:
from mailcheck import MailCheck, MailCheckError
mc = MailCheck("sk_live_your_api_key")
try:
result = mc.verify("invalid-email")
except MailCheckError as e:
print(f"Status: {e.status}") # HTTP status code
print(f"Code: {e.code}") # Error code from API
print(f"Message: {str(e)}") # Human-readable message
# Handle specific error types
if e.status == 401:
print("Invalid API key")
elif e.status == 429:
print("Rate limit exceeded")
elif e.code == "insufficient_credits":
print("Not enough credits")Common error codes:
invalid_email- Email format is invalidinsufficient_credits- Account has no remaining creditsrate_limit_exceeded- Too many requeststimeout- Request timed out
The API has built-in rate limiting. The SDK will automatically raise a MailCheckError if you exceed your rate limit. Consider implementing exponential backoff for production applications:
import time
from mailcheck import MailCheckError
def verify_with_retry(mc, email, max_retries=3):
for attempt in range(max_retries):
try:
return mc.verify(email)
except MailCheckError as e:
if e.status == 429 and attempt < max_retries - 1:
# Exponential backoff: 1s, 2s, 4s
wait_time = 2 ** attempt
time.sleep(wait_time)
continue
raiseThe SDK includes comprehensive type hints for better IDE support and error prevention:
from mailcheck import MailCheck
from mailcheck.types import VerifyResult, MailCheckOptions
options: MailCheckOptions = {
"timeout": 60
}
mc = MailCheck("sk_live_your_api_key", options)
result: VerifyResult = mc.verify("test@example.com")
# Your IDE will provide full autocomplete and type checking
print(result["score"]) # Type: int
print(result["valid"]) # Type: boolfrom mailcheck import MailCheck, MailCheckError
def validate_signup_email(email: str) -> bool:
mc = MailCheck("sk_live_your_api_key")
try:
result = mc.verify(email)
# Reject disposable emails and low-quality addresses
if result["details"].get("isDisposable"):
print("Disposable email not allowed")
return False
if result["score"] < 70: # Adjust threshold as needed
print("Email quality too low")
return False
return result["valid"]
except MailCheckError as e:
print(f"Verification failed: {e}")
return Falsedef clean_email_list(emails: list) -> dict:
mc = MailCheck("sk_live_your_api_key")
# Process in batches of 100
batch_size = 100
all_results = []
for i in range(0, len(emails), batch_size):
batch = emails[i:i + batch_size]
try:
job = mc.bulk.verify(batch)
all_results.extend(job["results"])
except MailCheckError as e:
print(f"Batch failed: {e}")
continue
# Categorize results
valid_emails = [r["email"] for r in all_results if r["valid"]]
invalid_emails = [r["email"] for r in all_results if not r["valid"]]
return {
"valid": valid_emails,
"invalid": invalid_emails,
"total_processed": len(all_results)
}- Python 3.8+
requestslibrary (automatically installed)
- π Documentation
- π¬ Support
- π Bug Reports
This project is licensed under the MIT License - see the LICENSE file for details.