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}]
}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}
}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.