api reference
Response fields
Every field in a /v1/check response: category, recommendation, confidence, flags, mail, workspace, integrations, reasons, degraded and more.
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.