# 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.

Source: https://isbusinessemail.com/docs/check-endpoint

```text
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

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

or

```json
{ "domain": "acme.io" }
```

or a website address:

```json
{ "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](https://isbusinessemail.com/docs/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`. |

```json
{ "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

```json
{ "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](https://isbusinessemail.com/docs/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](https://isbusinessemail.com/docs/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](https://isbusinessemail.com/docs/rate-limits).

## Checking a domain instead of an address

```bash
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](https://isbusinessemail.com/docs/signup-form-guide#fail-open).

## Examples

### GET with a domain

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

### Strict policy with deep enrichment

```bash
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](https://isbusinessemail.com/docs/code-examples). Many addresses at once: [Batch](https://isbusinessemail.com/docs/batch-endpoint).
