# Email Deliverability & DNS Health API — check SPF, DKIM, DMARC, MX, BIMI, MTA-STS, TLS-RPT, DNSSEC, DANE and blacklist status with a 0-100 deliverability score

> Full email-health audit: SPF + DKIM + DMARC + MX + BIMI + MTA-STS + TLS-RPT + DNSSEC + blacklist, plus a 0-100 deliverability score and letter grade.
> ReefAPI engine `email-health` · 12 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/email-health/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed or blocked calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /email-health/v1/check — 1 credit
Full email-health audit: SPF + DKIM + DMARC + MX + BIMI + MTA-STS + TLS-RPT + DNSSEC + blacklist, plus a 0-100 deliverability score and letter grade.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).
- `selector` (string, optional) — DKIM selector (the label before ._domainkey, e.g. 'google', 'selector1', 'k1'). Omit to autoscan ~30 common ESP selectors. DKIM selectors are provider-specific — pass the exact one if you know it.
- `selectors` (array, optional) — Optional comma-separated list (or array) of DKIM selectors to test instead of the common-selector autoscan.
- `bimi_selector` (string, optional, default "default") — BIMI selector (default per the BIMI spec is 'default').
- `skip_blacklist` (boolean, optional, default false) — If true, skip the DNSBL reputation lookups in 'check' (faster; blacklist is the slowest section — many IP×zone DoH queries).

**Returns:** domain, score{score,grade,breakdown}, spf{}, dkim{}, dmarc{}, mx{}, bimi{}, mta_sts{}, tls_rpt{}, dnssec{}, dane{} (informational, unscored), blacklist{}, issues[] (merged), summary{}

**Example request body:**
```json
{
  "domain": "google.com"
}
```

### POST /email-health/v1/spf — 1 credit
Parse + validate the SPF record: follow include:/redirect=, count the ≤10 DNS-lookup mechanisms, flag +all and void lookups, report the all-qualifier policy.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).

**Returns:** domain, found, record, valid, dns_lookups, void_lookups, all_qualifier, policy, mechanisms[], includes[], include_tree[], issues[]

**Example request body:**
```json
{
  "domain": "google.com"
}
```

### POST /email-health/v1/dmarc — 1 credit
Parse the DMARC policy at _dmarc.<domain>: p/sp/pct/rua/ruf/adkim/aspf/fo + enforcement verdict.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).

**Returns:** domain, found, record, valid, policy, subdomain_policy, pct, rua[], ruf[], adkim, aspf, fo, enforced, tags{}, issues[]

**Example request body:**
```json
{
  "domain": "paypal.com"
}
```

### POST /email-health/v1/dkim — 1 credit
DKIM selector lookup (<selector>._domainkey.<domain>): key type, public-key presence, RSA key-bit estimate, revocation. Autoscans ~30 common selectors if none given.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).
- `selector` (string, optional) — DKIM selector (the label before ._domainkey, e.g. 'google', 'selector1', 'k1'). Omit to autoscan ~30 common ESP selectors. DKIM selectors are provider-specific — pass the exact one if you know it.
- `selectors` (array, optional) — Optional comma-separated list (or array) of DKIM selectors to test instead of the common-selector autoscan.

**Returns:** domain, found, selectors_tested[], selectors_found[], records[] (selector, record, key_type, key_bits, public_key_present, revoked), issues[]

**Example request body:**
```json
{
  "domain": "paypal.com",
  "selector": "pp2"
}
```

### POST /email-health/v1/mx — 1 credit
MX records (sorted by preference) + a mail-provider guess from the exchange hostnames.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).

**Returns:** domain, found, count, records[] (preference, exchange), hosts[], provider, issues[]

**Example request body:**
```json
{
  "domain": "github.com"
}
```

