Bulk DMARC, SPF & DKIM Checker + Email Provider & SaaS Finder avatar

Bulk DMARC, SPF & DKIM Checker + Email Provider & SaaS Finder

Pricing

from $0.80 / 1,000 domain checkeds

Go to Apify Store
Bulk DMARC, SPF & DKIM Checker + Email Provider & SaaS Finder

Bulk DMARC, SPF & DKIM Checker + Email Provider & SaaS Finder

Check thousands of domains for email security in one run: MX records and mail provider (Google Workspace, Microsoft 365...), SPF with lookup count, DKIM selectors, DMARC policy, BIMI, MTA-STS, TLS-RPT, a 0-100 grade with fixes, and SaaS tools from DNS verification records. USD 1 per 1,000 domains.

Pricing

from $0.80 / 1,000 domain checkeds

Rating

0.0

(0)

Developer

JT Palms

JT Palms

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 days ago

Last modified

Share

Bulk DMARC, SPF and DKIM Checker + Email Provider and SaaS Finder

Paste a list of domains (or email addresses, or URLs) and get one row per domain with its email security setup: the mail provider (Google Workspace, Microsoft 365 and others), any security gateway in front of it, SPF with its DNS lookup count, DKIM keys found, the DMARC policy, BIMI, MTA-STS and TLS-RPT, a 0-100 grade with plain-English fixes, and the SaaS tools the domain has verified in DNS (Atlassian, Stripe, DocuSign, Zapier, OpenAI and about 70 more).

Everything comes from public DNS records that the domain owner publishes. Nothing is scraped, no mail server is contacted and no mailbox is checked.

USD 1 per 1,000 domains, plus a tiny start fee per run (see Pricing). Invalid inputs and domains that do not exist are free.

What people use it for

  • MSP and IT security prospecting. Find prospects on Microsoft 365 or Google Workspace with no DMARC, or DMARC stuck at p=none. That is a standard, concrete opener for a security conversation, and the fixes column tells you exactly what to offer. Turn on onlyProblems to get only the domains that need work.
  • Deliverability pre-flight before a campaign. Check your own sending domains and your clients' domains before every send: Gmail and Yahoo require SPF, DKIM and DMARC from bulk senders, and SPF breaks silently when it needs more than 10 DNS lookups.
  • Vendor and supplier risk checks. See which suppliers protect their domain against spoofing (DMARC reject) and which could be impersonated in an invoice fraud email.
  • Sales targeting and routing. Use the mail provider, the sending services in SPF (HubSpot, Salesforce, SendGrid, Mailchimp...) and the DNS-verified SaaS tools as firmographic signals.

Sample output

Real DNS answers on 2026-10-05 (default settings):

domaingrademailProvidersecurityGatewaydmarcPolicyspfAllspfLookupCountdkimSelectorsFoundMTA-STSTLS-RPTSaaS found
shopify.com92Google Workspacereject~all4google, mail, pmnono23
microsoft.com100Microsoft 365reject-all7selector2yesyes16
github.com87Microsoft 365quarantine~all10google, selector1, k1, k2, k3, s1, s2, cmnono16
ford.com92Proofpointreject~all2k2, k3, s1, s2, dkimnono28
crawlee.dev35missingmissing0none foundnono1

crawlee.dev gets 35 because it has no DMARC (-30), no SPF (-25) and no DKIM key among the common selectors (-10). It has no MX record, so MTA-STS and TLS-RPT are not counted against it.

One full row (shopify.com; dnsVerifiedServices trimmed to 10 of the 23 found):

