Domain RDAP & DNS Security Auditor avatar

Domain RDAP & DNS Security Auditor

Pricing

$3.00 / 1,000 domain auditeds

Go to Apify Store
Domain RDAP & DNS Security Auditor

Domain RDAP & DNS Security Auditor

Audit domain registration, expiry, DNS records, MX, SPF, DMARC and DNSSEC using IANA RDAP and DNS over HTTPS.

Pricing

$3.00 / 1,000 domain auditeds

Rating

0.0

(0)

Developer

Kadev Code

Kadev Code

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Audit up to 1,000 domain names per run. Get registrar details, registration dates, expiry, status and nameservers from the TLD's RDAP service. Check A, AAAA, MX, NS, TXT, SPF, DMARC and DNSSEC evidence through DNS over HTTPS.

The Actor uses Python 3.12 and the Apify SDK. It does not require API keys or a browser. The default memory allocation is 256 MB.

Input

{
"domains": ["example.com", "https://bücher.de/catalog", "EXAMPLE.COM"],
"checkDns": true,
"dnsRecordTypes": ["A", "AAAA", "MX", "NS", "TXT"],
"checkDmarc": true,
"checkDnssec": true,
"maxConcurrency": 5
}

domains is required. Names use IDNA/UTS 46 normalization and punycode. HTTP(S) schemes, paths, query strings and fragments are removed. Credentials, ports, IP addresses and invalid names are rejected. RDAP uses the registrable domain from the offline Public Suffix List (PSL); DNS uses the normalized host requested. For https://www.example.co.uk/path, RDAP queries example.co.uk, while DNS queries www.example.co.uk. The bundled PSL snapshot is pinned through tldextract; no PSL download or cache write occurs at runtime. Its ICANN rules, including wildcard and exception rules, identify registrations; private hosting suffixes such as blogspot.com do not create separate RDAP registrations. Unlisted TLDs use the PSL implicit wildcard rule and still need an IANA RDAP route. Public suffixes alone, such as co.uk, are rejected. Equivalent hosts produce one result, with the first input index. Distinct hosts under one registered domain remain separate DNS audits and billable items. A run with empty input fails; there is no automatic demo lookup.

OptionDefaultEffect
domainsRequired1–1,000 strings, at most 2,048 characters each
checkDnstruefalse disables all DNS, DMARC and DS queries
dnsRecordTypesAll five typesNonempty subset of A, AAAA, MX, NS and TXT
checkDmarctrueQuery TXT at _dmarc.<domain>
checkDnssectrueQuery DS at the domain
maxConcurrency51–10 workers; one active RDAP request per server, eight per DoH resolver

Unknown options cause an input error. A missing or malformed RDAP service produces an error for each affected domain. An invalid domain produces an error row; other valid domains continue.

Output

The default dataset contains one row per unique normalized domain, plus invalid domain rows. index is the zero-based position in the original input. The .actor/output_schema.json output link opens the dataset overview.

Successful rows have success: true and error: null, with these fields:

  • domain, inputDomain: normalized punycode host requested, without the URL path.
  • registrableDomain: PSL-derived domain used for RDAP.
  • partialData, dnsError: false and null for a complete audit. A DNS failure or DNS deadline keeps the valid RDAP result and completed DNS answers, sets partialData: true, and lists the failed query keys in dnsError.failedQueries. Those DNS fields and their derived flags remain null; the item still has success: true, emits a DNS_PARTIAL log warning and incurs domain-audited.
  • registrar: public registrar name and IANA registrar ID, when available.
  • createdAt, expiresAt, updatedAt: UTC ISO dates, or null if unavailable.
  • daysToExpiry: whole days, rounded down, from the lookup time; negative after expiry.
  • status, nameservers: RDAP registration status and nameserver names.
  • dns: A, AAAA, MX, NS and TXT arrays. MX entries retain their DNS presentation form, for example 10 mail.example.com.. Adjacent TXT chunks are joined.
  • spf, hasSpf, hasMx: SPF records and presence flags. Null MX (0 .) means hasMx: false. These fields do not prove email delivery or validate an SPF policy.
  • dmarc, dmarcPolicy: explicit DMARC TXT records and none, quarantine, reject or null. Multiple records, duplicate policy tags and invalid policy values yield null. Parent-domain inheritance is not evaluated.
  • dnssec: RDAP delegationSigned, DS presence and the resolver's AD flag. hasDnssec is true if RDAP declares a signed delegation or a DS answer exists. These are presence signals; they do not constitute an independent DNSSEC audit.
  • dnsRcodes: resolver response codes by query. 0 is NOERROR and 3 is NXDOMAIN.

