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

# Check a domain's SPF record

`GET /api/v1/tools/spf`

## 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/spf`
- Auth: none declared

Fetches the domain's SPF record and checks its syntax (RFC 7208), its policy for unlisted servers, and what a full evaluation costs: every include and redirect is followed, DNS-querying terms are counted against the limit of 10, and lookups that return nothing against the void limit of 2 (RFC 7208 §4.6.4). `tree` is the include tree with per-record costs. No sending IP is involved, so this says whether the record can be evaluated, not whether a given server passes.

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. A pasted URL or email address is accepted.

## Response `200`

Successful Response

- SpfOut
  - `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.
  - `record` string, nullable, required
  - `records` string[], required: Every v=spf1 record found; more than one is a permerror.
  - `terms` SpfTerm[], required
    - `qualifier` string, nullable, required: +, -, ~ or ?; null for a modifier.
    - `mechanism` string, required: Mechanism or modifier name, lowercased.
    - `value` string, nullable, required
    - `lookups` integer, required: DNS lookups this term costs, its include subtree included.
  - `lookups` SpfLookups, required
    - `count` integer, required
    - `limit` integer, required
    - `void` integer, required
  - `tree` SpfNode, required
    - `domain` string, required
    - `record` string, nullable, required
    - `lookups` integer, required: Lookups this record and everything below it cost.
    - `error` string, nullable, required
    - `children` SpfNode[], required

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