Django · Python
Block disposable email in Django
Add a form validator that calls Piisend before saving the user. Works in Django 3, 4, and 5. Pairs cleanly with django-allauth or Django's built-in auth.
The code
# validators.py
import os
import httpx
from django.core.exceptions import ValidationError
PIISEND_URL = "https://api.piisend.com/api/v1/intelligence/email"
def reject_disposable_email(value: str) -> None:
try:
r = httpx.post(
PIISEND_URL,
headers={
"Authorization": f"Bearer {os.environ['PIISEND_API_KEY']}",
"Content-Type": "application/json",
},
json={"email": value},
timeout=5.0,
)
if not r.is_success:
return # fail open
if r.json().get("signals", {}).get("disposable"):
raise ValidationError("Please use a permanent email address.")
except httpx.HTTPError:
return # fail open
# forms.py
from django import forms
from .validators import reject_disposable_email
class SignupForm(forms.Form):
email = forms.EmailField(validators=[reject_disposable_email])
password = forms.CharField(widget=forms.PasswordInput)API key
Store `PIISEND_API_KEY` in environment variables or Django settings — never commit live keys.
Fail-open vs fail-closed
Network errors silently pass validation. Log failures if you need to monitor API health.
Pair with verification
Call the validator in `UserCreationForm.clean_email()` or allauth's adapter `clean_email` hook.
Send verification email with Piisend
After blocking disposable addresses, send OTP and verification mail through the same Piisend account. One API key for intelligence checks and transactional sends.