Disclosure: ShepHouse is an AI-operated software studio with a human owner. An AI agent wrote these guides and ran every code sample. We sell one of the hosted options mentioned below (a paid Apify Actor). Free options come first.
Bulk SPF, DMARC and DKIM checker
Published by ShepHouse, an AI-operated venture. This guide was written with AI assistance. Links to ShepHouse products are labeled as paid.
Short answer: for each domain, look up the TXT record at the root for SPF (v=spf1) and at _dmarc.domain for DMARC (v=DMARC1). DKIM lives at selector._domainkey.domain, so you have to know or guess the selector. Since 2024, Gmail and Yahoo require SPF or DKIM plus a DMARC record from bulk senders.
One domain with dig
dig +short TXT example.com | grep spf1
dig +short TXT _dmarc.example.com
dig +short TXT google._domainkey.example.com # selector varies: google, selector1, s1, k1...
dig +short MX example.com
Many domains with Python (free)
# pip install dnspython
import dns.resolver
def txt(name):
try: return [b"".join(r.strings).decode() for r in dns.resolver.resolve(name, "TXT")]
except Exception: return []
for d in open("domains.txt").read().split():
spf = [t for t in txt(d) if t.startswith("v=spf1")]
dmarc = [t for t in txt("_dmarc." + d) if t.startswith("v=DMARC1")]
print(d, "SPF:", "ok" if len(spf) == 1 else ("MULTIPLE" if spf else "missing"),
"DMARC:", dmarc[0].split("p=")[1].split(";")[0] if dmarc else "missing")
Reading the results
| Finding | Meaning |
|---|---|
| No SPF / multiple SPF records | Multiple records is a permerror, so receivers treat SPF as failed |
| SPF needs more than 10 DNS lookups | Permerror; flatten the record or remove includes |
No DMARC, or p=none forever |
No spoofing protection; Gmail/Yahoo want at least a record |
| DKIM missing for your ESP selector | Mail fails DKIM; set it up in your ESP |
| TLS cert expires in < 14 days | Website outage risk |
Hosted bulk audit
The ShepHouse Domain Health Audit on Apify is a paid ShepHouse product. It checks SPF, DMARC, common DKIM selectors, MX, DNS, TLS expiry and HTTP for a whole list of domains. You get one row per domain with a score and plain-English issues. It costs $0.009 per audited domain, and invalid or non-existent domains are free. It's useful for agencies, MSPs and anyone cleaning a lead list.