Domain DNS & Email Policy Monitor - SPF, DMARC, MX
Pricing
from $1.80 / 1,000 domain observations
Domain DNS & Email Policy Monitor - SPF, DMARC, MX
Read public DNS records and SPF, DMARC, MX and supplied DKIM selectors. Compare complete observations over time with per-query errors. No API key or mailbox access required.
Pricing
from $1.80 / 1,000 domain observations
Rating
0.0
(0)
Developer
Brandt May
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Domain DNS & Email Policy Monitor
Read public DNS records and inspect the published SPF, DMARC and MX information for a list of domains. Optionally query known DKIM selectors and compare each complete observation with its previous snapshot.
Use this to document DNS changes, inspect an email migration, or maintain a structured domain inventory. Each finding includes the public evidence and any query errors. The Actor does not invent a security grade or claim to verify mailbox delivery.
Quick start
Empty input checks wordpress.org and apify.com:
{}
For your own domain list:
{"domains": ["wordpress.org", "apify.com"],"comparePrevious": false,"maxRunSeconds": 240}
No account credentials or API key are required. Queries use the Cloudflare public DNS-over-HTTPS JSON endpoint. The Actor reads DNS; it does not connect to mailboxes or change domain settings.
Inputs
| Field | Default | Meaning |
|---|---|---|
domains | wordpress.org, apify.com | Up to 100 distinct domains. Empty or omitted uses these samples. |
dkimSelectors | none | Up to five known selectors, queried for every domain. |
comparePrevious | false | Opt in to storing and comparing observations. |
snapshotName | default | Independent monitor namespace, up to 100 characters. |
maxRunSeconds | 240 | 30–3,600 seconds, also bounded by the platform deadline. |
Use domain names, or origin URLs without paths, ports, credentials or query strings. IP addresses are not accepted. A DKIM selector is the prefix in selector._domainkey.example.com, not the entire DNS name. Selectors are never guessed. Each selector must begin with a letter or digit and contain at most 63 letters, digits, dots, underscores or hyphens.
What each observation contains
One dataset row represents one domain. A row is complete when every requested query produced a usable response; otherwise it is partial. A legitimate no-data response or NXDOMAIN is a DNS observation, not a service failure.
| Field | Contents |
|---|---|
domain, observedAt, status | Domain, observation time and complete/partial status. |
records | A, AAAA, MX, NS, TXT and exact-domain DMARC results; additional DKIM:selector keys for supplied selectors. |
records.*.status | answer, no_data or nxdomain. A query failure is recorded separately. |
records.*.answers | Answer owner, resolver TTL and record value. TXT chunks are joined. |
records.*.authenticatedData | The resolver's AD flag; this is not a general domain security rating. |
spf | Observed SPF records, count, first all mechanism, simple include/redirect fields and a direct lookup-term count. |
dmarc | Observed exact-domain records, count, p, sp, and pct summary. |
mxProviders | Provider hints derived from recognized MX hostnames, each with the hostname as evidence. Empty means no recognized hint. |
dkim | Supplied selector names, DNS status and returned TXT values. |
issues | Specific informational findings or warnings, each with a code, severity and explanation. |
queryErrors | Resolver, shape, response-size or time-budget errors by query type. |
comparisonStatus, previousObservedAt, changes, baselineEligible | Optional snapshot comparison and whether this observation can update the baseline. |
limitations | The explicit boundaries of the policy checks. |
SPF findings include missing or multiple records, the first permissive all, multiple all terms and excessive direct lookup terms. DMARC checks summarize policy tags and flag selected invalid/duplicate policy cases. This is a policy inspection, not a full SPF or DMARC evaluator. A sole Null MX record is distinguished from an invalid Null MX mixed with other MX records.
Compare changes over time
{"domains": ["wordpress.org"],"comparePrevious": true,"snapshotName": "dns-observations"}
The first complete run emits a full observation with comparisonStatus: "first_observation" and an empty changes list. Later complete runs compare statuses and sorted record values. TTL countdowns and answer ordering are excluded from the comparison. Unchanged observations are still emitted.
The named key-value store maydit-dns-email-baselines holds snapshots by domain, sorted selector list and snapshot namespace. Changing selectors or namespace starts a separate comparison scope. A partial observation has comparisonStatus: "skipped_partial" and never replaces previous history. baselineEligible describes eligibility; confirmed updates are listed in SUMMARY.baselinesUpdated after persistence.
Use a separate snapshotName for independent monitors. Avoid overlapping runs with the same name and scope, because key-value storage does not provide an atomic monitor lock. Schedule future runs through Apify only when you want recurring execution; this Actor does not create schedules itself.
Run summary and failures
SUMMARY contains requested/emitted/complete/partial counts, failed domains, query errors, unprocessed domains, deadline status and confirmed baseline updates. If one domain fails completely, usable results from others are retained. If no domain yields any usable query response, the run fails with a diagnostic.
Resolver errors and malformed/truncated responses are not silently converted into missing DNS records. A partial observation can still contain useful DNS evidence; inspect status and queryErrors before making a decision from it.
Billing
Launch price: $3 per 1,000 emitted domain observations ($0.003 each) on Free/Bronze, plus an Actor Start event of $0.00005. Silver is 20% lower and Gold/Platinum/Diamond 40% lower. The live Pricing tab is authoritative.
Partial observations are billable, as are unchanged observations, first snapshots and valid no-data/NXDOMAIN results. A domain whose every query fails produces no dataset row and no result event. Each domain observation is one result; individual DNS answers and DKIM selectors are not separate result events. Consult the published pricing tab for any platform resource charges.
Limits
- No RDAP/WHOIS, ownership, expiry or registrant lookup is performed.
- No mailbox verification, SMTP probing, email sending or inbox-deliverability test is performed.
- SPF include chains are not expanded. The direct term count is not a complete SPF lookup-budget evaluation.
- DMARC is checked at
_dmarc.<exact-domain>only. Organizational-domain fallback and policy inheritance are not evaluated. - DKIM is queried only for supplied selectors. Returned keys do not prove that outbound mail is correctly signed.
- MX provider labels are hostname hints and can miss custom gateways or other providers.
- DNS caches, propagation and geography can affect observations. A public resolver's answer is a point-in-time observation, not proof that every resolver sees the same result.
authenticatedData: falseis not, by itself, proof of an insecure domain.
Development
Run npm test for the fixture suite. Use isolated CRAWLEE_STORAGE_DIR directories when running locally. The three inputs in examples/ are drafts for verification; the comparison example explicitly opts into state storage and does not create an external schedule.