api reference

Response fields

Every field in a /v1/check response: category, recommendation, confidence, flags, mail, workspace, integrations, reasons, degraded and more.

View as Markdown

This is the full response for a secret key. Publishable keys get a reduced subset.

{ "email": "jane+news@acme.io", "normalized_email": "jane@acme.io", "domain": "acme.io",
  "is_business": true, "category": "business", "confidence": 0.96, "recommendation": "allow",
  "is_free_provider": false, "is_disposable": false, "is_relay": false, "is_role_account": false,
  "shared_inbox": { "confidence": 0, "match": null }, "group": { "confidence": 0, "match": null },
  "is_blocked": false, "is_new_domain": false, "is_lookalike": false, "has_subaddress": true, "did_you_mean": null,
  "mail": { "has_mx": true, "provider": "google_workspace", "mx": [{ "priority": 1, "host": "smtp.google.com" }],
            "spf": "v=spf1 include:_spf.google.com ~all", "dmarc_policy": "reject" },
  "workspace": { "google_workspace": { "detected": true, "evidence": ["mx_google","dkim_google"] },
                 "microsoft_365": { "detected": false, "tenant_id": null, "auth": null, "identity_provider": null, "evidence": [] },
                 "other_suite": null, "pending": false },
  "integrations": { "google_workspace_ready": true, "microsoft_365_ready": false },
  "domain_age_days": null, "reasons": ["mx_google_workspace","dmarc_reject","txt_saas_tokens:3"],
  "degraded": false, "cached": false, "took_ms": 38, "request_id": "req_…" }

Input and identity

Field Type Meaning
email string | null The address you sent, trimmed. null for domain and URL checks.
url string Only for URL checks: the website address you sent. Its host (without www.) is domain.
normalized_email string | null Lowercased, Unicode-normalized, IDN domain in punycode, +tag removed. Use it to de-duplicate signups. null for domain checks.
domain string The domain part, normalized. Lookups use its registrable domain (mail.acme.co.uk → acme.co.uk).

Verdict

Field Type Meaning
category string One of business, personal, disposable, relay, education, government, invalid, unknown. See Categories and policies.
is_business boolean true for business, education and government. The simple yes/no.
recommendation string allow, review or block, for the policy you requested (b2b by default).
confidence number 0 to 1. How sure the engine is about category. List matches are near 1; custom domains are scored from DNS signals. Below a threshold the category becomes unknown.
reasons string[] Machine-readable reason codes, strongest first. Some carry a count suffix, e.g. txt_saas_tokens:3. See Reason codes.

Flags

Field Type true when…
is_free_provider boolean The domain is a shared-domain provider: one domain, many unrelated people (gmail.com, outlook.com, yahoo.com, gmx.de, icloud.com, ISP domains…). Paid consumer services count too: “free” means “not the company’s own domain”.
is_disposable boolean Throwaway inbox service, or a domain whose mail servers serve known disposable domains
is_relay boolean Privacy relay that forwards to a hidden inbox (Apple Hide My Email, Firefox Relay, DuckDuckGo, SimpleLogin, addy.io)
is_role_account boolean The local part is a role, not a person: info@, sales@, support@, noreply@…
shared_inbox object Hint that the address is a shared inbox: one mailbox several people answer from (a Microsoft 365 shared mailbox, a Google collaborative inbox, a helpdesk address) such as support@, billing@ or sales-eu@. confidence is 0.3 (low) on a name match and 0 otherwise; match is the word that matched. See shared inboxes and groups.
group object Hint that the address is a group that forwards to many members (a Google Group, a Microsoft 365 group or distribution list) such as team@, all@ or berlin-team@. 0.3 (low) on a name match, 1 for @googlegroups.com, 0 otherwise. Neither hint changes recommendation.
is_blocked boolean The domain, or (for secret keys) the exact address, is on our blocklist built from spam and abuse reports
is_new_domain boolean Registered less than 30 days ago. Only known with deep=true or when we have already enriched the domain.
is_lookalike boolean The domain imitates a popular provider with confusable characters or punycode
has_subaddress boolean The address has a +tag (jane+news@)
did_you_mean string | null A suggested correction when the domain looks like a typo of a popular provider (for example, for gmial.com). Show it to the user; don’t silently replace their input.

mail

