---
title: "Check a domain's DMARC record"
method: GET
path: "/api/v1/tools/dmarc"
tags: ["Free DNS tools"]
---

# Check a domain's DMARC record

`GET /api/v1/tools/dmarc`

## Request

- Base URL: `https://email-spam-tester.com` (the document declares no server; this is the origin it was published from)
- URL: `https://email-spam-tester.com/api/v1/tools/dmarc`
- Auth: none declared

Fetches _dmarc.<domain>, falling back to the organizational domain as receivers do (RFC 7489 §6.6.3), and validates every tag. Reports the policy that applies, pct, alignment modes, and whether each external rua/ruf destination has published the authorization record receivers require before sending reports there (RFC 7489 §7.1).

Free, no key. Limited to 30 requests a minute and 300 a day per client IP across all four tools; identical queries are answered from a 60-second cache. Any completed check is 200, including "no record" and "lookup failed"; `status` and `findings` carry the verdict. Each finding has a stable `code`, a `level` and `params`; `message` is the English sentence built from them.

## Query parameters

- `domain` string, nullable: Domain, e.g. example.com.

## Response `200`

Successful Response

- DmarcOut
  - `tool` string, required
  - `query` object, required: The inputs after normalisation.
  - `checked_at` string, required: When the lookups ran, ISO 8601 UTC.
  - `duration_ms` integer, required
  - `status` 'pass' | 'warn' | 'fail' | 'error', required: Overall verdict. "error" means the check could not complete (timeout, SERVFAIL); it is never "pass" when a lookup the verdict needs failed.
  - `findings` Finding[], required
    - `code` string, required: Stable identifier, e.g. spf.too_many_lookups. The English template for every code is in /i18n/tools/findings.en.json on the website.
    - `level` 'pass' | 'info' | 'warn' | 'fail' | 'error', required
    - `params` object, required: Values the message is built from.
    - `message` string, required: The English sentence, params filled in.
  - `name` string, required
  - `found_at` string, nullable, required: Domain whose _dmarc record applies; the organizational domain when the exact name has none (RFC 7489 §6.6.3).
  - `record` string, nullable, required
  - `tags` DmarcTags, required
    - `v` string, nullable
    - `p` string, nullable
    - `sp` string, nullable
    - `np` string, nullable
    - `pct` string, nullable
    - `adkim` string, nullable
    - `aspf` string, nullable
    - `rua` string[], nullable
    - `ruf` string[], nullable
    - `fo` string, nullable
    - `ri` string, nullable
    - `rf` string, nullable
  - `policy` 'none' | 'quarantine' | 'reject', nullable, required: The policy that applies to the domain asked about: sp= when the record was inherited and has one, p= otherwise.

## Other responses

- `422`: The input is not something we can look up (detail.code says which).
- `429`: Too many requests from this address; Retry-After says when to come back.

---

[API](https://skmtc.dev/email-spam-tester/apis/email-spam-tester-api.md) · [All operations](https://skmtc.dev/email-spam-tester/apis/email-spam-tester-api/llms.txt) · [OpenAPI document](https://skmtc.dev/email-spam-tester/apis/email-spam-tester-api/revisions/476a4c86600d?raw)
