api reference

Check an email, domain or website

GET and POST /v1/check: check one email address, domain or website URL, choose a policy, request deep enrichment, and read the full response.

View as Markdown

POST https://api.isbusinessemail.com/v1/check
GET  https://api.isbusinessemail.com/v1/check?email=…
GET  https://api.isbusinessemail.com/v1/check?domain=…
GET  https://api.isbusinessemail.com/v1/check?url=…

Checks one email address, one domain or one website URL. POST is recommended: with GET the address ends up in URLs, which tend to be logged by proxies, load balancers and browsers.

Request

POST body

{ "email": "jane+news@acme.io" }

or

{ "domain": "acme.io" }

or a website address:

{ "url": "https://www.acme.io/pricing" }

Send exactly one of email, domain or url, with Content-Type: application/json.

Website URLs

For url, only the host counts: https://www.acme.io/pricing, acme.io/about and //acme.io all check acme.io (a leading www. is dropped; other subdomains are kept). Only http and https are accepted; IP addresses are not. The response is the same as for a domain check, plus url with the address as you sent it, and email is null. Use it to qualify a lead’s company website, or to compare a signup’s website with their email domain.

Options

Options can be sent as query parameters on either method (?policy=strict&deep=true) or as fields in the POST body.

Option Values Default Effect
policy b2b, strict, lenient b2b Which categories map to allow, review and block. See Categories and policies.
deep true, false false Adds domain age (RDAP) and a homepage check. Secret keys only. Counts as 5 checks; at most 1,000 deep checks a day.
workspace true, false true false skips the Microsoft tenant lookup, the slowest part of a check. Use it when you only need the category: Microsoft 365 is still detected from MX, SPF and autodiscover, but tenant_id, auth and identity_provider stay null.
{ "email": "jane@acme.io", "policy": "strict", "deep": true }

Input limits

  • Email ≤ 254 characters, local part ≤ 64, domain ≤ 253, URL ≤ 2,048.
  • Control characters and wildcards are rejected.
  • International domains are accepted and converted to punycode.

A request that isn’t well-formed (missing input, both email and domain, wrong types, over the length limits) returns 400 invalid_input. A well-formed request for an address that isn’t valid returns 200 with category: "invalid" and a reason such as invalid_syntax or no_mx. That way you can treat “bad address” as a verdict, not an exception.

Response

{ "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_…" }

Every field is described in Response fields. The short version:

  • recommendation is what to do under your policy.
  • category is what the address is.
  • reasons explains why. Codes are listed in Reason codes.
  • workspace and integrations tell you whether Google Workspace or Microsoft 365 integrations can work for this company.

Response headers

Header Meaning
RateLimit-Policy, RateLimit Standardized rate-limit fields (IETF HTTPAPI draft)
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset The same information in the widely used legacy format
Retry-After On 429 and 503: seconds to wait before retrying
Cache-Control: private, max-age=300, ETag On GET responses

See Rate limits.

Checking a domain instead of an address

curl -s https://api.isbusinessemail.com/v1/check \
  -H "Authorization: Bearer $IBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"acme.io"}'

Domain checks return the same shape. Address-specific fields (normalized_email, is_role_account, shared_inbox, group, has_subaddress, is_blocked for exact addresses) don’t apply and are null, false or 0. Use domain checks for CRM enrichment and sales routing where you only have a company domain.

Timing and caching

  • Results for a domain are cached at the edge, so repeat checks are fast and cached: true.
  • DNS lookups use a 1.5 s budget. The Microsoft tenant lookup gets 0.7 s; if it hasn’t answered by then, the response returns with workspace.pending: true and the lookup completes in the background, so the next check of that domain returns the full result.
  • If DNS fails entirely, you still get an answer from our lists, with degraded: true and lower confidence.

Use a client timeout of about 2–3 seconds and fail open.

Examples

GET with a domain

curl -s "https://api.isbusinessemail.com/v1/check?domain=acme.io" \
  -H "Authorization: Bearer $IBE_API_KEY"

Strict policy with deep enrichment

curl -s "https://api.isbusinessemail.com/v1/check?policy=strict&deep=true" \
  -H "Authorization: Bearer $IBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@acme.io"}'

More languages: Code examples. Many addresses at once: Batch.