Email Typo Correction at Signup: Suggest, Never Silently Rewrite
On August 15, 2026, I sent two clearly labeled test addresses to the public emailverifier.dev API:
signup-test-20260815@gmial.com
signup-test-20260815@outlok.com
The first produced a correction. The second did not.
That is the useful lesson for a signup form. A typo detector provides evidence, not permission to rewrite an address. Show a suggestion when you have one, let the user choose, and verify the chosen value again before creating the account or sending a confirmation message.
One typo was recognized
The transposed letters in gmial.com returned this actual response:
{
"email": "signup-test-20260815@gmial.com",
"status": "risky",
"action": "block",
"flagged": true,
"signals": ["possible_typo"],
"suggestion": "signup-test-20260815@gmail.com"
}
The API preserved the local part and suggested a different domain. It did not claim that the suggested Gmail mailbox exists or belongs to the person at the form.
In this state, I would pause signup and display one clear choice: use the suggested address or keep editing. If the user accepts the suggestion, send the corrected value through verification as a new input.
Why verify twice? The first response evaluated gmial.com. It did not evaluate the mailbox at gmail.com. Copying the suggestion straight into the account record would skip the check you intended to perform.
The other misspelling stayed unknown
outlok.com looks obvious to a human, but the same live endpoint returned:
{
"email": "signup-test-20260815@outlok.com",
"status": "unknown",
"action": "review",
"flagged": false,
"signals": ["verification_inconclusive"],
"suggestion": null
}
This result does not mean the address is correctly typed. It means the checks did not produce enough evidence for a definite mailbox result or a supported correction.
A product which changes every domain within one edit of a popular provider will eventually rewrite a legitimate domain. Brand names, country domains, private mail systems, and newly registered domains do not owe your similarity function an explanation.
So I would keep this address in the ordinary unknown path: review it, retry when appropriate, or continue with inbox confirmation if the cost of a false rejection is higher than the cost of an extra step. The broader API result-handling guide covers dependency failures and retry states.
Why autocorrection is the wrong fix
An email address is a destination and often an account identifier. A spelling suggestion in a search box is reversible. Sending a recovery link to a silently substituted mailbox is not.
RFC 5321 assigns the meaning of a local part to the host named by the domain. Your application therefore cannot assume that two local parts, or two similar domains, reach the same mailbox.
The OWASP identity guidance recommends preserving the entered address, defining one consistent comparison policy, and avoiding provider-specific transformations unless the system fully controls them. That is a good boundary here too.
Normalize what the protocol lets you normalize, such as the case of an ASCII domain. Keep the user’s local part intact. Treat a proposed provider correction as a separate candidate until the user accepts it.
Build the suggestion as a reversible state
The implementation needs more than an error string. It needs to remember the original value, the suggested value, and the user’s decision.
export function typoState(result) {
const hasSuggestion =
result.signals.includes('possible_typo') &&
typeof result.suggestion === 'string'
if (hasSuggestion) {
return {
state: 'needs_typo_choice',
original: result.email,
suggested: result.suggestion
}
}
if (result.status === 'undeliverable' || result.flagged) {
return { state: 'needs_correction', original: result.email }
}
if (result.status === 'unknown') {
return { state: 'needs_confirmation', original: result.email }
}
return { state: 'ready', original: result.email }
}
The needs_typo_choice screen should name the candidate plainly. “Did you mean signup-test-20260815@gmail.com?” is better than “Invalid email” because it tells the user what the system observed.
Use two real controls, such as “Use gmail.com” and “Edit address.” Do not make the suggested address a decorative line of text which silently replaces the field when the user submits.
If the suggestion appears after an asynchronous request, expose it as a programmatic status message. WCAG’s guidance for status messages explains how a suggestion or error should be announced to assistive technology without forcing an unnecessary focus change.
Keep syntax, typo evidence, and mailbox evidence separate
The browser’s email control handles the first layer only. The HTML Living Standard defines the syntax used by input type="email", but it does not know whether gmial.com was intended to be gmail.com.
Then the verifier adds domain and mailbox evidence. In the current emailverifier.dev API contract, possible_typo is one signal, while status, action, and flagged carry the broader result.
Do not collapse those fields into a homemade isValid boolean. You need to distinguish at least these paths:
- A malformed address needs an input correction.
- A recognized provider typo needs a user choice.
- A confirmed routing or mailbox failure needs another address.
- An inconclusive result needs retry, review, or confirmation.
- An accepted suggestion needs a fresh verification request.
The validation, verification, and confirmation guide explains why the final confirmation step still matters. A correction suggests where the user meant to receive mail. Confirmation shows that someone acted from the chosen inbox.
Do not suggest account addresses during login or recovery
Signup is the right place for this interaction because the user is supplying a new address. Login and password reset are different.
A message such as “Did you mean the Gmail address on this account?” may reveal which address is registered. It may also steer a recovery attempt toward an address the user did not enter.
OWASP recommends consistent login and reset responses which do not disclose whether an account exists. Keep typo suggestions out of those flows. Let the user re-enter the identifier, rate-limit attempts, and return the same recovery response regardless of account state.
Log the decision without storing another copy of the address
Measure the interaction as events: suggestion shown, suggestion accepted, address edited, second verification result, and confirmation completed. Those events tell you whether the feature prevents bounces or creates friction.
Avoid placing full addresses in analytics and application logs. OWASP recommends masking or pseudonymizing email identifiers and never logging confirmation or reset tokens.
Keep the original address in the signup session only as long as the interaction needs it. Store the user-approved address on the account. Store the verification result separately from the confirmation state.
Suggest. Ask. Verify again.