{
"input": "shopify.com",
"domain": "shopify.com",
"acceptsMail": true,
"mx": [
{ "host": "aspmx.l.google.com", "priority": 1 },
{ "host": "alt1.aspmx.l.google.com", "priority": 5 },
{ "host": "alt2.aspmx.l.google.com", "priority": 5 },
{ "host": "alt3.aspmx.l.google.com", "priority": 10 },
{ "host": "alt4.aspmx.l.google.com", "priority": 10 }
],
"mailProvider": "Google Workspace",
"mailProviderSource": "mx",
"securityGateway": null,
"spfRecord": "v=spf1 include:_spf.google.com include:mail.zendesk.com include:sendgrid.net ~all",
"spfCount": 1,
"spfAll": "~all",
"spfLookupCount": 4,
"spfIncludes": ["_spf.google.com", "mail.zendesk.com", "sendgrid.net"],
"spfServices": ["Google", "Zendesk", "SendGrid"],
"spfErrors": [],
"dmarcRecord": "v=DMARC1; p=reject; pct=100; fo=1; rua=mailto:...;ruf=mailto:...",
"dmarcPolicy": "reject",
"dmarcSubdomainPolicy": null,
"dmarcPct": 100,
"ruaDomains": ["shopify.com"],
"dmarcAlignment": { "dkim": "relaxed", "spf": "relaxed" },
"dkimSelectorsFound": ["google", "mail", "pm"],
"dkimKeys": [
{ "selector": "google", "keyType": "rsa", "bits": 1024 },
{ "selector": "mail", "keyType": "rsa", "bits": 1024 },
{ "selector": "pm", "keyType": "rsa", "bits": null }
],
"bimiPresent": true,
"bimiLogo": "https://vmc.digicert.com/8833b699-1227-41ee-b185-cc2d9a08e213.svg",
"bimiVmc": true,
"mtaStsPresent": false,
"mtaStsMode": null,
"tlsRptPresent": false,
"dnsVerifiedServices": ["Microsoft 365", "Google", "Atlassian", "DocuSign", "Stripe", "Zapier", "Klaviyo", "OpenAI", "Facebook (Meta)", "Apple"],
"grade": 92,
"fixes": ["Publish an MTA-STS policy", "Publish a TLS-RPT record"],
"checkedAt": "2026-10-05T16:59:37.155Z",
"error": null
}

What it checks

Since February 2024, Gmail and Yahoo Mail require senders of about 5,000 or more messages a day to their users to publish SPF, DKIM and a DMARC record (p=none is enough to start), and every sender needs at least SPF or DKIM. These are the records this actor reads:

  • MX and mail provider. The MX hosts and priorities, matched against a dated table of providers (Google Workspace, Microsoft 365 including the newer *.mx.microsoft hosts, Zoho, Proton, Fastmail, Yahoo, GoDaddy, IONOS, OVHcloud and others) and of security gateways (Proofpoint, Mimecast, Barracuda, Cisco Secure Email, Broadcom/Symantec and others). A null MX (0 .) means the domain accepts no mail.
  • SPF. The v=spf1 record, how many there are (more than one is an error), how it ends (-all, ~all, ?all, +all, or none), and the DNS lookups a receiver must make, counted the way RFC 7208 does: include, a, mx, ptr, exists and redirect each cost one, nested includes are followed, loops are caught, and more than 10 is an error. Includes are mapped to sending services (SendGrid, Mailgun, Amazon SES, Mailchimp, HubSpot, Salesforce, Zendesk and others).
  • DMARC. The _dmarc record: policy (none, quarantine, reject), subdomain policy, pct, DKIM and SPF alignment, and the domains that receive the aggregate reports (ruaDomains, which often names the DMARC vendor).
  • DKIM. About 27 common selectors are tried (google, selector1 and selector2 for Microsoft 365, k1 to k3, s1 and s2, default, dkim, mail, zoho, protonmail, fm1 to fm3, mandrill, amazonses, mailjet and more) plus any you add. Each key found is reported with its type and size. Revoked keys (empty p=) and wildcard answers are not counted.
  • BIMI. The default._bimi record, the logo URL and whether a certificate (VMC) is published.
  • MTA-STS. The _mta-sts record. With checkMtaStsPolicy on, the policy file is read to get its mode (enforce, testing or none).
  • TLS-RPT. The _smtp._tls record for TLS failure reports.
  • SaaS from DNS verification records. TXT records such as MS=, atlassian-domain-verification, stripe-verification or docusign= show which tools the company has verified its domain with. Only the tool names are output, never the tokens.

Records are recognised by their version prefix only. Some domains answer every unknown name with a wildcard (shopify.com returns SPF, BIMI and DMARC strings at _mta-sts.shopify.com); those strings are correctly ignored.

The grade

Every domain starts at 100. Points come off for:

