Email that lands: set up SPF, DKIM and DMARC for your domain
The three DNS records Gmail, Yahoo and Outlook check before your sign-up codes and receipts reach the inbox.
Written by the IndieHacked teamEmail7 min read
Set up SPF, DKIM and DMARC before you send from your own domain: Gmail and Yahoo require at least SPF or DKIM from every sender, and all three from anyone sending 5,000 messages a day.
SPF lists the servers allowed to send for you, DKIM signs each message, and DMARC tells inboxes what to do when both checks fail to match your From address.
Start DMARC at p=none, read the reports, and tighten it once every service you send through passes.
Want your coding agent to walk you through it?Get the prompt
What the big inboxes ask for
- Gmail, every sender: SPF or DKIM, valid forward and reverse DNS for the sending server, TLS, and a spam rate under 0.3% in Postmaster Tools. Google's target is under 0.1%.
- Gmail and Yahoo, 5,000 or more a day: SPF and DKIM, a DMARC record (p=none is enough), a From address that aligns with SPF or DKIM, and one-click unsubscribe on marketing mail.
- Outlook.com, Hotmail and Live, over 5,000 a day: SPF and DKIM must pass, with DMARC at p=none or stricter, since 5 May 2025. Mail that fails goes to Junk or is rejected.
Google counts the 5,000 across every domain under your main domain together, and a sender that crosses it once stays a bulk sender. Your email provider (Postmark, Resend, Amazon SES, Google Workspace, Microsoft 365) handles TLS and reverse DNS. The DNS records are yours.
SPF: one record, every sender in it
SPF is a TXT record on your domain that lists who may send mail for it. It checks the hidden envelope sender (the Return-Path), not the From address people see. A domain has exactly one SPF record: a second one breaks both, and SPF fails for all your mail. When you add a sending service, add its include to the record you have.
v=spf1 include:_spf.google.com include:amazonses.com ~allSPF stops at 10 DNS lookups. Every include counts, and so do the includes inside it, so a record with six includes can still go over. ~all marks other senders as suspicious and -all fails them; Google's setup guide uses ~all and Microsoft's uses -all.
Transactional providers send with their own Return-Path unless you give them one on your domain. Postmark, for example, asks for a CNAME from pm-bounces to pm.mtasv.net. With it, SPF passes on your domain and lines up with your From address, and you don't add Postmark to your SPF record at all.
DKIM: a key per service
DKIM signs each message with a private key; the public key sits in DNS at selector._domainkey on your domain. Each service you send through signs with its own key, so each gets its own record, under its own selector. Copy the exact values from the provider's dashboard.
- Google Workspace: a TXT record at google._domainkey. Google recommends a 2048-bit key.
- Microsoft 365: two CNAMEs, selector1._domainkey and selector2._domainkey.
- Amazon SES: three CNAMEs, 2048-bit by default.
- Resend: a TXT record at resend._domainkey.
A service that signs with its own domain instead of yours passes DKIM and still fails DMARC, because the signature doesn't match your From address. Set up domain authentication in every service, not only the main one.
DMARC: start at none
DMARC passes when SPF or DKIM passes for a domain that matches the From address. By default the match is relaxed: mail.example.com counts for example.com. The record sits at _dmarc on your domain and names a policy and an address for daily reports.
v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com- Publish p=none and read the reports. Every service sending as your domain shows up there, including the ones you forgot.
- Fix each one until it passes, usually with its DKIM records or a custom Return-Path.
- Move to p=quarantine. RFC 9989, the current DMARC standard, suggests at least a month at none and a similar period at quarantine.
- Move to p=reject only when the reports stay clean, and not if your people post to mailing lists, which RFC 9989 warns against.
Check it worked
dig TXT example.com +short
dig TXT _dmarc.example.com +short
dig TXT google._domainkey.example.com +shortThen send a message to a Gmail address, open it, choose More and Show original, and read the Authentication-Results header. You want spf=pass, dkim=pass with your domain after d=, and dmarc=pass.
Set it up with your coding agent
A prompt for Claude Code, Codex, Cursor or the agent you use. Fill in your setup at the end and it walks you through the work, one step at a time. Free with an account.
Questions founders ask
I added a new email provider and now mail goes to spam. What happened?
Most often a second SPF record. A domain may have only one: two make SPF fail for all your mail. Merge the new provider's include into the record you already had, and add the provider's DKIM records.
Do I need DMARC if I only send sign-up codes and receipts?
Below 5,000 a day, Gmail and Yahoo require SPF or DKIM and not DMARC. A record at p=none costs nothing, gives you reports on every service sending as your domain, and is ready when you grow.
Where to go next
- Postmark
Our review of the transactional email service.
- Make your site readable to AI search
The next thing to check on your domain.
Report an error. Spotted a factual or language mistake? .
More guides
All guidesAgent skills6 min read
The agent skills to install before you build a web app
Agent skills5 min read
The agent skills to install before you build a mobile app
A new guide every few days.
Weekly Unpack brings each one to your inbox. One email a week with the launches, the numbers and one founder story.
Subscribe and your account is Plus.