MailCheck Python SDK
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.
Features
- ✅ 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
Installation
pip install mailcheck-dev
Quick Start
from 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}")
Authentication
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)
Configuration
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)
})
API Reference
Single Email Verification
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
}
Bulk Email Verification
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']}")
Email Authentication Verification
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
}
Error Handling
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
Rate Limits
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
raise
Type Safety
The 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: bool
Examples
Validating User Signups
from 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 False
Cleaning an Email List
def 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)
}
Requirements
- Python 3.8+
requestslibrary (automatically installed)
Support
- 📖 Documentation
- 💬 Support
- 🐛 Bug Reports
License
This project is licensed under the MIT License - see the LICENSE file for details.
Metadata
Release files for mailcheck-dev 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mailcheck_dev-1.0.0.tar.gz | 15.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mailcheck_dev-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.2 kB
Release files / mailcheck_dev-1.0.0.tar.gz
| Download URL | mailcheck_dev-1.0.0.tar.gz |
|---|---|
| Size | 15.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5e0369a0f77d626b4617e7be1fd581abd7f5adfe7c4b7fd507a48c30cda36202
|
|
BLAKE2b-256 checksum How to use checksums |
547f0aa18f0b6c7e6fadb3cc6fe36dda5b4a397148bba5c03cb010e0da9359f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / mailcheck_dev-1.0.0-py3-none-any.whl
| Download URL | mailcheck_dev-1.0.0-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
20a85986a396931a25edb15e5fb6ccbfe7e9b074f3e4e2a8b7248f3d91505ca1
|
|
BLAKE2b-256 checksum How to use checksums |
66223d5a3be2da4ffc086ccb0f343bafc81d08e11954bf1af4f26edee09a16c4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|