ProblemPoints
No DMARC record (or an invalid one: several records, or no valid p=)-30
DMARC p=none-15
DMARC p=quarantine-5
No SPF record-25
More than one SPF record-15
SPF ends in +all-25
SPF ends in ?all, or has no all at all (same meaning)-10
SPF needs more than 10 DNS lookups-10
No DKIM key found among the common selectors-10
No MTA-STS record-5
No TLS-RPT record-3
BIMIinformation only

The lowest possible grade is 2. fixes lists what to do, largest deduction first, then information-only notes (MTA-STS still in testing mode, DMARC pct under 100, DKIM keys shorter than 1024 bits, a policy file that could not be read).

Two rules keep parked domains fair: a domain with no MX hosts (a null MX, or no MX at all) is not penalised for missing MTA-STS or TLS-RPT, which protect incoming mail; and a domain whose SPF record is exactly v=spf1 -all (it authorises no sender) is not penalised for missing DKIM. A correctly parked domain such as example.com scores 100.

Input

FieldWhat it does
domainsDomains, email addresses or URLs, one per line. Each is reduced to its registered domain with the Public Suffix List (https://www.python.org/downloads/ becomes python.org, mail.example.co.uk becomes example.co.uk). For an email address only the part after the @ is used. Duplicates are checked once. Invalid entries get a row with an error and are free.
maxDomainsCheck at most this many unique domains (default 10,000). Domains past the limit are skipped and not charged.
extraDkimSelectorsYour own DKIM selector names to try on every domain, for example custom1 (up to 50).
includeSaasDetectionOn by default. Maps TXT verification records to tool names in dnsVerifiedServices.
checkMtaStsPolicyOff by default. For domains with an MTA-STS record, one HTTPS request to https://mta-sts.<domain>/.well-known/mta-sts.txt to read the mode.
onlyProblemsOff by default. Output only domains with a grade under 70. Domains with 70 or more are checked but left out and not charged.
concurrencyDomains checked at the same time (default 20, up to 50).

Output fields

FieldMeaning
input, domainWhat you entered (an email address is shown as (email) domain.com, never in full) and the registered domain checked.
acceptsMailtrue with MX hosts, false with a null MX, or with no MX and no A record; null with no MX but an A record (mail servers may then try that address, so it is unknown).
mxMX hosts with priorities, lowest priority first.
mailProvider, mailProviderSourceThe mailbox provider. mailProviderSource is mx when it comes from the MX hosts, or spf when the MX is a security gateway and the SPF record includes Microsoft 365 or Google. Other means an MX host not in the table (often self-hosted); null means no provider could be named.
securityGatewayThe inbound filtering service in the MX, if any (Proofpoint, Mimecast...).
spfRecord, spfCount, spfAllThe SPF record, how many SPF records exist, and how it ends (-all, ~all, ?all, +all, none, or null without SPF). With redirect=, the ending of the redirected record is used.
spfLookupCount, spfIncludes, spfServices, spfErrorsDNS lookups SPF needs, the include and redirect targets in the domain's own record, the sending services found anywhere in the include tree, and problems (over 10 lookups, loops, missing include targets, several records).
dmarcRecordThe DMARC record, with every mailto: address replaced by mailto:....
dmarcPolicy, dmarcSubdomainPolicy, dmarcPct, dmarcAlignmentParsed DMARC settings. dmarcPct is null when the record has no pct tag. Alignment is relaxed unless the record says s (strict).
ruaDomainsDomains that receive the aggregate reports (never the addresses).
dkimSelectorsFound, dkimKeysSelectors with a published key, and each key's type (rsa or ed25519) and size in bits (null when the key cannot be parsed).
bimiPresent, bimiLogo, bimiVmcBIMI record with a logo, the logo URL, and whether a certificate (a=) is published. A record with an empty logo (a BIMI opt-out) counts as not present.
mtaStsPresent, mtaStsModeMTA-STS record found; the policy mode only with checkMtaStsPolicy.
tlsRptPresentTLS-RPT record found.
dnsVerifiedServicesSaaS tools from TXT verification records (names only).
grade, fixesThe 0-100 grade and what to fix, in order.
checkedAt, errorWhen the domain was checked, and why a row has no data (domain does not exist, an invalid input, or a DNS failure).

The run's key-value store also holds a SUMMARY record with counts (checked, billed, not existing, DNS failures, left out by onlyProblems) and DNS statistics.

Pricing

WhatPrice
Domain checked (one row with all checks and a grade)USD 0.001 (USD 1 per 1,000)
Run startUSD 0.00005 per run
Invalid input, domain does not exist, DNS failure, domains past maxDomains, domains left out by onlyProblemsFree

Worked examples on the free plan:

  • The default input (3 domains): 3 x 0.001 + 0.00005 = USD 0.00305.
  • 1,000 prospect domains: about USD 1.00.
  • 10,000 domains with onlyProblems on, of which 3,200 grade under 70: 3,200 x 0.001 = USD 3.20 (plus the start fee).

Higher Apify plans get a discount on the per-domain price (10% on Silver, 20% on Gold and above). You can set a maximum cost per run in the run options: the actor checks no more domains than that budget can pay for, stops cleanly when it is reached, and keeps every row written so far.

Schedule it weekly. Save your list as a task and schedule it: you will see when a prospect moves from p=none to reject, when a domain changes mail provider, or when someone breaks their SPF.

How it queries DNS

  • About 35 to 40 small DNS queries per domain, most of them DKIM selector guesses. Answers that many domains share (such as _spf.google.com) are cached for the run.
  • The container's own resolver answers first. Only after a timeout or a server failure is a query asked once more, after a short back-off, at a public resolver (Cloudflare 1.1.1.1 or Quad9 9.9.9.9, taken in turn). Definite answers (the name does not exist) are never retried.
  • All queries share one rate limit (250 per second, at most 64 in flight; the public fallback resolvers get their own lower limit), so 1,000 domains take roughly 2 to 3 minutes.
  • Per-query timeout 5 seconds.

Limits and honesty

  • DKIM selectors cannot be listed. DNS has no way to ask "which DKIM keys does this domain have", so the actor tries common selector names. "None found" is not proof that a domain has no DKIM; its selector may have a custom name. Add known selectors in extraDkimSelectors.
  • Registered domains only. Subdomains are reduced to their registered domain (mail.example.com is checked as example.com), so a subdomain with its own SPF or DMARC record is not checked separately.
  • A snapshot. Each row shows the DNS answers at checkedAt. Records change; schedule runs to track them.
  • Provider and SaaS tables are dated (2026-10-05) and cover the common services. An unknown MX host shows as Other; an unknown TXT record is simply not listed.
  • The mail provider comes from the MX hosts. Behind a gateway it is inferred from SPF only when SPF includes Microsoft 365 or Google; otherwise it stays null.
  • DNS failures are free. If a domain's name servers time out or fail even after the retry, its row says so in error and it is not charged; run it again later.

Privacy

  • No mailbox checks, no SMTP connections, no address verification.
  • No email address is ever output. Email inputs are reduced to their domain (the input column shows (email) domain.com), DMARC report addresses are reduced to domains, and any mailto: address in a record is masked.
  • Verification tokens in TXT records are never output, only the tool names.

What this does not do

  • It reads published DNS records only (plus, if you turn it on, the public MTA-STS policy file). It does not send mail, connect to mail servers, test inbox placement, or verify that an email address exists.
  • It does not read DMARC reports or tell you who is sending mail as the domain.
  • It does not validate DKIM signatures or SPF results for real messages; it checks the published setup.
  • It does not check blacklists or IP reputation.
  • It does not visit the domain's website; the only web request is the optional MTA-STS policy file (see Related actors for website checks).

FAQ

Why is "no DKIM found" only -10 points? Because the actor can only guess selector names. A domain may sign every message with a selector named after a date or a vendor ID.

Why did a well-known company get a low grade? The grade measures published protections, not the company. Many large companies still run DMARC at p=none or have no MTA-STS.

Can I check 100,000 domains? Yes. Raise maxDomains (default 10,000) and the run timeout (default 1 hour): at the shared rate limit, 10,000 domains take roughly 25 minutes and 100,000 roughly 4 hours.

Something missing or wrong? Open an issue on the actor page with the domain.