EmailGuard
  • Pricing
Log inRegister
Hands typing on a laptop keyboard

How to Catch Email Typos at Signup

by EmailGuard Engineering

Unsplash
September 16, 2026engineering8 min read

Share this article

On this page

  • What you'll accomplish
  • The mistake that looks like a fake user
  • What the detect body does
  • UX that does not steal the address
  • Server sketch
  • What we will not claim
  • Copy that does not shame the user
  • Forms that collect email twice
  • Test list
  • What Kickbox-style "did you mean" is doing differently
  • Rate limits and double submit
  • Common mistakes
  • FAQ
    • What is email typo detection at signup?
    • Should I block the signup or only warn?
    • Does a suggestion mean the inbox exists?
    • Why is syntax_validation still false?
    • Can I test this without writing production rules?
  • Next steps

Enjoyed this article?

More notes on building products, infrastructure, and teams.

EmailGuard

Email validation API for signup and lead intake—syntax, disposable, role, relay, and public-domain signals in one request.

Product

  • What's included

Docs

  • Documentation
  • API Reference
  • Knowledge Base

Resources

  • Blog
  • Changelog
  • Free tools
  • Alternatives
  • Legal & security
  • Contact
  • Data correction

Pricing

  • Pricing

© 2026 EmailGuard

A Baker Assets company

When the user types jane@gnail.com or jane@company.ccom, reject the raw string and show a suggested address they can accept in one click. EmailGuard can return suggested_email and suggested_domain while syntax_validation stays false. The suggestion is a corrected candidate from domain and TLD typo rules. It is not a mailbox ping and it is not permission to silently rewrite the row.

This is the typo companion to the email validation API checklist. Syntax still fails closed. You add a repair path so a one-character hostname miss does not look like a disposable block.

What you'll accomplish

  1. Tell a typo apart from a disposable or a work-email rule.
  2. Read suggested_email / suggested_domain on GET /api/v1/emails/detect.
  3. Prompt the user instead of writing the suggestion into the database.
  4. Avoid chaining a "did you mean" UX onto addresses that already parse.

Prerequisites: Server-side detect, email:detect on the key, and a signup form you control. Staging first.

The mistake that looks like a fake user

notareal@gnail.com can pass a sloppy regex (something@something.something). A librarian-grade RFC parser still accepts many lookalike hostnames. The user meant Gmail. You stored a domain that will bounce forever.

A blocklist of gnail.com in the browser is easy to bypass and always incomplete. New TLD fat-fingers appear (ccom, con, comm). You want a rule catalog that can chain a domain typo and a TLD typo. In our matcher tests, bogpond.ccom is the kind of input that should land on bigpond.com, not on a generic "invalid email" with no hint.

That chain is first-hand EmailGuard behavior (domain_typo then tld_typo in the filter catalog). We do not publish the pattern list on the public API. You get the candidate strings, not the regexes.

What the detect body does

From the public detect contract:

FieldWhen it appearsWhat to do
syntax_validationAlways on 2xxIf false, do not create the user on the raw email
suggested_domainDomain or TLD typo rule matchedShow "Did you mean @fixed.com?"
suggested_emailSame, with local-part preservedPrefer this in the UI
matched_rulesCatalog or staff rules firedid, label, and signal only. signal can be typo. Do not persist patterns

syntax_validation remains false on an invalid TLD even when we suggest a fix. That is intentional. The typed string is still wrong. If you create the account on the raw value, you stored garbage. If you create it on the suggestion without asking, you may store an address they did not type (and did not own).

confidence is low when syntax failed. Do not read disposable or role as a finished verdict on that body. Details: confidence and fail-open.

UX that does not steal the address

1. User submits jane@gnail.com
2. Server calls detect
3. syntax_validation false, suggested_email jane@gmail.com
4. Return 422 with { code: EMAIL_TYPO, suggested: "jane@gmail.com" }
5. Form shows: "Did you mean jane@gmail.com?" [Use suggestion] [Edit]
6. If they accept, submit the suggested string as a new detect
7. Only then run disposable / role / public_domain policy

Re-detect after accept. The first response was about a broken hostname. The second is about gmail.com.

Do not:

  • Swap the value in a hidden field and POST again with no copy.
  • Treat suggested_email as verified ownership.
  • Apply work-email or role rules to the broken hostname.

Consumer Gmail vs Google Workspace still uses public_domain on the accepted address. A suggestion to gmail.com is still freemail.

Server sketch

type Detect = {
  syntax_validation: boolean;
  suggested_email?: string;
  suggested_domain?: string;
  disposable: boolean;
};
 
export function signupGate(d: Detect): 
  | { action: "fix_syntax"; suggested?: string }
  | { action: "block_disposable" }
  | { action: "continue" } {
  if (!d.syntax_validation) {
    return { action: "fix_syntax", suggested: d.suggested_email };
  }
  if (d.disposable) return { action: "block_disposable" };
  return { action: "continue" };
}

