Strict mode for B2C signups

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.

The strict-mode flag set

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_aliassoft+ in local-partada+sale@gmail.com
multi_dot_localsoft2+ dots in local-parta.d.a@gmail.com
gmail_dot_aliassoftGmail dot-aliasing collapses to existing mailboxa.d.a@gmail.com
throwaway_localhardtest@, asdf@, nobody@test@gmail.com
sequential_runhard4+ char sequential runqwerty@gmail.com
repeated_char_runhard4+ char repeataaaa@gmail.com
all_digits_localsoftLocal-part is all digits12345678@gmail.com
very_short_localsoftLocal-part ≤ 2 charsa@gmail.com
high_digit_ratiosoft≥50% digits in local-partada1234@gmail.com
The call

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.

request.sh
bash
curl https://vrfymail.com/v1/check?strict=true \
  -H "Authorization: Bearer vk_live_..." \
  -d '{ "email": "ada+throwaway123@gmail.com" }'
response.json
json
{
  "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
}
De-duplication

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.

The B2C signup math
  • 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.
Pairs well with

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.

Frequently asked

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