Python Integration Guide

Emailyze has no official Python package — integrate using the standard requests library or the async httpx library.

Installation

pip install requests
# or for async:
pip install httpx

Single Email Check

import os
import requests

API_KEY = os.environ["EMAILYZE_API_KEY"]
BASE_URL = "https://api.emailyze.dev/v1/check/"

def check_email(email: str, verify: bool = False) -> dict:
    """
    Check a single email address.

    Returns dict with: is_disposable, provider_type, risk_score,
    mx_valid, catch_all, syntax, smtp, sources, checked_at, latency_ms.
    """
    resp = requests.get(
        BASE_URL,
        headers={"X-API-Key": API_KEY},
        params={"email": email, "verify": str(verify).lower()},
        timeout=5,
    )
    resp.raise_for_status()
    return resp.json()

# Usage
result = check_email("user@tempmail.com")
if result["is_disposable"]:
    print(f"Blocked: {result['domain']} (risk score: {result['risk_score']})")

Type-Annotated Response

from typing import TypedDict, Optional

class SmtpResult(TypedDict):
    can_connect_smtp: bool
    is_catch_all: Optional[bool]
    is_deliverable: Optional[bool]
    is_disabled: Optional[bool]
    has_full_inbox: Optional[bool]

class SyntaxResult(TypedDict):
    domain: str
    username: Optional[str]
    is_valid_syntax: bool
    suggestion: Optional[str]

class EmailCheckResult(TypedDict):
    email: Optional[str]
    domain: str
    is_disposable: bool
    provider_type: str  # "disposable" | "personal" | "masked" | "unknown"
    risk_score: float
    mx_valid: bool
    mx_provider: Optional[str]
    local_part_type: Optional[str]
    catch_all: bool
    syntax: Optional[SyntaxResult]
    smtp: Optional[SmtpResult]
    sources: list[str]
    checked_at: str
    latency_ms: int

Batch Check

def batch_check(emails: list[str]) -> list[dict]:
    """Check up to 1,000 emails in a single request."""
    resp = requests.post(
        "https://api.emailyze.dev/v1/check/batch/",
        headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
        json={"emails": emails},
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()["results"]

def batch_check_large_list(emails: list[str]) -> list[dict]:
    """Validate any number of emails by chunking into batches of 1,000."""
    results = []
    for i in range(0, len(emails), 1000):
        results.extend(batch_check(emails[i:i + 1000]))
    return results

# Usage: filter a list to safe emails only
emails = ["user@gmail.com", "fake@tempmail.com", "bob@proton.me"]
results = batch_check(emails)
safe = [r for r in results if not r["is_disposable"] and r["risk_score"] < 60]

Error Handling

import time
from requests.exceptions import HTTPError

def check_email_safe(email: str) -> dict | None:
    """Check email with retry on 429 and 500. Returns None on persistent failure."""
    for attempt in range(4):
        try:
            resp = requests.get(
                BASE_URL,
                headers={"X-API-Key": API_KEY},
                params={"email": email},
                timeout=5,
            )
            if resp.status_code == 429:
                wait = int(resp.headers.get("Retry-After", 2 ** attempt))
                time.sleep(wait)
                continue
            resp.raise_for_status()
            return resp.json()
        except HTTPError as e:
            if e.response.status_code in (400, 401):
                raise  # Don't retry client errors
            time.sleep(2 ** attempt)
    return None

Async Version (httpx)

import asyncio
import httpx

async def check_email_async(email: str, api_key: str) -> dict:
    async with httpx.AsyncClient(timeout=5) as client:
        resp = await client.get(
            "https://api.emailyze.dev/v1/check/",
            headers={"X-API-Key": api_key},
            params={"email": email},
        )
        resp.raise_for_status()
        return resp.json()

async def batch_check_concurrent(emails: list[str], api_key: str) -> list[dict]:
    """Check multiple emails concurrently (use for small lists, not bulk)."""
    async with httpx.AsyncClient(timeout=5) as client:
        tasks = [
            client.get(
                "https://api.emailyze.dev/v1/check/",
                headers={"X-API-Key": api_key},
                params={"email": email},
            )
            for email in emails
        ]
        responses = await asyncio.gather(*tasks, return_exceptions=True)
    return [r.json() for r in responses if not isinstance(r, Exception)]

# Run
result = asyncio.run(check_email_async("user@example.com", API_KEY))

Django / Flask Integration Example

# Django view: validate email at registration
from django.contrib.auth.forms import UserCreationForm
from django import forms
import requests

class SafeRegistrationForm(UserCreationForm):
    def clean_email(self):
        email = self.cleaned_data["email"]
        try:
            result = check_email(email)
            if result["is_disposable"]:
                raise forms.ValidationError(
                    "Please use a permanent email address."
                )
            if result["risk_score"] >= 80:
                raise forms.ValidationError(
                    "This email address appears to be high-risk."
                )
        except requests.RequestException:
            pass  # Fail open — don't block registration on API error
        return email

Environment Variables

Never hardcode your API key. Use environment variables:

# .env
EMAILYZE_API_KEY=em_live_xxxxxxxxxxxx
import os
from dotenv import load_dotenv  # pip install python-dotenv

load_dotenv()
API_KEY = os.environ["EMAILYZE_API_KEY"]