Domain & Email Security Audit: SPF, DMARC, DKIM, SSL, DNS avatar

Domain & Email Security Audit: SPF, DMARC, DKIM, SSL, DNS

Pricing

Pay per event + usage

Go to Apify Store
Domain & Email Security Audit: SPF, DMARC, DKIM, SSL, DNS

Domain & Email Security Audit: SPF, DMARC, DKIM, SSL, DNS

Audit any domain's email and web security in seconds: SPF, DMARC, DKIM, DNSSEC, MTA-STS, BIMI, CAA, SSL certificate expiry and HTTP security headers. A-F grade plus prioritized fixes. Bulk lists or one domain at a time for AI agents.

Pricing

Pay per event + usage

Rating

0.0

(0)

Developer

Rod Services

Rod Services

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

a day ago

Last modified

Share

What does Domain & Email Security Audit do?

Domain & Email Security Audit checks the email deliverability and web security setup of any domain in one to two seconds and gives it an A to F grade with a prioritized list of fixes. One run covers:

  • Email authentication: SPF (with the 10 DNS lookup limit), DMARC policy, DKIM keys and key size, MTA-STS, TLS-RPT and BIMI.
  • DNS: A, AAAA, MX, NS, TXT and CAA records, plus DNSSEC.
  • Web security: SSL/TLS certificate (issuer, expiry, days left, SANs, TLS version, chain), HTTP security headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) and the HTTP to HTTPS redirect.
  • Optional: domain registration and expiry dates from RDAP.

It uses only public DNS, one TLS handshake and a few HTTP requests per domain. No API keys, no third-party paid services. Costs $1.50 per 1,000 domains.

Paste a list of domains for a bulk DMARC, SPF and SSL check, or call it one domain at a time as a real-time API from your app or AI agent. Run it on the Apify platform with API access, scheduling, integrations (Make, Zapier, n8n, Google Sheets, Slack, webhooks) and monitoring.

Try it now: press Start with the prefilled example (apify.com, github.com, google.com). It finishes in a few seconds.

Why use Domain & Email Security Audit?

  • Email deliverability. Gmail and Yahoo require SPF, DKIM and DMARC for bulk senders. Find missing or broken records before your mail lands in spam.
  • MSPs and IT consultants. Audit every client domain on a schedule. Get alerts when a certificate is about to expire or someone weakens DMARC.
  • Security audits and pentest prep. Quick external posture check: spoofing risk, TLS hygiene, missing headers, no CAA, no DNSSEC.
  • Lead qualification for security and email vendors. Grade thousands of prospect domains. Companies with DMARC p=none or no SPF are warm leads for your product.
  • Vendor and supply-chain risk. Score the domains of your suppliers and partners.
  • AI agents and LLM tools. A fast, predictable JSON endpoint. An agent asks "is example.com protected against email spoofing?" and gets findings with fixes it can explain.

How to check SPF, DMARC, DKIM and SSL for a list of domains

  1. Open the Input tab.
  2. Paste domains into Domains, one per line. example.com, https://www.example.com/page and jane@example.com all work.
  3. Optional: add your own DKIM selectors. Common ones are always checked.
  4. Optional: untick checks you do not need.
  5. Press Start.
  6. Open the Output tab. Use the Overview, Email security, Web and TLS or Findings view. Download results as JSON, CSV, Excel or HTML, or fetch them by API.

Input

All fields are on the Input tab. Only domains must be filled. Without it the run returns one free help row.

FieldTypeDefaultDescription
domainsarray of stringsDomains, URLs or email addresses. Duplicates and a leading www. are removed. IDN names are supported.
dkimSelectorsarray of strings[]Extra DKIM selectors. Always checked: google, selector1, selector2, default, k1, s1, mail, dkim.
checksarray of stringsallAny of dns, spf, dmarc, dkim, dnssec, mtaSts, bimi, ssl, headers, redirect. Only these affect the grade.
includeRdapbooleanfalseAdd registrar and expiry dates from RDAP. Low volume only, 1 lookup per second, 500 per run.
maxConcurrencyinteger10Domains audited in parallel (1 to 50).
timeoutSecsinteger10Timeout per TLS or HTTP connection (3 to 60). A whole domain is capped at 45 s.
{
"domains": ["apify.com", "github.com", "google.com"],
"dkimSelectors": ["mandrill", "20230601"],
"checks": ["spf", "dmarc", "dkim", "ssl", "headers"],
"includeRdap": false,
"maxConcurrency": 10
}

