1. Home
  2. API docs
  3. Django

Validate email addresses in Django

To validate an email in Django beyond its format, add a clean_email method to your form that calls the SimpleVerifier API and raises ValidationError when the status is invalid. EmailField has already checked the syntax by then, so malformed input never reaches the API. If the request fails, return the address unchanged.

By SimpleVerifier Team

Before you start

  • Create a key on the API keys page. Keys start with sv_live_ and are shown once.
  • Read SIMPLEVERIFIER_KEY from the environment in settings.py and access it as settings.SIMPLEVERIFIER_KEY.
  • API access is included in the Pro plan ($29.99/month) and the Email + Phone plan ($49.99/month). See pricing.

1. Add the helper

Put this in your app. It needs requests (pip install requests).

myapp/simpleverifier.py
# myapp/simpleverifier.py
import logging

import requests
from django.conf import settings

API_URL = "https://simpleverifier.com/api/v1/verify"
log = logging.getLogger(__name__)


def email_status(email: str) -> str | None:
    """Return "valid", "risky" or "invalid", or None if the API could not answer."""
    try:
        r = requests.get(
            API_URL,
            params={"email": email},
            headers={"Authorization": f"Bearer {settings.SIMPLEVERIFIER_KEY}"},
            timeout=(5, 30),
        )
    except requests.RequestException as exc:
        log.warning("SimpleVerifier unreachable: %s", exc)
        return None

    if r.status_code != 200:
        log.warning("SimpleVerifier returned HTTP %s", r.status_code)
        return None

    return r.json().get("status")

2. Add the setting

Reading it with os.environ[...] means a missing key stops the app at startup rather than failing quietly in production.

settings.py
# settings.py
import os

SIMPLEVERIFIER_KEY = os.environ["SIMPLEVERIFIER_KEY"]

3. Check the address in clean_email

Django calls clean_<field>() after the field's own validation passes, so this only runs for well-formed addresses. The same method works on a ModelForm.

myapp/forms.py
# myapp/forms.py
from django import forms

from .simpleverifier import email_status


class SignupForm(forms.Form):
    email = forms.EmailField()

    def clean_email(self):
        # Runs only after EmailField has accepted the syntax, so malformed
        # addresses never reach the API.
        email = self.cleaned_data["email"]
        if email_status(email) == "invalid":
            raise forms.ValidationError(
                "This email address cannot receive mail. Please check it.",
                code="undeliverable",
            )
        return email

4. Or in a REST framework serializer

Django REST framework calls validate_<field>() the same way.

myapp/serializers.py
# myapp/serializers.py — Django REST framework
from rest_framework import serializers

from .simpleverifier import email_status


class SignupSerializer(serializers.Serializer):
    email = serializers.EmailField()

    def validate_email(self, value):
        if email_status(value) == "invalid":
            raise serializers.ValidationError("This email address cannot receive mail. Please check it.")
        return value

What the API returns

GET or POST https://simpleverifier.com/api/v1/verify with email runs the syntax, domain, disposable-domain and live mailbox checks in one call and returns:

{
  "email": "jane@company.com",
  "status": "valid",
  "reason": "Mailbox exists",
  "mailbox_checked": true
}

Every snippet above follows the same rule: only a successful response with status set to invalid blocks a person.

ResultWhat it meansWhat to do
validThe mail server confirmed the mailbox exists.Accept.
riskyThe domain is real but the mailbox couldn't be confirmed: catch-all domains, role addresses like info@, providers that hide mailbox status.Accept on signup forms. Store the status and keep these out of cold campaigns.
invalidBad format, no mail server, a disposable domain, or the mailbox doesn't exist.Reject and ask the person to check the address.
timeout, 429 or 503The check didn't finish: a slow mail server, too many calls this minute, or a brief outage.Accept (fail open) and log it. Re-check later if it matters.
401 or 402The key is wrong or revoked, or the subscription isn't active.Accept, and alert yourself: every check is being skipped until it's fixed.

Errors return JSON with an error message. Each key can make 120 calls a minute; for thousands of addresses, upload a CSV in the dashboard instead.

Phone numbers and spreadsheets

The same key works with /api/v1/phone?phone=…&country=… to validate a phone number and normalise it to E.164, with live carrier lookups on the Email + Phone plan. The request and response are in the API reference. To check a column of addresses without code, use the Google Sheets add-on with the same key.

Common questions

Why not use Django's EmailValidator?
Keep it. EmailValidator, which EmailField uses, checks the format. It does not check that the domain receives mail, that the domain isn't a disposable provider, or that the mailbox exists. clean_email adds those checks on top.
Can I run the check in the background instead?
Yes. If you'd rather never make someone wait, accept the signup, then call email_status() from a Celery or RQ task and flag the account if it comes back invalid. The form version is better when you want people to fix a typo before they leave the page.
How much does the SimpleVerifier API cost?
API access is included in the paid plans: Pro at $29.99/month and Email + Phone at $49.99/month. There are no per-call credits. Each key can make 120 calls a minute.
Should I reject risky addresses?
Not on a signup or contact form. Risky means the mailbox couldn't be confirmed, which includes every address at a catch-all company domain. Accept it, store the status, and leave risky addresses out of cold outreach.
What if the API is slow or down?
Let the address through. A mailbox check can take several seconds when a mail server is slow, so cap the wait at about 30 seconds (less on a busy form) and treat a timeout, a 429 or a 503 as unknown rather than invalid.

Ready to clean your email and phone lists?

Start verifying emails and phone numbers today and boost your deliverability.

Get Started

Cancel anytime • No setup required