Do not reject admin@ or support@ merely because an email validator flags a role account. The flag describes a local-part pattern associated with a function, not a failed domain lookup. For most signup flows, accept the address and annotate the account. If your application requires a named individual, enforce that identity requirement separately rather than telling the user their email is invalid.
This distinction matters for developer tools. A team may deliberately register with a shared operational inbox so account notices survive staff turnover. A blanket “personal emails only” rule can exclude exactly the organisation you wanted to onboard.
Read the signal narrowly
nobounce returns risky with reason: "role_account" for patterns such as admin@, support@, and contato@. The role-account layer comes last, after syntax, reserved names, typo correction, DNS, typosquat MX matching, and disposable-domain detection. It flags risk; it does not turn that pattern into undeliverable.
The public fixture for admin@gmail.com, checked on October 5, 2026, returns:
{
"verdict": "risky",
"reason": "role_account",
"suggestion": null,
"confidence": 0.85,
"checked": { "syntax": true, "mx": true, "typo": true, "disposable": true },
"cached": false
}
support@hotmail.com returns the same fields. These are frozen demo results, not evidence that either specific inbox exists. /demo/check needs no key but resolves only the fixture corpus listed by /v1/config; it cannot validate arbitrary real addresses.
The response has no checked.role field. Do not invent one in your client. Use reason to identify the role-account result and preserve the documented checked object as received.
Likewise, confidence: 0.85 is not an 85% probability of delivery or proof that multiple people read the inbox. The API does not inspect its membership, ownership, or forwarding rules. A single founder can own admin@; a person's name can be an alias routed to a whole team.
Separate a contact address from a login identity
Ask which job the address serves before writing a block rule:
| Address use | Sensible role-account policy |
|---|---|
| Organisation contact or billing notices | Accept and annotate; the shared address may be intentional |
| Individual login | Confirm access, then apply your application's identity and authentication rules |
| Privileged administrator | Require your normal stronger authentication and authorisation controls |
| Marketing subscription | Apply consent rules independently; the role flag establishes no consent |
For a team product, model organisation contact and member identity as separate fields when they have different lifecycles. Requiring a named member for access does not require replacing the organisation's billing inbox.
A confirmation-link click establishes access to that message at that moment. It does not establish a unique human, employment status, or exclusive control of the inbox. Those are application responsibilities, not additional verdicts you can infer from DNS.
Branch on suggestion first, then reason
risky is not synonymous with role account. It also includes disposable domains and probable typos. A generic if (verdict === "risky") reject() loses those distinctions and can discard a correction the user could accept.
Here is a policy function for a server-side signup handler. null represents an unavailable check in your application, not a fifth API verdict:
export function signupEmailPolicy(result) {
if (result === null) {
return { action: "accept", verdict: "unchecked", mxChecked: false };
}
if (result.suggestion !== null) {
return {
action: "suggest",
suggestion: result.suggestion,
reason: result.reason,
};
}
if (result.verdict === "undeliverable") {
return { action: "reject", reason: result.reason };
}
return {
action: "accept",
verdict: result.verdict,
reason: result.reason,
roleAccount: result.reason === "role_account",
mxChecked: result.checked.mx,
};
}
Validate the upstream response shape before calling this function. A malformed response is an unavailable check, not a valid object with missing fields.
Offer any non-null suggestion rather than silently rewriting the address. Handle Email Validation Verdicts in a React Signup Form covers the UI states. For a role account with no correction, skip the typo banner: there is nothing to repair.
If a particular workflow genuinely forbids shared contacts, add an explicit product rule after this mapping. Say “This account requires an individual contact address,” not “This address cannot receive email.” Keep that restriction scoped to the workflow that needs it.
Make one bounded production call
Call your backend on submit or blur; keep the nobounce key off the browser:
curl -X POST https://nobounce.dev/v1/check \
-H "Authorization: Bearer $NOBOUNCE_KEY" \
-H 'Content-Type: application/json' \
-d '{"email":"admin@gmail.com"}'
Live checks require a paid key. There is no free tier: hobby is $1/mo for 1,000 checks/mo, pro $19/mo for 100,000, and scale $99/mo for 1,500,000. Obtain access by redeeming an operator-minted code or paying self-serve through Stripe cards or usevig stablecoins; both payment rails are live.
Bound the request with a short timeout. An HTTP error or client timeout says nothing about whether the input is a role account. Accept the signup with an unchecked annotation rather than deriving a rejection from the failure. How to Handle an Email Validation Timeout at Signup separates that case from the API's completed unknown response.
Test policy, not just the happy path
Before shipping, exercise these branches with fixtures or stubs:
admin@gmail.comandsupport@hotmail.com: accept withroleAccount: true, no suggestion banner.riskywithlikely_typoand a suggestion: offer the correction, not a shared-inbox warning.riskywithdisposable: apply your separate disposable policy, not the role rule. Handling disposable addresses explains that distinction.undeliverablewithout a suggestion: show the actual reason.- Timeout or malformed response: signup remains available, marked unchecked.
Log verdict, reason, and check metadata, not the submitted address or suggestion. nobounce persists no plaintext address; anything persisted is SHA-256 hashed, with domains in clear. Your application's logging still needs its own safeguards.
A role pattern is useful metadata, not a verdict on the person. For the full key-acquisition and signup integration procedure, give your coding agent /integrate.md.