Unrequested records and derived flags are null; requested records with no answer are empty arrays and have false presence flags. The RDAP DNSSEC signal can remain available when DNS checks are disabled. DNS authenticated evidence is true if any completed query has AD set.

An error row has this form and does not incur a domain event:

{
"index": 0,
"domain": "example.invalid",
"inputDomain": "example.invalid",
"registrableDomain": "example.invalid",
"success": false,
"error": {"code": "NO_RDAP_SERVER", "message": "IANA bootstrap has no HTTPS RDAP service for this TLD"}
}

Other error codes include INVALID_INPUT, INVALID_DOMAIN, BOOTSTRAP_ERROR, NOT_FOUND, INVALID_RDAP, RATE_LIMITED, HTTP_ERROR, NETWORK_ERROR, UNSAFE_URL, RESPONSE_TOO_LARGE, INVALID_RESPONSE and TIMEOUT. DNS_ERROR is reported through dnsError on partial rows. An input-level error has index: null and domain: null, and fails the run. RDAP or DNS errors do not establish that a domain is available for registration.

Sources and limits

The IANA RDAP bootstrap is downloaded once per run. HTTPS service URLs are tried in their bootstrap order. RDAP responses are reduced to the documented fields. Registrant contacts, addresses, emails, telephone numbers, raw entities and raw RDAP responses are not returned. TXT values are public DNS records and are returned as requested; an input URL path or its credentials is never echoed.

Cloudflare's JSON DNS API is used first, with Google as fallback. The fallback also applies to malformed answers, SERVFAIL, refused queries and truncation. NXDOMAIN is a completed response. A DNS failure after both providers fail keeps the RDAP result as a billable partial audit. DNS timeout also yields a partial audit. RDAP failures remain uncharged error rows.

HTTPS requests use a validated public destination IP, preserve TLS SNI and Host, and disable proxy environment variables. DoH uses HTTP/1.1 keep-alive with a separate connection pool per resolver, up to eight concurrent requests and a 60-second cache of validated destination addresses. Other servers, including RDAP, keep one active request per host with no connection reuse. The peer IP is checked on every response, including reused connections. Each redirect selects the destination's pool and is validated. Private, reserved, loopback, link-local, multicast and transition addresses are blocked. Responses are limited to 2 MiB; compression is disabled. Each request has a 15-second timeout and a 10-second connect timeout. HTTP 429 and 5xx responses receive at most three attempts with exponential backoff. Retry-After seconds and HTTP dates are honored. A delay over 60 seconds ends the lookup without an early retry.

Each domain has a 60-second processing limit. Its requested DNS queries run in parallel, within the time left after RDAP. The run has a 270-second processing budget. Domains which cannot start or complete RDAP receive uncharged timeout rows if that budget ends. Valid RDAP plus DNS timeout yields a billable partial. Set the Apify run timeout to 300 seconds. A slow server or a large list can exceed the processing budget; use shorter lists for such servers. A worker starts the next domain as soon as it finishes. Output stays in input order; the number of active and buffered audits is limited to twice maxConcurrency. Workers are cancelled when the charge cap is reached or dataset delivery fails. The Actor logs the processed row count, charged event count and skipped duplicate count.

Pricing

US$ 0.003 per successful unique host audit, via domain-audited, including partial DNS results with valid RDAP. RDAP errors and duplicate hosts do not incur this event. The SDK respects ACTOR_MAX_TOTAL_CHARGE_USD and stops when the charge limit is reached. The result at that limit and subsequent results can be omitted. See pricing.md for Console configuration.

Local development

From this Actor directory:

uv venv --python 3.12 .venv
uv pip install --python .venv/Scripts/python.exe -r requirements-dev.txt
& .venv/Scripts/python.exe -m pytest -q

The tests block external HTTP and DNS. They cover mocked bootstrap, RDAP, DoH, retries, private-IP protection, budgets and local SDK dataset delivery. Set storage/key_value_stores/default/INPUT.json and run python -m src to perform a local lookup with network access. Configure a 300-second timeout when deploying. Local tests do not verify a Docker build or an Apify platform run.

python benchmarks/throughput.py --report benchmarks/throughput-1000.json runs an offline 1,000-domain benchmark with 200 ms per RDAP/DoH request, the production HTTPX pools and a mock dataset/charge sink. See verification.md for measured latency and process memory; these are local mock results.

Protocol references: IANA bootstrap, RDAP JSON responses, RFC 9083, Cloudflare JSON DoH, Google JSON DoH, offline PSL extraction.