{
  "id": 16916792,
  "title": "Check a domain's SPF and DMARC from code in 5 minutes (curl, JavaScript, Python)",
  "url": "https://urgent.news/2026/10/28/check-a-domains-spf-and-dmarc-from-code-in-5-minutes-curl-javascript",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-28T15:22:20.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/michaelrice_dev/check-a-domains-spf-and-dmarc-from-code-in-5-minutes-curl-javascript-python-1onn"
  },
  "original_language": "en",
  "account": "Two DNS blunders often lead to outbound mail being routed to the spam folder: having multiple SPF records for a single domain. The SPF spec only permits a single v=spf1 TXT record. When there are two, mail receivers return a permerror, and many interpret this as a failure. Without a DMARC record under the _dmarc domain, receivers lack any policy from the domain owner and receive no reports. You can verify both SPF and DMARC from your codebase in mere minutes, using a public DNS-over-HTTPS (DoH) resolver that delivers JSON responses.\n\nTo begin, install curl, which is pre-installed on macOS, Linux, and Windows 10+. For JavaScript, Node.js version 18 or later is required (built-in fetch() function). Python users need to install the requests library via pip.\n\nFirst, perform a curl request to Cloudflare's DoH endpoint to retrieve the domain's DMARC record. The request includes the accept: application/dns-json header to request JSON format instead of binary DNS. The response includes a JSON object with the DMARC record's details, including the v=DMARC1; p=quarantine; sp=reject; pct=100; rua=mailto:dmarc@github.com; ruf=mailto:dmarc@github.com; fo=1 data.\n\nNext, check for SPF records using JavaScript. Save the script as check.mjs and run it with Node.js. The script defines a txt() function that sends a curl request to the DoH endpoint for a TXT record at the specified domain. The function filters the returned records to find those starting with v=spf1. For the domain github.com, the output indicates one valid SPF record, while the DMARC record is present as expected.\n\nThe Python version of the script, check.py, follows a similar process. It imports the requests library, defines a txt() function that sends a GET request to the DoH endpoint with the appropriate parameters. The function parses the JSON response and filters for TXT records starting with v=spf1. The github.com domain check shows one valid SPF record and the correct DMARC record.",
  "summary": "Two DNS mistakes cause a lot of \"why is our mail going to spam?\" tickets: Two SPF records on one domain. The SPF spec allows exactly one v=spf1 TXT record. With two, receivers return permerror , and many treat that as a fail. No DMARC record at _dmarc.<domain> . Without one, receivers have no policy from you, and you get no reports. You can check both from code in a few minutes. Nothing to sign…",
  "key_points": [
    "Multiple SPF records cause mail to be routed to spam folder",
    "DMARC record needed for domain owner's policy and reports",
    "Public DNS-over-HTTPS (DoH) resolver verifies SPF and DMARC quickly"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}