Signals and reasons
Understand why a decision was returned and when individual signals matter.
The action tells your signup flow what to do. primary_reason says why, and the signals are the facts behind it.
Primary reason
primary_reason is the one thing that most drove the action. It is OK when nothing applied.
This shortened response says the address was blocked because its domain is a known disposable provider:
{
"action": "block",
"primary_reason": "DISPOSABLE",
"signals": {
"disposable": true
}
}Use it for a short explanation, or to record why a signup was stopped. It is always one of these:
| Value | The action was driven by |
|---|---|
DOMAIN_NEWLY_REGISTERED | Your new-domain rule. |
INFRASTRUCTURE_ZONE | Your free and dynamic-DNS rule. |
DOMAIN_UNDELIVERABLE | Your undeliverable-domain rule. |
DISPOSABLE | A known disposable or temporary email provider. |
NO_MX | The domain has no mail servers. |
DOMAIN_TYPO_SUGGESTED | The domain looks like a misspelling of a known provider. |
SUSPICIOUS | The address looks like generated junk or a test address. |
ROLE_BASED | A shared address such as info@, admin@, or support@. |
PRIVACY_RELAY | A privacy or alias relay that forwards to another inbox. |
PUBLIC_PROVIDER | A public provider such as Gmail or Yahoo. |
OK | Nothing. The address looked ordinary. |
The table is in priority order. Your own rules come first, so when one of them matches you always see it here. Compare the value, not the wording: the descriptions can change, the values will not.
Signals
Signals are the facts found during the check. Every field is always present. Use them when your product needs an exception the action alone cannot express.
| Signal | Example | What it tells you |
|---|---|---|
disposable | name@tempmail.com | The domain is a known temporary email provider. |
public_provider | name@gmail.com | The address uses a public provider. This is not bad by itself. |
role_based | support@company.com | The address looks shared by a team or function. |
suspicious | A strong junk-like pattern | The address needs more confidence before valuable access. |
privacy_relay | A known relay domain | The service forwards mail to another inbox. |
has_mx | true | Mail server records were found for the domain. |
suggested_domain | gmail.com | The entered domain may contain a typo. |
normalized_email | foobar@gmail.com | The canonical form after provider alias rules (see below). |
previously_checked | true | Your account already checked this same underlying address. |
has_spf | true | The domain publishes an SPF record. Read the caveats below. |
has_dmarc | false | The domain publishes a DMARC record. Read the caveats below. |
has_mx, has_spf, has_dmarc, and previously_checked can be null, which means not known rather than no. suggested_domain and normalized_email are null when they do not apply.
Email normalization and previously_checked
Some providers treat many spellings as one inbox. f.o.o.bar+trial2@gmail.com and foobar@googlemail.com both reach foobar@gmail.com. normalized_email gives you that single form.
- Gmail, Proton, Outlook, Fastmail, iCloud, and Zoho have alias rules we apply.
- Every other domain is only lowercased and trimmed.
- Two different mailboxes are never merged into one.
previously_checked is true when your account has checked the same address before, even spelled differently.
- It proves a previous check, not an existing account. If you only call the API at final signup submit,
trueusually means a repeat attempt. - It never changes
action. What to do about a repeat is your call. - All your API keys share one memory, so rotating a key loses nothing. Test addresses are remembered too; use Dashboard → Try a check to avoid that.
- Turn it off or delete a single address under Dashboard → Protection → Email memory. Details in Privacy and retention.
Sender authentication: has_spf and has_dmarc
Whether the domain publishes SPF and DMARC records.
nullmeans not known yet, not "no". The first check of a new domain returnsnulland a later one has the answer.- They describe whether a domain can be spoofed as a sender, which is a different question from whether a signup is real.
- Real businesses and disposable providers publish SPF at about the same rate, so
has_spfon its own tells you little. - Do not reject on missing records. Plenty of legitimate small businesses have never set up DMARC.
- Both are data only and never change
action. They are most useful as corroboration alongside other signals.