Audit Email Domain Health: SPF, DKIM, and DMARC Checks
Check SPF, DKIM, DMARC, and MX records across an email list before a campaign, with a reproducible Apify and Python workflow.

A domain can accept mail and still be poorly configured for outbound sending. That distinction matters when a campaign list mixes customer addresses, free inboxes, partner domains, and old CRM imports. A useful audit separates address quality from domain authentication instead of reducing everything to a single green check.
The Bulk Email Verifier returns syntax status, MX availability, disposable and role-address flags, plus SPF, DKIM, and DMARC signals. It does not claim mailbox-level verification.
Run a domain-health audit
Submit the addresses with checkDomainHealth enabled:
import os
import requests
response = requests.post(
"https://api.apify.com/v2/acts/thirdwatch~email-verifier/run-sync-get-dataset-items",
params={"token": os.environ["APIFY_TOKEN"]},
json={
"emails": [
"sales@vendor-one.com",
"founder@vendor-two.com",
"ops@vendor-three.com",
],
"checkDomainHealth": True,
},
timeout=300,
)
rows = response.json()Cache the result by domain. Ten thousand addresses from 200 companies need 200 domain assessments, not 10,000 copies of the same DNS data.
Interpret the fields without overclaiming
mxFound tells you whether the domain advertises a mail exchanger. No MX record is a deterministic reason to suppress the address. domainHealth.spf and domainHealth.dmarc describe published sender controls. domainHealth.dkim is best-effort because DKIM selectors are not globally discoverable.
Use the checks as routing rules:
def route(row):
if not row["syntaxValid"] or not row["mxFound"]:
return "suppress"
health = row.get("domainHealth") or {}
if not health.get("dmarc"):
return "domain-review"
if row["isDisposable"]:
return "suppress"
return "eligible"This produces an auditable reason for every decision. It is much easier to defend than a vendor score whose inputs are hidden.
Schedule the audit around list changes
Run the check when a large import lands, before a high-volume send, and monthly for dormant CRM segments. DNS settings change, but not often enough to justify checking every address on every workflow execution. Save the last checked timestamp and refresh only stale domains.
If mailbox confirmation is required, send the eligible subset to a provider that performs SMTP-level verification. The deterministic audit removes obvious waste first and makes the paid verification batch smaller.
Frequently asked questions
Does a passing domain-health check prove a mailbox exists?
No. MX, SPF, DKIM, and DMARC describe the domain's mail setup. They do not confirm that one recipient mailbox exists.
Why can DKIM be false when a company sends signed mail?
DKIM keys live under selector-specific DNS names. The Actor checks common selectors, so an uncommon private selector may not be found.
Related
100 free credits, no credit card.
About 30 real searches. Add the MCP to Claude or Cursor in two minutes.