Block disposable email signups static lists miss.
Disposable domain lists catch test@mailinator.com. They don't catch ada+throwaway123@gmail.com, asdf@gmail.com, a.d.a@gmail.com, or qwerty@gmail.com. vrfymail's strict mode does.
Nine local-part patterns, graded by severity
Each flag fires on a different pattern in the local-part of the email (the bit before @). Hard flags downgrade to undeliverable. Soft flags downgrade to risky — your form decides whether to block or warn.
| Flag | Severity | Trigger | Example |
|---|---|---|---|
| plus_alias | soft | + in local-part | ada+sale@gmail.com |
| multi_dot_local | soft | 2+ dots in local-part | a.d.a@gmail.com |
| gmail_dot_alias | soft | Gmail dot-aliasing collapses to existing mailbox | a.d.a@gmail.com |
| throwaway_local | hard | test@, asdf@, nobody@ | test@gmail.com |
| sequential_run | hard | 4+ char sequential run | qwerty@gmail.com |
| repeated_char_run | hard | 4+ char repeat | aaaa@gmail.com |
| all_digits_local | soft | Local-part is all digits | 12345678@gmail.com |
| very_short_local | soft | Local-part ≤ 2 chars | a@gmail.com |
| high_digit_ratio | soft | ≥50% digits in local-part | ada1234@gmail.com |
Strict mode is one flag
Pass strict: true in the body (or ?strict=true in the URL). The response shape extends with a strict object naming every flag that fired.
curl https://vrfymail.com/v1/check?strict=true \
-H "Authorization: Bearer vk_live_..." \
-d '{ "email": "ada+throwaway123@gmail.com" }' {
"result": "risky",
"reason": "plus_aliasing_rejected",
"reason_message": "Please use your real email without a +tag.",
"strict": {
"flags": ["plus_alias"],
"severity": "soft",
"canonical_email": "ada@gmail.com"
},
"did_you_mean": null
} canonical_email kills the "+1, +2, +3" trick.
Strict mode always returns strict.canonical_email — plus-alias-stripped, and for Gmail, dot-collapsed. ada+sale@gmail.com and a.d.a+launch@gmail.com both canonicalize to ada@gmail.com.
Index your users table on canonical_email, not the literal address. Now your "one free trial per customer" rule actually enforces.
- Static list Catches
test@mailinator.com. Misses everything on Gmail. - CAPTCHA Detects bots. Doesn't detect humans claiming a 10th free trial.
- Email OTP Confirms inbox ownership. Doesn't prevent 50 burner Gmail accounts.
- Strict mode Catches the patterns above. Combine with OTP/CAPTCHA for high-stakes flows.
The other signals on the same call
Strict mode runs alongside disposable detection (269K+ domain database), spam-trap detection, and your per-customer bounce overlay. One call returns every signal — 50ms p50.
Building a B2C signup form with an AI editor? The AI builders hub has copy-paste integrations for Cursor, Claude Code, v0, Bolt.new, and seven more — each scaffolds strict-mode-aware signup handlers.
B2C strict mode, answered
- What does strict mode actually catch that the default doesn't?
- Default verification catches syntax errors, missing MX, disposable domains, and previously-bounced addresses. Strict mode adds a layer of pattern detection on the local-part (the bit before @): plus-aliases (ada+throwaway@), gmail dot tricks (a.d.a@gmail.com that resolves to ada@gmail.com), throwaway local-parts (test@, asdf@, nobody@), sequential keyboard runs (qwerty@, asdfgh@), repeated character runs (aaaa@), all-digit locals (123456@), very short locals (a@), and high digit ratios. These are the patterns static blocklists miss because they live in the local-part, not the domain.
- Doesn't blocking plus-aliases break Gmail signups?
- Strict-mode flags are graded: plus_alias is a soft flag (verdict: risky, allow submit), throwaway_local is a hard flag (verdict: undeliverable, block). The reasoning: a plus-alias might be a legitimate user filtering signups for organization. A throwaway_local like test@ almost never is. Tune the boundary in your form — accept all risky, accept some risky with reasons, or block everything below deliverable.
- What's canonical_email and how do I use it?
- canonical_email is always returned when strict mode fires. It strips plus-aliases and, for Gmail, collapses dot-aliasing. Use it as a de-duplication key during signup: if ada+sale1@gmail.com tries to register and you already have a user with canonical_email = ada@gmail.com, you know they're trying to bypass a per-account limit. The canonical form lets you de-dupe without rejecting the real signup.
- Is strict mode on by default?
- No, and that's deliberate. Strict mode is opt-in via ?strict=true (query param) or strict: true (body). For B2B forms — where role accounts like sales@ and recruiting@ are legitimate leads — strict mode is wrong. For B2C signups, free trials, and fraud-sensitive flows, strict mode is the right default. Two endpoints, one config flag.
- How does this compare to a CAPTCHA?
- CAPTCHA detects bots; strict-mode flags detect humans with bad intent. They're complementary: a real human spinning up ada+1@gmail.com, ada+2@gmail.com, ada+3@gmail.com to claim 10 free trials passes a CAPTCHA on every signup but fails strict-mode's plus_alias check on every one. Use both for high-stakes B2C flows. For lower-stakes lists, strict-mode alone covers 90% of cases without the UX hit.
Strict mode is one flag. Throwaways stop today.
5,000 verifies/month free, no card. Paid plans start at $9/mo — see pricing.
Get my API key