Output

One item per domain. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Shortened example:

{
"domain": "github.com",
"grade": "A",
"score": 90,
"summary": { "critical": 0, "high": 0, "medium": 0, "low": 5, "info": 4 },
"spf": { "found": true, "all": "~all", "dnsLookups": 10, "voidLookups": 0 },
"dmarc": { "found": true, "policy": "quarantine", "pct": 100, "rua": ["mailto:dmarc@github.com"] },
"dkim": [
{ "selector": "google", "keyType": "rsa", "keyBits": 2048 },
{ "selector": "selector1", "keyType": "rsa", "keyBits": 1024 }
],
"dnssec": { "signed": false, "validated": false },
"mtaSts": { "found": false, "tlsRpt": { "found": false } },
"bimi": { "found": false },
"ssl": {
"issuer": "Sectigo Limited / Sectigo Public Server Authentication CA DV E36",
"validTo": "2026-11-29T23:59:59.000Z",
"daysLeft": 63,
"protocol": "TLSv1.3",
"chainOk": true,
"hostnameMatch": true
},
"headers": {
"hsts": "max-age=31536000; includeSubdomains; preload",
"xFrameOptions": "deny",
"permissionsPolicy": null
},
"redirect": { "redirectsToHttps": true, "status": 301, "location": "https://github.com/" },
"findings": [
{
"severity": "low",
"check": "spf",
"message": "SPF uses 10 of 10 allowed DNS lookups.",
"recommendation": "Leave headroom. Adding one more provider may break SPF."
},
{
"severity": "low",
"check": "dmarc",
"message": "DMARC policy is p=quarantine.",
"recommendation": "Move to p=reject for full protection."
},
{
"severity": "low",
"check": "dkim",
"message": "DKIM selectors \"selector1\", \"k1\" use a 1024-bit RSA key.",
"recommendation": "1024-bit keys still pass DKIM, but 2048-bit is recommended (RFC 8301). Rotate when convenient."
}
],
"checkedAt": "2026-09-27T10:31:05.670Z",
"error": null
}

Data fields

FieldWhat it contains
gradeA to F from score. See How the grade is calculated.
score0 to 100. Starts at 100 and loses points per finding.
dnsA, AAAA, MX, NS, TXT and CAA records (CAA inherited from parent names). nullMx marks "0 ." MX.
spfRecord, parsed mechanisms, all qualifier, recursive DNS lookup count, void lookups, includes.
dmarcRecord, policy, subdomain policy, pct, rua and ruf, alignment. Falls back to the parent domain.
dkimKeys found per selector with key type, RSA key size, test mode and revoked flag.
dnssecDS record present and resolver-validated (AD flag), via DNS-over-HTTPS.
mtaStsMTA-STS TXT record, fetched policy (mode, mx, max_age) and TLS-RPT record.
bimiBIMI record with logo and VMC URLs.
sslIssuer, subject, validFrom, validTo, daysLeft, SANs, TLS protocol, cipher, chain and hostname check.
headersHSTS (max-age, includeSubDomains, preload), CSP, X-Frame-Options, and the other security headers.
redirectWhether http:// redirects to https://, with the redirect chain.
rdapRegistrar, created, expires, daysToExpiry, status. Only when includeRdap is on.
findingsseverity, check, message and recommendation, worst first.
errorSet when the domain could not be audited, for example it has no DNS records. Not charged.

How the grade is calculated

Every domain starts at 100 points. Each finding subtracts points by severity:

SeverityPointsExamples
critical-30SPF +all, expired certificate, expired domain registration
high-15no SPF, no DMARC, SPF over 10 lookups, certificate for the wrong name, cert expires soon
medium-7DMARC p=none or partial quarantine, no DKIM key found, no HSTS, no HTTPS redirect
low-2no CAA, no DNSSEC, no MTA-STS, missing CSP or nosniff, DMARC p=quarantine, 1024-bit DKIM
info0no BIMI, no Referrer-Policy, SPF ~all while DMARC enforces

Low findings are hygiene items, so they count at most 6 points per check. Ten small header gaps never cost more than one missing HSTS header. High and critical findings are never capped.

ScoreGradeMeaning
90+AStrong. Only hygiene items left.
80-89BGood. One real gap or several hygiene items.
65-79CNeeds work. Usually a missing SPF, DMARC or HTTPS protection.
50-64DWeak. Several real gaps. Any critical finding also caps the grade at D.
< 50FSpoofable or broken. Fix the high and critical findings first.

