Does My Email Work - API & Agent Docs

Does My Email Work is a free email deliverability scanner. It checks a domain's SPF, DKIM, DMARC, and MX records using public DNS and returns plain-English results. Everything below is available without signup, authentication, or stored state.

When to use this

If you are an AI agent, call the scan_domain tool (or GET /api/v1/dns-scan/{domain}) when a user wants to know:

The scan is read-only. It only queries public DNS, sends no email, and changes nothing. It is safe to call without asking the user for confirmation.

Rate limit: 10 domains per hour per IP. Honor the RateLimit-Remaining and RateLimit-Reset headers and back off when you hit 429. See /status for retry guidance.

Quickstart

Agents: Prefer the MCP scan_domain tool below. Some HTTP fetchers only allow URLs seen verbatim in prior results and cannot fetch a freshly constructed ?domain=client.com URL. If that applies to you, use MCP, POST /api/v1/scan, or ask the user to paste the scan URL. Always verify the response domain field matches what you intended.

MCP (preferred for agents)

Point your MCP client at the Streamable HTTP endpoint below, then call the scan_domain tool. No API key is required.

Endpoint: https://doesmyemail.work/mcp
Transport: Streamable HTTP
Tool:     scan_domain
Argument: { "domain": "their-domain.com" }

curl (sandbox example)

curl "https://doesmyemail.work/api/v1/dns-scan/sandbox.doesmyemail.work"

The domain goes in the path (preferred). The query-string form ?domain= is also supported, but some HTTP caches discard query strings and can return another domain's cached result.

JavaScript (fetch)

const domain = "their-domain.com";
const res = await fetch(
  `https://doesmyemail.work/api/v1/dns-scan/${encodeURIComponent(domain)}`
);
const data = await res.json();

if (data.domain !== domain) throw new Error(`Wrong domain in response: ${data.domain}`);
console.log(data.spf.found, data.dkim.found, data.dmarc.enforced);

Authentication

None. All endpoints are public and require no API key, token, or signup. The only constraint is rate limiting, currently 10 domains per hour per IP, applied across the DNS scan and batch endpoints.

Machine-readable auth details for agents live at /auth.md.

API reference

Base URL: https://doesmyemail.work. A safe test domain that always returns a deterministic sample response is sandbox.doesmyemail.work - use it to exercise your integration without consuming rate limit against real lookups.

GET /api/v1/dns-scan/{domain}

Scans a single domain and returns its email authentication status. The domain goes in the path (preferred URL style; survives caches that discard query strings). The query-string form GET /api/v1/dns-scan?domain={domain} behaves identically and remains supported.

Parameters

Caching note for agents: your HTTP client may cache results for several minutes. After a DNS fix, a re-scan can show the old state; allow a few minutes or use the MCP tool, which is not subject to URL caching.

Example 200 response

{
  "domain": "sandbox.doesmyemail.work",
  "spf": {
    "found": true,
    "value": "v=spf1 include:_spf.google.com ~all",
    "lookups": 1,
    "issues": [],
    "mechanisms": ["include:_spf.google.com", "~all"]
  },
  "dkim": {
    "found": true,
    "selector": "default"
  },
  "dmarc": {
    "found": true,
    "enforced": true,
    "value": "v=DMARC1; p=reject; rua=mailto:dmarc@sandbox.doesmyemail.work"
  },
  "mx": {
    "found": true,
    "null_mx": false,
    "receives_mail": true,
    "records": ["aspmx.l.google.com", "alt1.aspmx.l.google.com"],
    "provider": "Google Workspace / Gmail"
  },
  "cloudflare": true,
  "nameservers": ["lola.ns.cloudflare.com", "rex.ns.cloudflare.com"],
  "provider": "Cloudflare"
}

Error codes

Rate-limit headers (returned on every response)

POST /api/v1/scan

Scans multiple domains in one request. Send a JSON body with a domains array. The response is paginated for large batches.

Request

POST /api/v1/scan
Content-Type: application/json

{
  "domains": ["client-a.com", "client-b.com"]
}

Response

{
  "results": [
    { "domain": "client-a.com", "result": { "domain": "client-a.com", "spf": { "found": true }, "...": "..." } }
  ],
  "page": 1,
  "pageSize": 50,
  "total": 3,
  "nextPage": null
}

Each domain in the batch counts toward your rate limit.

POST /ask

A natural-language endpoint (NLWeb). Send a question in plain English and get a structured answer about a domain's deliverability. Useful when you want the service to interpret the intent rather than parse fields yourself.

POST /ask
Content-Type: application/json

{
  "query": "Why does email from their-domain.com go to spam?"
}

MCP server

The Model Context Protocol server lets agents call the scanner as a native tool over Streamable HTTP.

Resources