Home / Block disposable email signups
Block disposable email signups
Published 2026-10-17
Throwaway inboxes let one person open many free trials, skew your activation numbers and never receive your onboarding emails. A disposable-domain check at signup stops most of them with one API call.
What ContactLint flags
- Disposable domains: the domain or any parent domain is on a list of 9,880 known throwaway domains from the open disposable-email-domains project (CC0 1.0), fetched 2026-10-12. Result:
disposable: true. - Dead domains: no MX or A record, so the address cannot receive mail. Result: verdict
invalid, reasonno_mx_or_a. - Typos of big providers:
gmial.comand similar. Result:did_you_meanis set. - Role addresses: admin@, info@ and similar shared inboxes. Result:
role_address: true.
Check typos before you block
Some typo domains, such as gmial.com, are also on the disposable list. If you block every disposable result first, a real person who mistyped Gmail gets a rejection instead of a fix. Check did_you_mean first:
const r = await fetch('https://contactlint.com/v1/email/validate', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + process.env.CONTACTLINT_KEY, 'content-type': 'application/json' },
body: JSON.stringify({ email }),
signal: AbortSignal.timeout(3000),
}).then(r => r.json()).catch(() => null);
const res = r && r.result;
if (res) {
if (res.did_you_mean) return askUser('Did you mean ' + res.did_you_mean + '?');
if (res.disposable) return reject('Please use a permanent email address.');
if (res.verdict === 'invalid') return reject('That email address cannot receive mail.');
}
// fail open: if the check times out, let the signup through
Python:
import os, requests
def check(email):
try:
r = requests.post("https://contactlint.com/v1/email/validate",
headers={"Authorization": f"Bearer {os.environ['CONTACTLINT_KEY']}"},
json={"email": email}, timeout=3)
res = r.json()["result"]
except Exception:
return "ok" # fail open
if res["did_you_mean"]:
return "suggest:" + res["did_you_mean"]
if res["disposable"]:
return "reject_disposable"
if res["verdict"] == "invalid":
return "reject_invalid"
return "ok"
Limits to know
A list only knows the domains someone has reported, and new throwaway domains appear all the time. Pair this check with a bot challenge and a per-network signup rate limit. It also cannot catch a real Gmail account made just for one trial. Look up any domain with the free disposable email checker or browse the disposable domain list.
Questions
Will this block real users?
Rarely, if you check did_you_mean first. A real user on a listed domain is possible, so show a clear message that asks for a different address instead of failing silently.
How often is the disposable list updated?
The list in use was fetched 2026-10-12 from the disposable-email-domains project and has 9,880 domains. Subdomains of listed domains are matched too.
What does it cost?
One check per signup: 100 free per key each month, then credit packs from $9 for 5,000.
Get a free API key. 100 checks per month, no card required. Or try a live check first.