# Domain Email Health API

> MX, SPF, DKIM, DMARC, MTA-STS, TLS-RPT, BIMI and disposable-domain checks with a score.

Audits everything a receiving mail server looks at before trusting mail from a domain: MX records and their reachability, SPF syntax and the ten-lookup limit, DKIM keys under common or supplied selectors with key sizes, DMARC policy and reporting, MTA-STS and TLS-RPT, BIMI, and whether the domain is a known disposable or free provider. Returns a 0 to 100 score, a letter grade and a findings list with codes and severities.

- **Endpoint:** `GET https://api.zactonz.com/email/domain/`
- **Category:** Email
- **Version:** 1
- **Status:** stable
- **Authentication:** `Authorization: Bearer YOUR_API_KEY`
- **Reference page:** https://developers.zactonz.com/apis/email-domain/

## Parameters

Send parameters in the query string.

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `domain` | string | yes |  | Domain to audit. An email address is accepted and reduced to its domain. |
| `selectors` | string | no |  | Comma-separated DKIM selectors to check in addition to the common ones, up to 20. |
| `probe` | boolean | no | `false` | `1` connects to the primary MX to read its banner and STARTTLS support. |

## Example request

```bash
curl "https://api.zactonz.com/email/domain/?domain=zactonz.com&selectors=google%2Cmail&probe=" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Response

OK

| Field | Type | Description |
|---|---|---|
| `status` | integer | `200` on success. |
| `data` | object | The result. |
| `data.domain` | string | Domain audited. |
| `data.score` | integer | 0 to 100. |
| `data.grade` | string | A to F. |
| `data.disposable` | boolean | Known disposable-address provider. |
| `data.free_provider` | boolean | Consumer webmail provider. |
| `data.mx` | array of object | MX hosts with `priority`, `exchange`, `addresses` and, with `probe=1`, `smtp` (`reachable`, `banner`, `starttls`). |
| `data.spf` | object | `present`, `record`, `valid`, `all` qualifier, DNS `lookups`, `mechanisms`. |
| `data.dkim` | array of object | Keys found: `selector`, `key_type`, `key_bits`, `revoked`, `testing`. |
| `data.dmarc` | object | `present`, `record`, `policy`, `subdomain_policy`, `pct`, `rua`, `ruf`, `adkim`, `aspf`. |
| `data.mta_sts` | object | `present`, `record`, fetched `policy`. |
| `data.tls_rpt` | object | `present`, `record`. |
| `data.bimi` | object | `present`, `record`. |
| `data.findings` | array of object | Each with `code`, `severity` (`critical`, `warning`, `info`) and `message`. |
| `data.checked_selectors` | array of string | Selectors that were queried. |
| `data.checked_at` | string | Timestamp. |

```json
{
    "status": 200,
    "data": {
        "domain": "zactonz.com",
        "score": 100,
        "grade": "A",
        "disposable": false,
        "free_provider": false,
        "mx": [
            {
                "priority": 0,
                "exchange": "mail.zactonz.com",
                "addresses": [
                    "67.43.236.62"
                ]
            }
        ],
        "spf": {
            "present": true,
            "record": "v=spf1 +a +mx +ip4:67.43.236.62 ~all",
            "valid": true,
            "all": "~all",
            "lookups": 2,
            "mechanisms": [
                "+a",
                "+mx",
                "+ip4:67.43.236.62"
            ]
        },
        "dkim": [
            {
                "selector": "default",
                "key_type": "rsa",
                "key_bits": 2048,
                "revoked": false,
                "testing": false
            }
        ],
        "dmarc": {
            "present": true,
            "record": "v=DMARC1; p=reject; rua=mailto:dmarc@zactonz.com",
            "policy": "reject",
            "subdomain_policy": "reject",
            "pct": 100,
            "rua": [
                "dmarc@zactonz.com"
            ],
            "ruf": [],
            "adkim": "r",
            "aspf": "r"
        },
        "mta_sts": {
            "present": false,
            "record": null,
            "policy": null
        },
        "tls_rpt": {
            "present": false,
            "record": null
        },
        "bimi": {
            "present": false,
            "record": null
        },
        "findings": [
            {
                "code": "mx.single",
                "severity": "info",
                "message": "Only one MX host; a second one adds resilience."
            },
            {
                "code": "mta_sts.missing",
                "severity": "info",
                "message": "No MTA-STS. Inbound TLS is opportunistic only."
            }
        ],
        "checked_selectors": [
            "default",
            "google",
            "selector1",
            "selector2"
        ],
        "checked_at": "2026-09-17T14:05:40+00:00"
    }
}
```

## Status codes

The outcome is reported in the JSON `status` field. General rules: https://developers.zactonz.com/apis/errors.md

| status | Meaning | Description |
|---|---|---|
| `400` | Bad request | `domain` is missing or not a domain name. |
| `401` | Unauthorized | The Authorization header is missing or the key is not recognised. |
| `403` | Forbidden | The key is not licensed for this product. |
| `429` | Too many requests | The per-minute rate or the plan quota is exhausted. Retry after the seconds given in `Retry-After`. |

## Notes

Complements Mail Verifier, which checks individual mailboxes. Answers are cached for ten minutes. `probe=1` connects to the primary MX on port 25 to read the banner and STARTTLS support.
