Metadata-Version: 2.4
Name: mailcheck-dev
Version: 1.0.0
Summary: Official Python SDK for the MailCheck.dev email verification API. Verify emails, detect disposable addresses, check DNS/SPF/DKIM/DMARC, and bulk verify lists.
Home-page: https://mailcheck.dev
Author: MailCheck.dev
License: MIT
Project-URL: Homepage, https://mailcheck.dev
Project-URL: Repository, https://github.com/bnuyts/mailcheck-python
Project-URL: Documentation, https://mailcheck.dev/docs
Project-URL: Bug Reports, https://github.com/bnuyts/mailcheck-python/issues
Keywords: email,verification,validate,mailcheck,disposable,email-validation,email-verification,bulk-verify,spf,dkim,dmarc,mx,dns,api,sdk
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25.0
Requires-Dist: typing_extensions>=4.0.0; python_version < "3.11"
Provides-Extra: dev
Requires-Dist: pytest>=6.0.0; extra == "dev"
Requires-Dist: pytest-cov>=2.0.0; extra == "dev"
Requires-Dist: responses>=0.18.0; extra == "dev"
Dynamic: license-file

# MailCheck Python SDK

[![PyPI version](https://badge.fury.io/py/mailcheck-dev.svg)](https://badge.fury.io/py/mailcheck-dev)
[![Python version](https://img.shields.io/pypi/pyversions/mailcheck-dev.svg)](https://pypi.org/project/mailcheck-dev/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Official Python SDK for the [MailCheck.dev](https://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

```bash
pip install mailcheck-dev
```

## Quick Start

```python
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](https://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

```python
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:

```python
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:

```python
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:

```python
# 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:

```python
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:

```python
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:

```python
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

```python
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

```python
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

- 📖 [Documentation](https://mailcheck.dev/docs)
- 💬 [Support](https://mailcheck.dev/support)
- 🐛 [Bug Reports](https://github.com/bnuyts/mailcheck-python/issues)

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