Field Type Meaning
mail.has_mx boolean The domain can receive mail (MX records, not a null MX)
mail.provider string | null Short identifier of who hosts the mailboxes, from MX and other DNS records, e.g. google_workspace. Treat it as an open set; new values can appear. null when unknown.
mail.mx array MX records, {priority, host}, lowest priority first
mail.spf string | null The domain’s SPF record, or null if it publishes none
mail.dmarc_policy string | null Published DMARC policy: reject, quarantine, none, or null if there’s no DMARC record

workspace

Detection runs per company domain. Details in Workspace detection.

Field Type Meaning
workspace.google_workspace.detected boolean The domain’s mail or DNS shows Google Workspace
workspace.google_workspace.evidence string[] Short evidence tags, e.g. mx_google, dkim_google
workspace.microsoft_365.detected boolean The domain belongs to a Microsoft Entra ID tenant (Microsoft 365)
workspace.microsoft_365.tenant_id string | null The tenant’s GUID, from Microsoft’s public OpenID discovery document
workspace.microsoft_365.tenant_region string | null Tenant region scope reported by Microsoft (e.g. EU, NA, WW), when detected
workspace.microsoft_365.auth string | null managed (passwords in Entra ID) or federated (sign-in redirected to another identity provider)
workspace.microsoft_365.identity_provider string | null For federated tenants, the identity provider we recognized (Okta, ADFS, Ping…)
workspace.microsoft_365.evidence string[] Evidence tags for the Microsoft detection
workspace.other_suite string | null Another hosted suite seen in MX: Zoho, Proton, Fastmail, Yandex 360… null if none
workspace.pending boolean true when the Microsoft tenant lookup didn’t finish within its 0.7 s budget and continues in the background. Check again later for the full result.

Google Workspace and Microsoft 365 can both be true: a company might sign in with Entra ID but keep mail on Google, or be mid-migration.

integrations

Field Type Meaning
integrations.google_workspace_ready boolean The company has a Google Workspace tenant, so admin-level Google integrations (Admin SDK, domain-wide delegation, Shared Drives) are possible
integrations.microsoft_365_ready boolean The company has a Microsoft 365 / Entra ID tenant, so Graph admin consent, SharePoint, OneDrive for Business and Teams integrations are possible

“Ready” means the tenant exists. It doesn’t mean this person is an admin, or that their admin will consent.

Enrichment

Field Type Meaning
domain_age_days number | null Days since the domain was registered, from RDAP. Filled with deep=true (or when we already have it); otherwise null.

Operational

Field Type Meaning
degraded boolean DNS lookups failed or timed out; the answer comes from our lists only and confidence is lower. Consider treating review as allow and re-checking later.
cached boolean Served from cache
took_ms number Server-side processing time in milliseconds
request_id string Unique ID for this request. Include it when you contact support.

Reduced response (publishable keys)

Publishable keys receive category, is_business, recommendation, confidence, did_you_mean, the top reasons and workspace.google_workspace / workspace.microsoft_365 as detected-or-not. They never receive is_blocked, mail, tenant details or deep enrichment.

Compatibility

Within /v1 we only make additive changes: new fields, new reasons codes, new mail.provider and other_suite values. Ignore fields you don’t know and treat unknown reason codes as informational. See Versioning and deprecation.

Shared inboxes and groups

Two kinds of address are read by more than one person, and they behave differently:

  • A shared inbox is one mailbox several people answer from: a Microsoft 365 shared mailbox, a Google collaborative inbox, a helpdesk address. Typical names: support@, info@, billing@, orders@.
  • A group forwards each message to many members: a Google Group, a Microsoft 365 group or a distribution list. Typical names: team@, all@, everyone@, engineering@.

On a company’s own domain both have exactly the same DNS and mail servers as a person’s mailbox. The only way to know for sure would be to ask Google or Microsoft about that address, which is account probing, and we never do it. So each hint uses the one piece of evidence there is, the name, and has its own confidence:

confidence When Examples
1 group only: the domain is googlegroups.com, where every address is a Google Group book-club@googlegroups.com
0.3 (low) The local part is, starts with or ends with a word from that hint’s list shared inbox: support@, support2@, eu.support@; group: team@, berlin-team@, all-staff@
0 No sign, or not a custom domain jane.doe@, anything at gmail.com

Some names are commonly either, such as sales@ and projects@; they get a low score on both. Plenty of people own a mailbox called projects@ or sales@, so treat a low match as a hint: route it to a team queue or ask for a named contact, but don’t block on it. Role names such as info@ and support@ also set is_role_account, which is what the b2b and strict policies act on.