Timeouts stay on the fail-open path. A skipped check is not a typo.

Cache 2xx by normalized with a short TTL. Do not cache syntax-fail suggestions as if they were durable mailbox facts. See cache detect results.

What we will not claim

We do not run SMTP to see whether jane@gmail.com exists. Kickbox-style "did you mean" on a deliverable mailbox is a different product. Our suggestion is hostname repair from catalog rules.

We do not correct every brand. If no rule fires, you get syntax false and no suggested_*. Show a plain "check the domain" message. Do not invent a guess in your app.

Homograph / mixed-script lookalikes are on the product roadmap as classification, not as this typo catalog. Do not stretch suggested_email to cover mixed-script lookalikes until that signal exists.

Copy that does not shame the user

Bad: "Invalid email." Better: "Check the domain. Did you mean jane@gmail.com?"

Put the suggestion in the same error surface as syntax, not in a toast that disappears. Keyboard users need a button, not only a clickable domain.

If they dismiss the suggestion twice, stop nagging. Store email_typo_dismissed_at on the attempt and show the generic syntax error. Some people own odd domains. Your catalog will be wrong for them.

Internationalized domains: we validate TLD and IDNA on the syntax path. A suggestion is still an ASCII or IDNA hostname from the catalog. Do not punycode in the UI unless you also show the Unicode form they will recognize.

Forms that collect email twice

Checkout plus account create: run detect on each submit. A typo fixed on the account step can reappear if billing copies a stale field. Re-read the input. Do not reuse the first suggested_email after they edited the box.

CRM import: do not auto-apply suggestions in bulk. A 10,000-row "fix gnail" job will rewrite real hosts that collided with a rule. Queue a review for rows that have suggested_email and leave the raw value until a human or the subscriber confirms.

Mobile keyboards add .con and .cpm more than desktop. Log suggested_domain in your analytics (the domain, not the local-part) so you can see whether the catalog is earning its keep.

Test list

  1. gnail.com / gmial.com style host: syntax false, suggestion present, no user created.
  2. Accept suggestion: second detect, syntax true, then disposable/role/public_domain apply.
  3. Dismiss suggestion, submit same junk: still 422.
  4. Valid plus address: no suggestion, normalize separately.
  5. Timeout: no suggestion UI, fail-open path, email_check=skipped.
  6. Key missing email:detect: 401, fail closed, page ops. Not a typo.

Wire these next to the disposable tests in block disposables at signup.

What Kickbox-style "did you mean" is doing differently

Kickbox and peers attach a suggestion to a verification result: they think the mailbox is close to a real one after SMTP or their own corpus. EmailGuard attaches a suggestion to a syntax failure: the hostname looks like a catalog fat-finger. You can use both products in one company. Do not copy their credit rules or risky buckets onto our 2xx body.

If you already show Kickbox's hint on a marketing form, do not show two competing suggestions. Pick the hostname repair when syntax_validation is false. Pick the verifier hint only when syntax passed and you are in a send-prep job.

Rate limits and double submit

Users mash the "use suggestion" button. That is two detect calls: the fail, then the accepted host. Cache the 2xx for the accepted normalized value so a third click does not spend a third unit. Do not cache the failed hostname as if it were a valid key. The cache guide is the quota counterpart.

matched_rules with signal: typo is for support, not for a public "we know your regex" UI. Patterns stay off the wire. If you open a ticket, send the rule id and the typed domain, not a guessed pattern.

Common mistakes

Auto-replacing on blur. Users who own a weird but real domain will fight you. Offer, do not overwrite.

Only fixing gnail / gmial in JavaScript. You will ship the three jokes everyone copies and miss TLD doubles.

Showing a suggestion when syntax already passed. If they typed jane+news@gmail.com, that is plus addressing, not a typo.

Logging the raw misspelled address in a public Slack. Treat it as personal data, same as the rest of detect.

FAQ

What is email typo detection at signup?

A check that the hostname looks like a known fat-finger of a real mail domain, then a candidate correction. EmailGuard exposes that as suggested_email / suggested_domain when a domain or TLD typo rule matches.

Should I block the signup or only warn?

Block the raw invalid address. Warn with a one-click accept for the suggestion. After they accept, apply disposable and policy flags on the new detect.

Does a suggestion mean the inbox exists?

No. It means the hostname looks like a catalog repair. Prove ownership with a confirmation email if you need the mailbox.

Why is syntax_validation still false?

Because they have not submitted a valid addr-spec yet. The suggestion is a candidate, not the request email.

Can I test this without writing production rules?

Yes. Use the syntax checker and detect in staging. Create a key on a free plan.

Next steps

  1. Map 422 bodies so the form can render suggested_email.
  2. Re-run detect after accept.
  3. Keep MX and disposable on their own pages: MX vs validation, block disposables.
  4. Read the detect reference for field names before you alias them in your API layer.