Tutorial · Python

Validate email addresses in Python

From a syntax check to a full mailbox verification of a CSV file, with working Python code.

Updated October 1, 2026 · 1 min read

1. Syntax check with email-validator

pip install email-validator
from email_validator import validate_email, EmailNotValidError

try:
    info = validate_email("Anna@Example.com", check_deliverability=False)
    email = info.normalized  # "Anna@example.com"
except EmailNotValidError as e:
    print(str(e))

check_deliverability=True additionally checks that the domain has DNS records for email.

2. MX lookup with dnspython

import dns.resolver  # pip install dnspython

def has_mx(domain: str) -> bool:
    try:
        return len(dns.resolver.resolve(domain, "MX")) > 0
    except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.NoNameservers):
        return False

3. Check that the mailbox exists

import os
import requests

def validate(email: str) -> dict:
    res = requests.get(
        "https://api.emailvalidation.io/v1/info",
        params={"email": email},
        headers={"apikey": os.environ["EMAILVALIDATION_API_KEY"]},
        timeout=30,
    )
    res.raise_for_status()
    return res.json()

result = validate("anna@company.com")
print(result["state"], result["reason"], result["score"])

4. Validate a CSV file

import csv

with open("contacts.csv") as src, open("contacts.validated.csv", "w", newline="") as dst:
    reader = csv.DictReader(src)
    writer = csv.DictWriter(dst, fieldnames=reader.fieldnames + ["state", "reason", "disposable"])
    writer.writeheader()
    for row in reader:
        r = validate(row["email"])
        writer.writerow({**row, "state": r["state"], "reason": r["reason"], "disposable": r["disposable"]})

For large files, run requests in parallel with a thread pool (5–10 workers) and respect your plan’s rate limit. For a quick one-off list of up to 50 addresses, use the bulk email validator.

Frequently asked questions

Which Python library validates email addresses?

The email-validator package (pip install email-validator) checks syntax and, optionally, that the domain resolves. It does not check whether the mailbox exists.

Can I verify an email with smtplib?

In theory you can send RCPT TO with smtplib, but most residential and cloud IPs are blocked on port 25, many servers greylist or accept everything (catch-all), and repeated probes can get your IP blacklisted. An API handles this for you.

Email validation API

Validate emails in your app

emailvalidation.io checks syntax, MX records and the mailbox over SMTP, flags disposable, role and free addresses and returns a quality score, in one request.

Read the docs

100 free validations every month. No credit card required.

GET https://api.emailvalidation.io/v1/info?email=support@emailvalidation.io

{
  "email": "support@emailvalidation.io",
  "domain": "emailvalidation.io",
  "format_valid": true,
  "mx_found": true,
  "smtp_check": true,
  "disposable": false,
  "role": true,
  "free": false,
  "score": 0.64,
  "state": "deliverable",
  "reason": "valid_mailbox"
}

Keep reading

Start using our email validation software today!

Get 100 validations per month for free