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:

Decision example
{
  "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:

ValueThe action was driven by
DOMAIN_NEWLY_REGISTEREDYour new-domain rule.
INFRASTRUCTURE_ZONEYour free and dynamic-DNS rule.
DOMAIN_UNDELIVERABLEYour undeliverable-domain rule.
DISPOSABLEA known disposable or temporary email provider.
NO_MXThe domain has no mail servers.
DOMAIN_TYPO_SUGGESTEDThe domain looks like a misspelling of a known provider.
SUSPICIOUSThe address looks like generated junk or a test address.
ROLE_BASEDA shared address such as info@, admin@, or support@.
PRIVACY_RELAYA privacy or alias relay that forwards to another inbox.
PUBLIC_PROVIDERA public provider such as Gmail or Yahoo.
OKNothing. 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.

SignalExampleWhat it tells you
disposablename@tempmail.comThe domain is a known temporary email provider.
public_providername@gmail.comThe address uses a public provider. This is not bad by itself.
role_basedsupport@company.comThe address looks shared by a team or function.
suspiciousA strong junk-like patternThe address needs more confidence before valuable access.
privacy_relayA known relay domainThe service forwards mail to another inbox.
has_mxtrueMail server records were found for the domain.
suggested_domaingmail.comThe entered domain may contain a typo.
normalized_emailfoobar@gmail.comThe canonical form after provider alias rules (see below).
previously_checkedtrueYour account already checked this same underlying address.
has_spftrueThe domain publishes an SPF record. Read the caveats below.
has_dmarcfalseThe 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, true usually 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.

  • null means not known yet, not "no". The first check of a new domain returns null and 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_spf on 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.