framework

Validate work emails in Django

A Django form validator that checks signup emails with isBusinessEmail via requests, rejects personal and disposable addresses and fails open.

isBusinessEmail for Django

In Django the check fits in a form’s clean_email method: validation errors render next to the field, and the verdict stays on the form for your view.

1. Settings

# settings.py
import os

IBE_API_KEY = os.environ["IBE_API_KEY"]

2. A small client

# accounts/isbusinessemail.py
import logging

import requests
from django.conf import settings

log = logging.getLogger(__name__)
_session = requests.Session()


def check_email(email: str, policy: str = "b2b") -> dict:
    """Return the isBusinessEmail verdict, or a fail-open placeholder."""
    try:
        r = _session.post(
            "https://api.isbusinessemail.com/v1/check",
            json={"email": email, "policy": policy},
            headers={"Authorization": f"Bearer {settings.IBE_API_KEY}"},
            timeout=(2, 3),
        )
    except requests.RequestException as exc:
        log.warning("isBusinessEmail unreachable: %s", exc)
        return {"recommendation": "allow", "fail_open": True}
    if r.status_code != 200:
        log.warning("isBusinessEmail error: HTTP %s", r.status_code)
        return {"recommendation": "allow", "fail_open": True}
    return r.json()

3. The form

# accounts/forms.py
from django import forms

from .isbusinessemail import check_email


class SignupForm(forms.Form):
    name = forms.CharField(max_length=255)
    email = forms.EmailField(label="Work email", max_length=254)

    def clean_email(self):
        email = self.cleaned_data["email"]
        verdict = check_email(email)
        self.email_verdict = verdict

        if verdict.get("recommendation") == "block":
            suggestion = verdict.get("did_you_mean")
            message = "Please use your work email."
            if suggestion:
                message += f" Did you mean {suggestion}?"
            raise forms.ValidationError(message, code="work_email_required")
        return email

4. The view

# accounts/views.py
from django.shortcuts import redirect, render

from .forms import SignupForm


def signup(request):
    form = SignupForm(request.POST or None)
    if request.method == "POST" and form.is_valid():
        v = form.email_verdict
        create_account(
            name=form.cleaned_data["name"],
            email=form.cleaned_data["email"],
            email_category=v.get("category"),
            needs_review=v.get("recommendation") == "review" or v.get("fail_open", False),
        )
        return redirect("onboarding")
    return render(request, "accounts/signup.html", {"form": form})

Notes

  • EmailField runs first, so malformed input never costs a check.
  • With Django REST Framework, put the same logic in a serializer’s validate_email.
  • In tests, patch check_email, or call the real API with test addresses such as personal@test.isbusinessemail.com.

Official docs: Django documentation (Forms and field validation). See also: Signup form guide.