For developers
API
Every dns-doctor.com check and tool is also available as a JSON API: free, CORS-enabled (Access-Control-Allow-Origin: *, including POST and the Authorization header) and usable without signup. Check results are cached server-side for 5 minutes.
Domain check
GET/api/v1/check/{domain}?lang=en|de
Complete health report for a domain: a score from 0 to 100 and findings in the categories dns, email, web and security, each with a severity (ok, info, warn, problem), an explanation and, where possible, a concrete fix including the DNS record. The lang parameter selects the language of all texts (default: en). Errors: 400 invalid_domain, 429 rate_limited.
curl 'https://dns-doctor.com/api/v1/check/example.com?lang=en'
{
"api": "v1",
"domain": "example.com",
"displayDomain": "example.com",
"resolvable": true,
"score": 92,
"findings": [
{
"id": "email-spf-missing",
"category": "email",
"severity": "problem",
"title": "No SPF record found",
"detail": "Without SPF, any server may send mail as example.com.",
"fix": {
"steps": ["Create this TXT record for your domain."],
"record": {"host": "@", "type": "TXT", "value": "v=spf1 mx ~all"}
}
}
],
"summary": {"ok": 12, "info": 2, "warn": 1, "problem": 1},
"checkedAt": "2026-07-15T09:30:00.000Z",
"locale": "en"
}DNS lookup
GET/api/v1/lookup/{name}/{type}
Raw records via DNSSEC-validating resolvers. Supported types: A, NS, CNAME, SOA, PTR, MX, TXT, AAAA, SRV, DS, DNSKEY and CAA. For PTR, name may also be an IP address; the arpa mapping happens automatically. status is the DNS RCODE (0 = NOERROR, 3 = NXDOMAIN), ad tells you whether the answer is DNSSEC-validated. Errors: 400, 429, 502.
curl https://dns-doctor.com/api/v1/lookup/example.com/MX
{
"api": "v1",
"name": "example.com",
"type": "MX",
"typeCode": 15,
"status": 0,
"ad": true,
"answers": [
{"name": "example.com", "type": 15, "ttl": 3600, "data": "10 mail.example.com."}
]
}Propagation
GET/api/v1/propagation/{name}/{type}
Queries the same name and type on five public resolvers (cloudflare, google, alidns, dnssb, adguard) and compares the answers. consistency shows how many reachable resolvers agree; consistent is true once all reachable resolvers return the same answer set. Handy after record changes to watch propagation. Errors: 400, 429.
curl https://dns-doctor.com/api/v1/propagation/regfish.de/A
{
"api": "v1",
"name": "regfish.de",
"type": "A",
"resolvers": [
{
"id": "cloudflare",
"label": "Cloudflare (1.1.1.1)",
"reachable": true,
"status": 0,
"ad": true,
"answers": [{"ttl": 300, "data": "203.0.113.10"}]
},
{
"id": "google",
"label": "Google (8.8.8.8)",
"reachable": true,
"status": 0,
"ad": true,
"answers": [{"ttl": 287, "data": "203.0.113.10"}]
}
],
"consistency": {"reachable": 5, "total": 5, "agreeing": 5, "consistent": true}
}Domain availability
GET/api/v1/availability/{domain}
Non-binding availability check via public RDAP; for registered domains it includes the registrar plus creation and expiry dates. Important: TLDs without public RDAP (e.g. .de) return state "unknown" with noRdapForTld=true; only the responsible registry decides at registration time. Errors: 400, 429.
curl https://dns-doctor.com/api/v1/availability/regfish.com
{
"api": "v1",
"domain": "regfish.com",
"state": "registered",
"noRdapForTld": false,
"registrar": "regfish GmbH",
"created": "2004-09-13T10:22:41Z",
"expires": "2027-09-13T10:22:41Z",
"disclaimer": "Non-binding. Only the responsible registry decides at registration time."
}DKIM check
GET/api/v1/dkim/{domain}/{selector}
Fetches selector._domainkey.domain as TXT and inspects the DKIM key: key type (rsa or ed25519), key length in bits, revoked (empty p=) and testing (t=y). Without a DKIM record you get found=false with no further fields except status (the DNS RCODE). Errors: 400, 429, 502.
curl https://dns-doctor.com/api/v1/dkim/regfish.de/k1
{
"api": "v1",
"domain": "regfish.de",
"selector": "k1",
"name": "k1._domainkey.regfish.de",
"found": true,
"valid": true,
"revoked": false,
"testing": false,
"keyType": "rsa",
"keyBits": 2048,
"record": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
}DNSSEC check
GET/api/v1/dnssec/{domain}
Reads DS and DNSKEY records, computes key tags and shows in links which DS entries match a published DNSKEY. status is unsigned (no DS), valid (resolver-validated and at least one DS matches) or broken. Errors: 400, 429, 502.
curl https://dns-doctor.com/api/v1/dnssec/denic.de
{
"api": "v1",
"domain": "denic.de",
"status": "valid",
"adValidated": true,
"ds": [
{"keyTag": 26902, "algorithm": "ECDSAP256SHA256", "digestType": "SHA-256", "digest": "4a7c..."}
],
"dnskeys": [
{"keyTag": 26902, "flags": 257, "algorithm": "ECDSAP256SHA256", "role": "ksk"},
{"keyTag": 43547, "flags": 256, "algorithm": "ECDSAP256SHA256", "role": "zsk"}
],
"links": [{"keyTag": 26902, "matched": true}]
}Mail server check
GET/api/v1/mail-check/{domain}
Resolves the MX hosts (forward), checks their reverse DNS (PTR) with FCrDNS match and the TCP availability of the common mail ports (SMTP, IMAP, POP3) and web ports. Connects only to public target IPs (SSRF-safe). Extra burst limit because of the port probes. Errors: 400, 429.
curl https://dns-doctor.com/api/v1/mail-check/example.com
{
"api": "v1",
"domain": "example.com",
"acceptsMail": true,
"nullMx": false,
"mail": [
{
"host": "mail.example.com",
"priority": 10,
"ipv4": ["203.0.113.10"],
"ipv6": [],
"ptr": [{"ip": "203.0.113.10", "names": ["mail.example.com"], "matchesForward": true}],
"ports": [
{"port": 25, "service": "SMTP", "state": "open"},
{"port": 587, "service": "Submission", "state": "open"},
{"port": 993, "service": "IMAPS", "state": "open"}
]
}
],
"web": null,
"checkedAt": "2026-07-18T09:30:00.000Z"
}SEO & AI visibility
GET/api/v1/seo-check/{domain}?lang=en|de
Fetches the page (soft-404-guarded), robots.txt and the metadata and scores how well the domain is visible to search engines and AI assistants. Findings in four categories: indexing, content, technical and ai (AI-crawler access). Localized via ?lang=de. Each run makes several outbound requests, so there is an extra burst limit. Errors: 400, 429.
curl 'https://dns-doctor.com/api/v1/seo-check/example.com?lang=en'
{
"api": "v1",
"domain": "example.com",
"finalUrl": "https://example.com/",
"fetchedAt": "2026-07-18T09:30:00.000Z",
"ttfbMs": 142,
"score": 94,
"pageTitle": "Example Domain",
"error": null,
"findings": [
{
"id": "https",
"category": "technical",
"severity": "ok",
"title": "HTTPS active",
"detail": "The page is served over HTTPS."
},
{
"id": "ai-crawlers",
"category": "ai",
"severity": "warn",
"title": "Some AI crawlers are blocked",
"detail": "robots.txt disallows GPTBot."
}
]
}IDN/Punycode
GET/api/v1/idn/{name}
Converts domain names between Unicode and Punycode (ASCII), in both directions. Pure conversion without network access, therefore not rate-limited. Errors: 400.
curl https://dns-doctor.com/api/v1/idn/xn--mller-kva.de
{
"api": "v1",
"input": "xn--mller-kva.de",
"ascii": "xn--mller-kva.de",
"unicode": "müller.de"
}Record generators
POST/api/v1/generate/{kind}
Record generators as an API, no DNS queries. kind is spf, dmarc, caa or mta-sts; the JSON body mirrors the fields of the corresponding web tools: spf (allowA, allowMx, ip4, ip6, includes, all), dmarc (policy, subdomainPolicy, rua, ruf, pct, adkim, aspf, fo, domain), caa (issue, issuewild, iodef, critical; the value ";" in the issue array forbids all certificate issuance) and mta-sts (domain, mode, mx, maxAgeDays, id, tlsRptEmail). Warnings and errors are deliberately structured codes (e.g. too-many-lookups) instead of prose so integrations can localize them. Errors: 400, 405, 429.
curl -X POST 'https://dns-doctor.com/api/v1/generate/spf' \
-H 'Content-Type: application/json' \
-d '{"allowMx": true, "ip4": ["203.0.113.10"], "all": "softfail"}'{
"api": "v1",
"kind": "spf",
"host": "@",
"type": "TXT",
"record": "v=spf1 mx ip4:203.0.113.10 ~all",
"lookupCount": 1,
"warnings": [],
"errors": []
}curl -X POST 'https://dns-doctor.com/api/v1/generate/mta-sts' \
-H 'Content-Type: application/json' \
-d '{"domain": "regfish.de", "mode": "testing", "mx": ["mx1.regfish.de", "mx2.regfish.de"]}'{
"api": "v1",
"kind": "mta-sts",
"dnsRecord": {"host": "_mta-sts.regfish.de", "type": "TXT", "value": "v=STSv1; id=202607150930"},
"policyFile": "version: STSv1\nmode: testing\nmx: mx1.regfish.de\nmx: mx2.regfish.de\nmax_age: 604800\n",
"policyUrl": "https://mta-sts.regfish.de/.well-known/mta-sts.txt",
"warnings": []
}Email header analysis
POST/api/v1/header-analysis
Parses a raw email header: Received hops with time deltas, Authentication-Results (SPF, DKIM, DMARC), the key sender fields and an alignment hint. Body as text/plain (raw header) or JSON {"raw": "..."}, at most 64 KiB. Privacy: processing is ephemeral, nothing is stored or passed on; the response is sent with Cache-Control: no-store. Errors: 400, 413, 429.
curl -X POST 'https://dns-doctor.com/api/v1/header-analysis' \ -H 'Content-Type: text/plain' \ --data-binary @header.txt
{
"api": "v1",
"hops": [
{"index": 1, "from": "client.example.net", "by": "mail.example.net", "with": "ESMTPSA"},
{"index": 2, "from": "mail.example.net", "by": "mx.regfish.de", "with": "ESMTPS", "deltaSec": 1}
],
"auth": {"spf": "pass", "dkim": "pass", "dmarc": "pass"},
"fields": {"from": "Alice <alice@example.net>", "returnPath": "<alice@example.net>"},
"alignment": {"fromDomain": "example.net", "returnPathDomain": "example.net", "aligned": true}
}MCP server (for AI assistants)
POST/mcp
Every check is also available as an MCP server (Model Context Protocol) for AI assistants like Claude: stateless over JSON-RPC 2.0 at https://dns-doctor.com/mcp, with the same engine, auth and rate limits as this REST API.
Rate limits & API keys
| Anonymous | With API key | |
|---|---|---|
| Requests per day | 50 per IP | 5000 |
| Authentication | none | X-Api-Key (HTTP header) |
Higher limits are available with an API key via your regfish account: sign up for free →
curl -H 'X-Api-Key: rf_xxxxxxxx' \ 'https://dns-doctor.com/api/v1/check/example.com'
Already have a regfish API key (api.regfish.de/.com)? Use it directly: as Authorization: Bearer or X-Api-Key. It is verified server-side with regfish and counts like a dns-doctor key, i.e. 5000 requests per day.
curl -H 'Authorization: Bearer <regfish-token>' \ 'https://dns-doctor.com/api/v1/check/regfish.de'
Exception: /api/v1/idn is a pure conversion and is not rate-limited.
Badge
GET/badge/{domain}.svg
Embeddable SVG badge showing the current DNS health score of your domain. The color depends on the score and the badge is cached for 1 hour. Live example:
[](https://dns-doctor.com/?domain=YOUR-DOMAIN)
<a href="https://dns-doctor.com/?domain=YOUR-DOMAIN"> <img src="https://dns-doctor.com/badge/YOUR-DOMAIN.svg" alt="DNS health" /> </a>
Replace YOUR-DOMAIN with your domain, e.g. example.com.
OpenAPI & fair use
A machine-readable description of the API is available as an OpenAPI 3.1 spec: /api/v1/openapi.json
Fair use: the API is meant for integrations, monitoring and occasional automated checks, not for mass scraping of entire domain lists. Abuse will lead to blocking.