Context rules keep the grade fair:

  • A domain without MX, or with a null MX (0 .), is treated as a non-mail domain. Missing DKIM, MTA-STS and BIMI are not penalised. SPF -all and DMARC p=reject are still expected, because spoofing does not need an MX.
  • SPF ~all is only info when DMARC is at quarantine or reject with pct=100. That combination is common and safe.
  • Certificate expiry warnings scale with the certificate lifetime. A 6-day certificate with 4 days left is fine. A 90-day certificate is flagged below 14 days (high) and 30 days (medium).
  • If TLS works but the homepage times out, the site most likely blocks data-center traffic. That is info, not a penalty.

Every finding has a recommendation, so the grade is always explained by the findings list.

Use it as an API for AI agents (Standby mode)

The Actor also runs as an always-ready HTTP API. Send one domain, get one JSON result back:

GET https://rod-analytics--domain-security-audit.apify.actor/?domain=example.com
Authorization: Bearer <YOUR_APIFY_TOKEN>

Optional query parameters: dkimSelectors=s1,s2, checks=spf,dmarc,ssl, includeRdap=true, timeoutSecs=10. url= works as an alias of domain=.

  • 200 with a graded result: billed as one audited domain.
  • 200 with error set (for example the domain has no DNS records): not billed.
  • 400 for an invalid domain, 402 when your maximum cost per run is reached. Not billed.

It works well as a tool in LangChain, CrewAI, n8n AI agents or any MCP client.

How much does a domain security audit cost?

Pricing is pay per event: $1.50 per 1,000 audited domains ($0.0015 per domain) plus a $0.001 start fee per run. Domains that fail (no DNS records, invalid names) are not charged. The prefilled 3-domain example costs under one cent. Platform usage is included. The Apify free plan's $5 monthly credit covers over 3,000 audits.

Set Maximum cost per run on the run options to cap spending. The Actor never charges past the limit. It stops cleanly and the status message says how many domains were skipped.

Tips and advanced options

  • Find more DKIM keys. DKIM selectors cannot be listed from DNS. Open a received email, find s= in its DKIM-Signature header, and add it to dkimSelectors.
  • Go faster. Turn off checks you do not need. spf and dmarc alone take well under a second per domain.
  • Big lists. Raise maxConcurrency to 20 to 30. 1,000 domains take about 5 to 8 minutes at 256 MB.
  • Monitoring. Schedule a daily run and add a webhook or Slack integration. Alert on ssl.daysLeft < 14 or on a grade drop.
  • Subdomains. Enter mail.example.com to audit it directly. DMARC falls back to the organizational domain like real receivers do.

FAQ, disclaimers and support

Is this legal? Yes. The Actor only reads public DNS records, performs a normal TLS handshake and fetches the homepage headers, the same things any mail server or browser does. It does not scan ports, brute-force anything or send email.

Why is RDAP off by default? Registries publish RDAP for occasional lookups. Verisign's RDAP terms of service (.com and .net) forbid high-volume automated queries. The option is limited to 1 request per second and 500 domains per run, and results are cached. Use it for small lists only.

Why does a site show HTTP 403? Some sites block data-center traffic with a bot-protection page. The header results then describe that page. The Actor adds an info finding when this happens.

Why did DKIM say "not found" when I sign my mail? Your provider uses a selector that is not in the common list. Add it to dkimSelectors.

What happens if my input is invalid? The run still ends SUCCEEDED and you pay only the small start fee. No domain is charged. The dataset gets one help row, and the run status message says the same:

{
"error": true,
"errorCode": "EMPTY_INPUT",
"message": "No domains in input.",
"howToFix": "Add at least one domain to \"domains\", e.g. [\"apify.com\"]. ..."
}

EMPTY_INPUT means no domain was given. INVALID_INPUT means none of the entries is a public domain name (IP addresses, localhost and test TLDs are skipped). In a list that mixes good and bad entries, the good ones are audited and each bad one gets a free row with its error text.

Known limits. No SMTP connection to MX servers, no port scan, no blacklist lookup. The registrable-domain logic is a heuristic, so rare public suffixes may fall back incorrectly. IPv4 is used for all connections.

Found a bug or want another check? Open an issue on the Issues tab. Need a custom audit, white-label report or integration? Get in touch through the Actor page.