### POST /email-health/v1/blacklist — 1 credit
DNSBL reputation: reverse the domain's A + MX-host IPs against live-proven public DNSBLs (SpamCop, Barracuda, UCEPROTECT, PSBL, Mailspike, GBUdb, DroneBL, s5h). Spamhaus/CBL are flagged as paid-key-required (public-resolver refused), not queried.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).
- `ips` (array, optional) — Optional explicit IPv4 list (comma-separated or array) to check against the DNSBLs. Omit to auto-resolve the domain's A + MX-host IPs.

**Returns:** domain, checked_ips[], ptr_records{ip:hostname}, listings[] (ip, zone, blacklist, return_codes), listed_count, clean, zones_checked[], paid_key_zones[], issues[]

**Example request body:**
```json
{
  "domain": "github.com"
}
```

### POST /email-health/v1/mta_sts — 1 credit
MTA-STS: the _mta-sts.<domain> TXT (id) plus the fetched https://mta-sts.<domain>/.well-known/mta-sts.txt policy (mode, mx[], max_age).

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).

**Returns:** domain, found, record, id, policy_fetched, mode, mx[], max_age, enforced, issues[]

**Example request body:**
```json
{
  "domain": "google.com"
}
```

### POST /email-health/v1/bimi — 1 credit
BIMI brand-logo record at <selector>._bimi.<domain>: the published logo (SVG) URL and the VMC (Verified Mark Certificate) URL, plus whether a VMC is present. Standalone lookup (MXToolbox SuperTool exposes BIMI on its own — no full audit needed).

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).
- `selector` (string, optional, default "default") — BIMI selector — the label before ._bimi (default per the BIMI spec is 'default'; large senders sometimes publish per-brand selectors).

**Returns:** domain, found, record, selector, logo_url, vmc_url, has_vmc

**Example request body:**
```json
{
  "domain": "cnn.com"
}
```

### POST /email-health/v1/tls_rpt — 1 credit
SMTP TLS Reporting (RFC 8460) record at _smtp._tls.<domain>: the rua= report destination(s) that receive aggregate TLS-negotiation failure reports. Standalone lookup.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).

**Returns:** domain, found, record, rua[]

**Example request body:**
```json
{
  "domain": "google.com"
}
```

### POST /email-health/v1/dnssec — 1 credit
DNSSEC signing status: the DoH AD (Authenticated-Data) flag = the resolver cryptographically validated the answer, plus a DS record at the parent = the delegation is signed. Standalone lookup.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).

**Returns:** domain, signed, validated_ad_flag, has_ds_record

**Example request body:**
```json
{
  "domain": "cloudflare.com"
}
```

### POST /email-health/v1/dane — 1 credit
DANE for SMTP (RFC 7672): TLSA records at _25._tcp.<mx-host> for every MX host, with per-host DNSSEC validation (DANE is only effective on a signed TLSA RRset). Value-add: MXToolbox has NO TLSA/DANE lookup.

**Parameters:**
- `domain` (string, required) — The domain to inspect (a bare host like github.com; a full URL, a leading www., or a full email address are accepted and normalized to the registrable domain).

**Returns:** domain, found, mx_hosts_checked[], hosts[] (mx_host, found, records[] (usage, usage_label, selector, matching_type, association_data), dnssec_validated), record_count, issues[]

**Example request body:**
```json
{
  "domain": "internet.nl"
}
```

### POST /email-health/v1/batch — 1 credit
Run the full 'check' audit on up to 25 domains in one call (each with score + grade).

**Parameters:**
- `domains` (array, required) — Comma-separated list (or array) of up to 25 domains to run a full health check on in one call.
- `skip_blacklist` (boolean, optional, default false) — If true, skip the DNSBL reputation lookups in 'check' (faster; blacklist is the slowest section — many IP×zone DoH queries).

**Returns:** results[] (domain, score, grade, found-summary), count, average_score

## More
- Try it live, no code: https://reefapi.com/playground?engine=email-health
- Human docs page: https://reefapi.com/docs/email-health
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
