Dev.to Security 🔐 Cybersecurity 👁 0 📖 2 min read

Check SPF and DMARC for a list of domains in one API call

Before sending cold email, or when auditing client domains, you want to know three things per domain: is there an SPF record and how strict is it, is DMARC present and what is the policy, and is the domain actually regis

Before sending cold email, or when auditing client domains, you want to know three things per domain: is there an SPF record and how strict is it, is DMARC present and what is the policy, and is the domain actually registered. Doing this with dig for 200 domains is tedious.

This is a real run of an Apify Actor I built. Input:

{
  "domains": [
    "example.com"
  ],
  "maxDomains": 2,
  "includeSubdomains": false,
  "maxSubdomains": 2,
  "checkSsl": true,
  "checkHeaders": true
}

First result (lists trimmed to 2 items):

{
  "domain": "example.com",
  "registrableDomain": "example.com",
  "checkedAt": "2026-11-06T11:31:30.051Z",
  "registered": true,
  "dns": {
    "status": "NOERROR",
    "a": [
      "172.66.147.243",
      "104.20.23.154"
    ],
    "aaaa": [
      "2606:4700:10::6814:179a",
      "2606:4700:10::ac42:93f3"
    ],
    "mx": [],
    "ns": [
      "elliott.ns.cloudflare.com",
      "hera.ns.cloudflare.com"
    ],
    "txt": [
      "v=spf1 -all",
      "_k2n1y4vw3qtb4skdx9e7dxt97qrmmq9"
    ],
    "cname": [],
    "spf": {
      "present": true,
      "record": "v=spf1 -all",
      "all": "fail",
      "includes": []
    },
    "dmarc": {
      "present": true,
      "record": "v=DMARC1;p=reject;sp=reject;adkim=s;aspf=s",
      "policy": "reject",
      "subdomainPolicy": "reject",
      "pct": null,
      "rua": []
    },
    "nullMx": true
  },
  "hasSpf": true,
  "hasDmarc": true,
  "dmarcPolicy": "reject",
  "ssl": {
    "issuer": "SSL Corporation",
    "issuerCn": "Cloudflare TLS Issuing ECC CA 3",
    "subjectCn": "example.com",
    "validFrom": "2026-09-26T22:49:11.000Z",
    "validTo": "2026-12-25T22:56:35.000Z",
    "daysLeft": 49,
    "expired": false,
    "authorized": true,
    "authorizationError": null,
    "protocol": "TLSv1.3",
    "sanCount": 2,
    "sanSample": [
      "example.com",
      "*.example.com"
    ]
  },
  "sslIssuer": "SSL Corporation",
  "sslValidTo": "2026-12-25T22:56:35.000Z",
  "sslDaysLeft": 49,
  "securityHeaders": {
    "finalStatus": 200,
    "score": 0,
    "max": 6,
    "present": {
      "strict-transport-security": null,
      "content-security-policy": null,
      "x-frame-options": null,
      "x-content-type-options": null,
      "referrer-policy": null,
      "permissions-policy": null
    },
    "missing": [
      "strict-transport-security",
      "content-security-policy",
      "x-frame-options",
      "x-content-type-options",
      "referrer-policy",
      "permissions-policy"
    ],
    "server": "cloudflare",
    "poweredBy": null,
    "finalUrl": "https://example.com/"
  },
  "securityHeadersScore": 0,
  "rdap": {
    "registered": true,
    "registrar": "RESERVED-Internet Assigned Numbers Authority",
    "registrarIanaId": "376",
    "createdAt": "1995-08-14T04:00:00Z",
    "expiresAt": "2027-08-13T04:00:00Z",
    "updatedAt": "2026-08-14T08:01:43Z",
    "nameservers": [
      "elliott.ns.cloudflare.com",
      "hera.ns.cloudflare.com"
    ],
    "status": [
      "client delete prohibited",
      "client transfer prohibited",
      "client update prohibited"
    ],
    "ageDays": 11407,
    "daysT

example.com publishes v=spf1 -all and p=reject, so it sends no mail and is locked down, which is what the output says (nullMx true, spf all=fail, dmarc policy=reject).

Run it with the prefilled input: https://apify.com/transparent_meteorite/domain-intelligence-lookup?utm_source=devto&utm_medium=article&utm_campaign=dil_howto
Feedback and Issues are welcome; honest reviews help others judge it.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.