SPF, DKIM & DMARC for Customer.io.
Customer.io authenticates your domain the old-fashioned, transparent way: no one-click wizard and no everything-through-CNAMEs delegation. It hands you a small set of DNS records to publish on a dedicated sending subdomain, then verifies them. You add a single MX record with two hostnames (which gives Customer.io a custom Return-Path on your domain for bounce and spam feedback), an SPF TXT record using the shared include:customeriomail.com mechanism, and a DKIM TXT record whose key Customer.io generates for you. DMARC is a fourth record you add yourself, on your root domain. All of it is managed in Workspace Settings under Email, on the Sending Domains page. Once SPF and DKIM both show green, Customer.io sends fully as your own domain instead of leaning on customeriomail.com.
Why authenticate Customer.io?
Customer.io is a high-volume behavioral messaging platform — newsletters, lifecycle campaigns, transactional journeys — so almost every account clears the bulk-sender thresholds that now decide inbox placement. Since February 2024, Gmail and Yahoo have required every bulk sender (roughly 5,000+ messages a day) to pass SPF, DKIM, and DMARC with alignment, and Microsoft began enforcing the same on high-volume mail into Outlook.com/Hotmail/Live in 2025. Customer.io is stricter than most ESPs about this: it will not send from a domain until both SPF and DKIM are verified — an unauthenticated domain simply can't send, and if either record later breaks, deliveries fail. There's also a genuine alignment advantage worth setting up for. Because Customer.io provisions a custom Return-Path on your own sending subdomain (that's what the MX record is for), the SPF check runs against your domain, not just customeriomail.com — so unlike Mailchimp or Klaviyo's default setup, where only DKIM can carry DMARC, a properly configured Customer.io domain can pass DMARC on both mechanisms. That's the resilient configuration that survives forwarding, and it means the sending reputation you build accrues to your own domain.
The SPF reality for Customer.io
Customer.io is a genuine "include" provider — you publish a single SPF TXT record containing the shared mechanism include:customeriomail.com (the full record is v=spf1 include:customeriomail.com ~all, ending in ~all exactly as Customer.io's dashboard shows it). But two Customer.io-specific truths change where and how you add it. First, this record does not go on your root domain — Customer.io recommends (and effectively expects) a dedicated sending subdomain such as mail.yourbrand.com or email.yourbrand.com, and the SPF, DKIM, and MX records all live there. That's deliberate: because the MX record puts Customer.io's Return-Path on your subdomain, the envelope sender is on your domain, so SPF actually ALIGNS and can contribute to a DMARC pass — something Return-Path-owning ESPs can't do. Second, the include is not flat. A live lookup of customeriomail.com returns v=spf1 ip4:50.31.36.179 include:sendgrid.net ~all, and sendgrid.net in turn nests include:ab.sendgrid.net — so include:customeriomail.com resolves to about 3 DNS lookups toward the RFC 7208 limit of 10, not the 1 that most guides claim. Keeping it on its own sending subdomain isolates that cost from your root domain's SPF budget entirely, which is the whole point of the subdomain approach. Keep exactly one SPF record on the sending subdomain, and don't merge other senders into it — that subdomain is Customer.io's.
Two ways to set it up
Dedicated sending subdomain (recommended)
- All of Customer.io's records — MX, SPF, and DKIM — live on one subdomain like mail.yourbrand.com
- The MX-based custom Return-Path stays on the subdomain, so it can never interfere with your primary inbound mail
- The nested, ~3-lookup include:customeriomail.com stays off your root domain's 10-lookup SPF budget
- Marketing/lifecycle volume builds reputation on an isolated subdomain, insulating your root domain
Authenticating your root domain (avoid)
- Customer.io doesn't require the root domain and doesn't recommend it
- The two-host MX record would sit on your root, competing with your real inbound MX
- The nested include eats ~3 of your root's 10 SPF lookups alongside Google Workspace, M365, and every other sender
- One noisy marketing send can drag down your whole domain's sending reputation
Step by step
- 1
Open the Sending Domains page
Sign in, click the Settings icon, and go to Workspace Settings → Email → Sending Domains. This one page handles adding a domain, revealing its DNS records, and verifying them. SPF, DKIM, MX, and the link-tracking CNAME are all shown here; DMARC is not — you add that separately at your DNS host.
- 2
Add your sending subdomain
Click Add Sending Domain and enter a dedicated subdomain, not your root — mail.yourbrand.com or email.yourbrand.com is the convention. Sending from a subdomain is what lets Customer.io put a custom Return-Path there, and it keeps the MX record off your root domain.
- 3
Reveal the DNS records
On the domain's Authentication tab, Customer.io displays the exact records to publish: one MX record with two hostnames, one SPF TXT record, one DKIM TXT record (the key is generated for your account), and — on the Link Tracking tab — an optional CNAME for branded link tracking. Copy each Host/Name and Value exactly as shown; the DKIM selector and the two MX hostnames are specific to your account.
- 4
Add the two-host MX record
At your DNS host, on the sending subdomain (host mail), create the single MX record with both hostnames Customer.io lists, at the priority it specifies. This MX exists only to give Customer.io a custom Return-Path/bounce address on your domain — it does not receive your normal mail, and because it's on a subdomain it can't affect inbound delivery to your root domain.
- 5
Add the SPF TXT record
On the same subdomain (host mail), add a TXT record: v=spf1 include:customeriomail.com ~all. Keep just this one SPF record on the subdomain and don't add other senders' mechanisms to it — this subdomain belongs to Customer.io. End with ~all as the dashboard shows.
- 6
Add the DKIM TXT record
Add the DKIM TXT record exactly as Customer.io generated it: the host is a selector under your subdomain (like selector._domainkey.mail) and the value is v=DKIM1; k=rsa; p=<public key>. This is a TXT record you paste, not a CNAME — so it's static, and Customer.io does not silently rotate it for you.
- 7
Optional: add the link-tracking CNAME
If you want click-tracked links branded to your domain instead of customeriomail.com, add the CNAME shown on the Link Tracking tab (a tracking subdomain pointing at Customer.io). It's not required for authentication, but skipping it leaves tracked links on customeriomail.com, which weakens brand alignment.
- 8
Publish your DMARC record on the root
Customer.io never creates DMARC. Add a TXT record at _dmarc on your ROOT domain (not the sending subdomain): v=DMARC1; p=none; rua=mailto:dmarc@yourbrand.com. p=none is monitor-only so nothing changes while you confirm alignment; the sending subdomain inherits this policy automatically.
- 9
Click Verify domain
Back on the Authentication tab, click Verify (the grey ticks turn green when records resolve). Propagation is usually minutes but can take up to 24–48 hours. You need green checkmarks on SPF and DKIM specifically — Customer.io hard-requires both before it will send from the domain; the MX and link-tracking records support Return-Path and branding, but SPF+DKIM are the gate.
- 10
Send a test and read the headers
Send a campaign or broadcast from a From address on the authenticated subdomain, open it in Gmail, and choose ⋮ → Show original. Confirm SPF: PASS (envelope on your subdomain), DKIM: PASS with d=yourbrand.com (not customeriomail.com), and DMARC: PASS. Then run the subdomain through a domain health check to confirm every record resolves.
Records to add
Customer.io generates the exact values in its setup wizard — these show the shape of what you'll add at your DNS host.
| Type | Host | Value |
|---|---|---|
| MX | mxa.customeriomail.comFirst of two hostnames on a single MX record — Customer.io's custom Return-Path for bounce/spam feedback, on the sending subdomain. Illustrative: copy the exact two hostnames and priority from the Authentication tab. | |
| MX | mxb.customeriomail.comSecond hostname on the same MX record. Illustrative — use the exact value and priority Customer.io shows. | |
| TXT | v=spf1 include:customeriomail.com ~allSPF on the sending subdomain — one SPF record per host. include:customeriomail.com nests to ~3 lookups (via sendgrid.net → ab.sendgrid.net); ends in ~all as the dashboard shows. | |
| TXT | selector._domainkey.mail | v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQ…(public key from Customer.io)DKIM TXT — Customer.io generates the key pair and shows the full value to paste. Illustrative: the real selector and key are per-account on the Authentication tab. It's a static TXT, not a delegated CNAME. |
| CNAME | customeriomail.comOptional branded link tracking, on a tracking subdomain — copy the exact host/target from the Link Tracking tab. Not required for SPF/DKIM verification. | |
| TXT | _dmarc | v=DMARC1; p=none; rua=mailto:dmarc@yourbrand.comYou add this yourself on the ROOT domain — Customer.io never creates it. One per domain; the sending subdomain inherits it. Start at p=none. |
Keep exactly one SPF (v=spf1) TXT record on your root domain — merge every sender into it. Two SPF records is itself an error.
The 10-lookup budget
SPF is capped at a hard 10 DNS lookups — go over and it returns a permerror and stops validating everywhere. Here's what Customer.io's setup costs against that budget.
Customer.io adds 3 of your 10 lookups; ip4: and ip6: mechanisms are free.
DKIM
DKIM for Customer.io is a TXT record you publish, not a delegated CNAME. When you add a sending domain, Customer.io generates a DKIM key pair for it and shows you a single DKIM TXT record: the host is a selector under your sending subdomain (like selector._domainkey.mail.yourbrand.com) and the value is v=DKIM1; k=rsa; p=<public key>. You paste that TXT exactly as shown; Customer.io holds the matching private key and signs your outbound mail with it as d=yourbrand.com — so the signature aligns to your domain and can carry a DMARC pass. Two things distinguish this from the CNAME-delegated DKIM used by SendGrid or Microsoft 365. First, because it's a static TXT record rather than a CNAME pointing back into the provider, Customer.io does not silently rotate the key behind the scenes — if you regenerate or rotate the key in the dashboard, you must republish the new TXT value yourself, or signing breaks. Second, DKIM here is not optional or best-effort: Customer.io requires both SPF and DKIM to verify before it will send from the domain at all, and if the DKIM TXT is missing, truncated, or mangled by your DNS panel, the domain reverts to unverified and deliveries stop. Publish the record on the sending subdomain exactly as Customer.io formats it, wait for propagation, then click Verify.
DMARC
DMARC is a separate policy record that Customer.io does not create for you — you publish it yourself, and it goes on your ROOT domain, not the sending subdomain. Add a TXT record at _dmarc.yourbrand.com starting with v=DMARC1; p=none; rua=mailto:dmarc@yourbrand.com. p=none is monitor-only: it changes nothing about delivery while receivers email you aggregate (rua) reports so you can confirm Customer.io is passing SPF and DKIM aligned to your domain. This is where Customer.io's subdomain design pays off — DMARC uses relaxed alignment by default (aspf=r, adkim=r), so the DKIM signature on mail.yourbrand.com and the SPF/Return-Path on that subdomain both align to your organizational domain yourbrand.com, and your Customer.io mail passes DMARC on both mechanisms. Keep exactly one _dmarc record on the root; your sending subdomain inherits the parent policy automatically, so do not add a second _dmarc record on the subdomain (adding one there is a common mistake that can break inheritance). Watch the rua reports for a week or two until every legitimate source — Customer.io plus your other senders — is authenticating, then tighten the policy to p=quarantine and eventually p=reject.
Check it actually worked
Don't trust the dashboard checkmarks alone — confirm it on a real message. In Customer.io's Authentication tab you want green checkmarks on SPF and DKIM (the two records Customer.io gates sending on); the MX supports the Return-Path and the CNAME supports branded links. Then send a broadcast or campaign from a From address on the authenticated subdomain, open it in Gmail, and choose ⋮ → Show original: you're looking for SPF: PASS with the envelope/Return-Path on your subdomain, DKIM: PASS signed by d=yourbrand.com (the tell-tale failure is d=customeriomail.com, meaning custom DKIM didn't take), and DMARC: PASS. Spot-check the raw records with dig TXT mail.yourbrand.com, dig TXT selector._domainkey.mail.yourbrand.com, and dig TXT _dmarc.yourbrand.com. Finally, run the sending subdomain through Qualisend's domain health check to confirm the SPF (and its nested lookups), the DKIM TXT, the MX, and your root DMARC all resolve cleanly, and once aggregate reports start arriving, drop one into the DMARC report analyzer — Customer.io should appear as an aligned, passing source.
Common gotchas
- Breaks auth
Customer.io hard-requires BOTH SPF and DKIM to verify before it will send from a domain — most ESPs send on partial auth, Customer.io does not. If either record is missing or mangled, the domain shows unverified and deliveries fail, not just look unbranded.
- DNS setup
Publish everything on a dedicated SENDING SUBDOMAIN (mail.yourbrand.com), never your root. The two-host MX record in particular must stay on the subdomain — put it on your root and you'd redirect bounce handling for your whole domain and risk your real inbound mail.
- Coverage
The MX record is not for receiving your normal email — it exists only to give Customer.io a custom Return-Path on your domain for bounce and spam feedback. Don't panic that you're 'changing your MX'; it's on a subdomain that no human mailbox uses.
- DNS setup
include:customeriomail.com is NOT one DNS lookup — a live lookup shows it nesting include:sendgrid.net, which nests include:ab.sendgrid.net, so it resolves to about 3 lookups. On a dedicated subdomain that's isolated; if you ever fold it into a shared root SPF, it competes with every other sender against the 10-lookup limit.
- DNS setup
DKIM here is a static TXT record, not an auto-rotating CNAME. Customer.io does not rotate it for you — if you regenerate the key in the dashboard, you must republish the new TXT value or signing breaks.
- DNS setup
Host-field doubling on subdomains: many registrars auto-append your zone, so entering mail.yourbrand.com produces mail.yourbrand.com.yourbrand.com. Enter just the label the panel expects (mail, selector._domainkey.mail) if it adds the domain for you.
- Coverage
Put DMARC on the ROOT (_dmarc.yourbrand.com), not the sending subdomain. The subdomain inherits the root policy via relaxed alignment; adding a second _dmarc on the subdomain is a common mistake that can break inheritance.
- DNS setup
Skipping the link-tracking CNAME is fine for authentication, but your click-tracked links stay on customeriomail.com instead of your domain — which weakens brand alignment and can look less trustworthy to recipients and filters.
Build your SPF record
Customer.io doesn't need an SPF include: on your root domain — use the generator to assemble one clean record for your other senders, and keep it to a single line.
Sending sources
Search for each platform you send email through and tick it.
Search for your email platform above, or .
This domain's own servers
Authorize the domain itself, if it sends mail directly (not through a platform above).
Other senders & IPs
Anything not in the list — another provider's SPF host, or specific IP addresses.
We add the include: prefix — enter the hostname your provider documents.
Policy for everyone else
What receivers should do with mail from any server not listed above (the all mechanism).
No senders yet, so every message would hit the ~all policy. Add the platforms you send through in step 1.
- Publish it as a TXT record at your root domain — host @ (the bare domain), value the full string above.
- Keep only one SPF record per domain. Merge every sending source into this single line — a second TXT record starting v=spf1 makes both invalid.
- Stay at or under 10 DNS lookups. Each include:, a and mx counts, and an include can trigger more lookups inside itself — ip4: and ip6: are free.
Authentication published? The next step is sending to a clean, verified list.
Verify a listCustomer.io SPF — FAQ
Related reading
Once it's published, confirm everything resolves with the domain health check, then read who's sending as you with the DMARC report analyzer. Browse all sending sources in the generator. Authentication is only half of deliverability, though — a listed sending IP or domain still lands you in spam no matter how clean your SPF is, so it's worth watching the blacklists with blacklist monitoring.
Authenticated — now keep the list clean
Passing SPF, DKIM, and DMARC gets you to the inbox; a clean list keeps you there. Verify yours — start free with 100 credits, no card required.