Mailchk
Back to Blog
Guides7 min read

How to Validate Emails in Django with Mailchk

Feb 11, 2026

How to Validate Emails in Django with Mailchk

Django's form and model validation system makes it straightforward to add external email validation. This guide shows how to integrate Mailchk using a custom validator, a service with caching, and DRF serializer integration.

Step 1: Validation Service

# utils/email_validation.py
import requests
from django.conf import settings
from django.core.cache import cache

def validate_email_address(email: str) -> dict:
    cache_key = f"email_validation:{email}"
    cached = cache.get(cache_key)
    if cached is not None:
        return cached

    try:
        response = requests.post(
            "https://api.mailchk.io/v1/check",
            json={"email": email},
            headers={
                "X-API-Key": settings.MAILCHK_API_KEY,
                "Content-Type": "application/json",
            },
            timeout=5,
        )
        response.raise_for_status()
        result = response.json()
    except requests.RequestException:
        result = {"valid": True, "disposable": False}

    cache.set(cache_key, result, timeout=86400)
    return result

Step 2: Custom Validator

# validators/email.py
from django.core.exceptions import ValidationError
from utils.email_validation import validate_email_address

def validate_real_email(email: str) -> None:
    result = validate_email_address(email)

    if not result.get("valid", False):
        raise ValidationError("Please enter a valid email address.")

    if result.get("disposable", False):
        raise ValidationError("Disposable email addresses are not allowed.")

Step 3: Use in Models and Forms

# models.py
from validators.email import validate_real_email

class User(models.Model):
    email = models.EmailField(unique=True, validators=[validate_real_email])

# forms.py
class SignupForm(forms.Form):
    email = forms.EmailField(validators=[validate_real_email])
    password = forms.CharField(widget=forms.PasswordInput)

Django REST Framework Integration

# serializers.py
from rest_framework import serializers
from utils.email_validation import validate_email_address

class SignupSerializer(serializers.Serializer):
    email = serializers.EmailField()
    password = serializers.CharField(min_length=8)

    def validate_email(self, value):
        result = validate_email_address(value)

        if not result.get("valid"):
            raise serializers.ValidationError("Invalid email address.")
        if result.get("disposable"):
            raise serializers.ValidationError("Disposable emails not allowed.")

        if result.get("did_you_mean"):
            self.context["email_suggestion"] = result["did_you_mean"]

        return value

Async Support (Django 4.1+)

import httpx

async def validate_email_async(email: str) -> dict:
    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://api.mailchk.io/v1/check",
            json={"email": email},
            headers={"X-API-Key": settings.MAILCHK_API_KEY},
            timeout=5.0,
        )
        return response.json()

Best Practices

  • Cache results — use Redis or Memcached in production for fast lookups.
  • Fail open — allow signups if the validation service is temporarily unreachable.
  • Use the typo suggestion — return did_you_mean to the user as a helpful prompt.
  • Validate in forms/serializers, not views — keeps validation reusable across your app.

Getting Started

Get your free API key at mailchk.io/signup. 200 validations/month free, sub-50ms response times.

Ready to validate emails?

Start with 200 free validations. No credit card required.