Skip to main content

MailCheck Python SDK

PyPI version Python version License: MIT

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 invalid
  • insufficient_credits - Account has no remaining credits
  • rate_limit_exceeded - Too many requests
  • timeout - 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+
  • requests library (automatically installed)

Support

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)

Source distribution for mailcheck-dev 1.0.0
File Size Uploaded
mailcheck_dev-1.0.0.tar.gz 15.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mailcheck-dev 1.0.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page