Disposable email detection is the cheapest fraud signal to add and the easiest one to over-trust. A domain list, a set lookup, one boolean. It takes an afternoon, it flags real abuse, and teams routinely wire it straight into a hard block at signup.
That last step is where it starts costing money. This is what the signal actually contains, what it cannot contain, and the shape we settled on after getting it wrong on our own signup form.
What the list actually is
Every disposable email checker, ours included, is a domain membership test. We pull the disposable-email-domains community blocklist — roughly four thousand domains — refresh it every 24 hours, and hold it in memory as a set. An address is checked by taking everything after the @, lowercasing it, and testing the domain and its parent, so x.mailinator.com matches on mailinator.com.
That is the whole mechanism. It is worth being blunt about the consequences:
- It is a list, so it lags. New burner domains appear faster than any list absorbs them, and anyone motivated can register one for a few dollars.
- It fails open by design. If the feed is unreachable we keep serving the last copy; if it is empty we flag nothing. A dead feed must never turn into a wall of refused signups.
- It knows domains, not intent. This is the part that bites.
The masked-email problem
Ten-minute-mail and Apple's Hide My Email are structurally the same thing: a throwaway-looking address on a shared domain that forwards somewhere real. One is used to farm free trials. The other ships by default on every iPhone.
Community blocklists are assembled from domain patterns, not intent, so they cannot separate them — and in practice they do not. DuckDuckGo Email Protection, Firefox Relay and iCloud Hide My Email all turn up on burner lists. So do a long tail of custom domains that happen to offer forwarding.
The users behind those addresses are not a marginal segment. They are the privacy-conscious, technically literate buyer — disproportionately the person evaluating a developer tool, and disproportionately the person who pays for one.
We stopped blocking on it at our own signup
Sentinel's signup form used to reject disposable domains outright. On 17 July 2026 we removed that check, deliberately, and wrote down why.
The reasoning was not that the signal is bad. It was that the check was refusing exactly the people most likely to buy, in order to prevent an abuse case we already had better answers for. What remained after we pulled it:
- The address still has to receive a one-time code to activate, which a genuine ten-minute inbox will not survive in volume.
- Three accounts per IP, ever.
- Ten signup attempts per IP per day, durably counted.
- A free-plan quota that caps what an abusive account is worth in the first place.
Every one of those constrains the actual abuse — farming free accounts — without punishing an address for the domain it sits on. The disposable signal itself is untouched in the customer-facing pipeline. We just stopped using it as a gate on ourselves.
Use it as an escalation, not a gate
The useful framing: a burner domain slightly raises the probability that a session is abusive. It never establishes it. So the signal should move a decision, not make one.
Concretely, in our pipeline a disposable domain adds 15 to the risk score, appends disposable_email to the reason list, and escalates a decision of allow to review. That is the entire effect. It cannot escalate review to block, and it cannot rescue a session that network or device signals already condemned.
The asymmetry is intentional. A burner address on an otherwise clean residential session is a mild curiosity. The same address arriving from a datacenter range through an antidetect browser, on a device already linked to four accounts, is a different story — and in that case the network and device signals are what carry the verdict, with the email merely confirming it.
In practice
Pass the address to evaluate() and read the result. The address is checked transiently — it is never stored or logged, and only the boolean survives on the event record.
const verdict = await sentinel.evaluate({
token,
email: req.body.email, // checked transiently, never stored
accountId: req.user?.id,
});
// verdict.email -> { disposable: true }
// verdict.reasons -> [..., 'disposable_email']
// verdict.decision -> 'review' (escalated from 'allow')
if (verdict.decision === 'block') return refuse();
if (verdict.decision === 'review') return stepUp(); // OTP, card check, manual queue
return proceed();
The important line is the middle one. If review routes to the same place as block in your application, you have built a hard block with extra steps and you will get the outcome we did.
If you genuinely want burner domains refused outright — and for some businesses that is the right call — make it an explicit policy decision rather than a side effect. In the dashboard, disposable_email is one of the signals you can bind to a block action, which overrides the engine's decision while leaving engine_decision intact so you can still see what the pipeline actually thought.
When blocking is the right call
The test is whether the action has a real unit cost and no recovery path:
- Promotion and referral credit. Money leaves on redemption. Refuse burners here.
- Free trials that provision paid infrastructure. Each signup has a floor cost you cannot claw back.
- Anything granting immediate withdrawal or transfer. Irreversible by definition.
And where it is usually wrong:
- Ordinary account signup. The abuse is multi-accounting, and device linking answers that far more precisely.
- Login. The address already exists in your database; the domain tells you nothing new.
- Newsletter and waitlist forms. The cost of a fake row is a row.
What it can never tell you
A burner domain does not mean fraud, and a reputable domain does not mean safety. The overwhelming majority of card testing, account takeover and bonus abuse we see arrives on ordinary Gmail, Outlook and corporate addresses, because attackers operating at any scale buy aged accounts rather than register throwaways.
Read the signal for what it is: weak evidence about intent to be contactable, useful in combination, dangerous alone. If disposable email is doing heavy lifting in your risk model, the model is thin — the questions that actually separate abuse from customers are whether the network is a proxy or datacenter exit, whether the browser is telling the truth about itself, and whether this device has been here before under other names.
On storing the address
A domain membership test needs no persistence. Ours is an in-memory set lookup: the address is not written to disk, not logged, and not retained after the request. Only the resulting boolean is kept on the event.
This is worth checking with any vendor you evaluate, because the default is often worse. Shipping every signup address to a third party and having it retained for months is a real data-protection exposure, and it is a poor trade for a signal this weak.
Frequently Asked Questions
Is disposable email detection worth adding at all?
Yes, as an input. A burner domain is a genuine signal that the person does not intend to be reachable, and on abuse-prone actions it correlates with trial farming and multi-accounting. The mistake is treating it as a verdict. Used as one escalation among several it costs you nothing; used as a gate it silently refuses privacy-conscious customers who are paying you money.
Why do masked-email services show up on burner lists?
Because structurally they look identical. DuckDuckGo Email Protection, Firefox Relay and iCloud Hide My Email all hand the user a throwaway-looking address on a shared domain that forwards to a real inbox. Community blocklists are built from domain patterns, not from intent, so relays land in the same file as ten-minute-mail. The domain cannot tell you which one you are looking at.
How current are disposable domain lists?
The widely used community list refreshes continuously and we re-pull it every 24 hours, but the ceiling is inherent: new burner domains appear faster than any list absorbs them, and an attacker who cares can register one. Treat coverage as good-not-complete. A list that flags nothing is failing open, which is the correct failure mode; a list you trust absolutely is the problem.
Should the email address be stored to check it?
No, and you should ask any vendor that does. The check is a domain lookup against an in-memory set, so the address never needs to be persisted, logged, or sent anywhere. We keep only the boolean result on the event record. Storing raw signup addresses in a fraud vendor's logs creates a data-protection liability that the signal does not come close to justifying.
When is it right to hard-block on a burner domain?
When the action has a real unit cost and no recovery path: redeeming a promotion, claiming free credit, or starting a trial that provisions paid infrastructure. There the cost of a false negative is money out the door and the cost of a false positive is one annoyed user who can retry with another address. For ordinary signup or login, blocking is almost always the more expensive error.
Get the signal without the collateral damage
Pass an email, get email.disposable back alongside network and device signals. Checked transiently, never stored.
Try Sentinel free →