SPF, DKIM & DMARC for SparkPost.
SparkPost (now part of Bird, formerly MessageBird) authenticates your domain from Configuration → Sending Domains, where it generates a DKIM key you publish as a TXT record on your sending domain. That DKIM signature — signed as d=yourdomain.com — is the mechanism that actually carries your DMARC pass. SPF is the SparkPost-specific catch: by default SparkPost sends the bounce/envelope from its own shared domain (sparkpostmail.com), so a plain SPF check passes on SparkPost's domain but never aligns to yours. The fix is a custom Bounce Domain — a CNAME that points a subdomain of yours at sparkpostmail.com and becomes your Return-Path, so SPF aligns too. Add a DMARC policy record and you have all three, aligned, with nothing added to your root SPF.
Why authenticate SparkPost?
Authenticating your SparkPost domain isn't housekeeping — it decides whether high-volume transactional and marketing mail reaches the inbox at all. 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 consumer Outlook/Hotmail/Live inboxes in 2025 — exactly the volumes SparkPost is built for. Until you authenticate, SparkPost signs your mail with a shared key and bounces it from sparkpostmail.com: your From address isn't cryptographically yours, DMARC can't pass, and your reputation is pooled with every other unauthenticated sender on that infrastructure. There's a SparkPost-specific twist that makes DKIM non-negotiable: because SparkPost owns the Return-Path by default, SPF passes but does not align to your domain, so DKIM is the only mechanism carrying your DMARC pass until you also set up a custom bounce domain. Doing DKIM plus a bounce domain aligns both mechanisms to you, removes the doubt receivers have about your identity, lets DMARC pass, and builds sending reputation under your own name instead of the shared pool.
The SPF reality for SparkPost
SparkPost is nominally an "include" provider — include:sparkpostmail.com (and include:_spf.sparkpostmail.com, which resolves to the identical record) both exist and DNS-verify — but adding that include to your root SPF is legacy and does NOT make DMARC pass. Here's why. The live record is v=spf1 exists:%{i}._spf.sparkpostmail.com ~all — an exists: macro that authorizes SparkPost's outbound IPs per-IP (%{i} is the sending IP, checked against a wildcard zone) rather than listing fixed ip4: ranges. SPF is always evaluated against the envelope MAIL FROM / Return-Path domain, and by default that domain is sparkpostmail.com, which SparkPost owns. So SPF resolves and passes on SparkPost's domain, but it never aligns with your organizational From domain — and DMARC only counts SPF when it aligns. Publishing include:sparkpostmail.com on your own root domain doesn't change this, because your root domain is never the envelope domain; it just burns two of your ten SPF lookups (the include itself plus the nested exists mechanism inside sparkpostmail.com's record) for no alignment benefit. The aligned SPF path is a custom Bounce Domain: you point a subdomain of yours (e.g. bounces.yourdomain.com) at sparkpostmail.com with a CNAME, SparkPost uses that subdomain as the Return-Path, and now the SPF check runs against your subdomain (relaxed-aligned to your org domain) while still inheriting sparkpostmail.com's SPF via the CNAME. That's why SparkPost's own flow gives you a DKIM TXT record and a bounce-domain CNAME, not an SPF line to paste on your apex. Reserve your root SPF record for senders that actually put your domain in the Return-Path (Google Workspace, Microsoft 365, a relay you control), and let the bounce CNAME + DKIM do SparkPost's work.
Two ways to set it up
Custom bounce domain + DKIM (recommended, aligned)
- DKIM TXT with an scph selector signs mail as d=yourdomain.com — the mechanism that actually passes DMARC
- A custom bounce-domain CNAME (e.g. bounces.yourdomain.com → sparkpostmail.com) makes SPF align to your domain too
- Adds zero DNS lookups to your root SPF — the bounce record lives on its own subdomain, not your apex
- Works the same on SparkPost US and EU (EU just points the CNAME at eu.sparkpostmail.com)
Root SPF include (legacy, does not align)
- You add v=spf1 include:sparkpostmail.com ~all to your root SPF yourself
- SparkPost owns the envelope (default bounce = sparkpostmail.com), so this SPF never aligns to your domain
- It does nothing for DMARC — DKIM and the bounce domain still do all the work
- Costs two of your 10 SPF lookups (the include plus the nested exists mechanism) for no alignment benefit; safe to leave off entirely
Step by step
- 1
Open Sending Domains and add your domain
Sign in to SparkPost (app.sparkpost.com, or app.eu.sparkpost.com for EU accounts) and go to Configuration → Sending Domains → Add Domain. Enter the domain or subdomain you'll send from (a subdomain like mail.yourdomain.com is common and keeps sending reputation separate) and save.
- 2
Copy the DKIM record SparkPost generates
On the domain's setup screen, SparkPost shows a DKIM record under 'Set up for DKIM signing'. It's a TXT record: the host is an auto-generated selector like scph0421._domainkey.yourdomain.com and the value begins v=DKIM1; k=rsa; h=sha256; p=… followed by your public key. SparkPost defaults to a 2048-bit key, so the value is long — copy the whole thing exactly.
- 3
Publish the DKIM TXT record
At your DNS host, create a TXT record with host scph0421._domainkey (under your sending domain/subdomain) and paste the full v=DKIM1… value. Keep it a TXT record — SparkPost DKIM is not a CNAME. Because it's a 2048-bit key, some panels cap a TXT string at 255 characters and require you to split it into multiple quoted strings — split it, don't drop characters. If your panel auto-appends the domain, enter just the label (scph0421._domainkey) to avoid doubling it.
- 4
Verify the sending domain
Back on the Sending Domains screen, check the box confirming you added the record and click Verify Domain. Once it resolves, the domain shows as verified and 'DKIM Signing' reads ready — SparkPost won't sign with your key until this flips. Propagation is usually minutes but can take up to 24–48 hours.
- 5
Add a custom Bounce Domain
Go to Configuration → Bounce Domains (or choose the Bounce Domain option when adding a domain) and add a subdomain to own the Return-Path — e.g. bounces.yourdomain.com for relaxed alignment, or reuse your exact sending subdomain (mail.yourdomain.com) for strict alignment. This is the step that gives you SPF alignment.
- 6
Publish the bounce-domain CNAME
Create a CNAME record: host = your bounce subdomain (bounces), value = sparkpostmail.com (for SparkPost EU, point it at eu.sparkpostmail.com instead). On Cloudflare, set the record to 'DNS only' (grey cloud) — an orange-cloud proxied CNAME won't resolve to SparkPost and verification fails.
- 7
Verify the bounce domain
Return to Bounce Domains and click to verify. Once green, SparkPost uses your subdomain as the envelope MAIL FROM, so SPF now passes AND aligns to your organizational domain — a second aligned mechanism alongside DKIM.
- 8
Add a DMARC policy record
SparkPost doesn't create DMARC for you. Add a TXT record at host _dmarc with v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com. p=none is monitor-only, so nothing changes about delivery while you confirm SparkPost passes SPF and DKIM aligned; you'll tighten it later.
- 9
Send a test and read the headers
Send yourself a message through SparkPost from an address on the authenticated domain, open it in Gmail, and choose ⋮ → Show original. You want DKIM: PASS signed by yourdomain.com (selector scph…), SPF: PASS with the mailfrom on your bounce subdomain (not sparkpostmail.com), and DMARC: PASS. Then confirm every record resolves with a domain health check.
Records to add
SparkPost generates the exact values in its setup wizard — these show the shape of what you'll add at your DNS host.
| Type | Host | Value |
|---|---|---|
| TXT | scph0421._domainkey | v=DKIM1; k=rsa; h=sha256; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A…(2048-bit public key from SparkPost)DKIM — the aligned mechanism that passes DMARC. The scph selector is auto-generated per account (e.g. scph0421, scph0717); illustrative value — copy the exact record from Configuration → Sending Domains. SparkPost defaults to a 2048-bit key, so split it across multiple quoted strings if your panel caps TXT at 255 chars. Publish under your sending domain/subdomain, e.g. scph0421._domainkey.mail.yourdomain.com. |
| CNAME | bounces | sparkpostmail.comCustom Bounce Domain (Return-Path) — this is what makes SPF ALIGN to your domain. Use a subdomain, not your apex. SparkPost EU points this at eu.sparkpostmail.com. Set 'DNS only' (grey cloud) on Cloudflare. |
| TXT | _dmarc | v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.comYou add this yourself — SparkPost never creates it. One per domain; start at p=none, then ramp to quarantine/reject. |
| TXT | @ | v=spf1 include:sparkpostmail.com ~allLEGACY / OPTIONAL — does NOT create DMARC alignment because SparkPost owns the envelope. The bounce CNAME above is the aligned SPF path; only add this if you want your raw SPF to reference SparkPost, and if you do, merge it into your single root SPF record. It costs two lookups — the include plus the nested exists macro inside sparkpostmail.com's record. |
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 SparkPost's setup costs against that budget.
SparkPost's recommended setup adds 0 lookups — all 10 stay free for the senders that do need an include.
DKIM
DKIM is the load-bearing record for SparkPost, because it's the mechanism that aligns by default. When you add a sending domain, SparkPost generates an RSA keypair (2048-bit by default) and shows you a TXT record to publish: the host is an auto-generated selector of the form scphNNNN._domainkey.yourdomain.com (for example scph0421._domainkey — the four digits are assigned per account/key), and the value is v=DKIM1; k=rsa; h=sha256; p=<your public key>. You publish that TXT at your DNS host; SparkPost holds the matching private key and signs every outbound message with it, so the DKIM signature carries d=yourdomain.com and aligns with your From address. Two things set SparkPost's DKIM apart from CNAME-delegation providers (SendGrid, Mailchimp, Klaviyo). First, it's a TXT record you paste — not a CNAME — so publishing a CNAME where the scph TXT is expected will break signing; keep the record type as TXT. Second, because you hold the published key rather than delegating it, there's no automatic key rotation: if you ever need to rotate, you generate a fresh key in SparkPost and republish the new scph TXT yourself. One practical wrinkle from the 2048-bit default: the public key exceeds the 255-character single-string TXT limit, so many DNS panels require you to split it into multiple quoted strings (SparkPost can issue a 1024-bit key instead if your host can't handle multi-string TXT). Publishing the record isn't enough on its own — you must return to Configuration → Sending Domains and click Verify Domain so the domain shows verified and 'DKIM Signing' reads ready; SparkPost won't sign with your key until that flips.
DMARC
DMARC is a separate policy record you add yourself — SparkPost doesn't create it. Publish a TXT record at _dmarc.yourdomain.com starting with v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com. p=none is monitor-only: it changes nothing about delivery while receivers email you aggregate (rua) reports so you can confirm SparkPost mail is passing SPF and DKIM aligned to your domain. This is where the two-part SparkPost setup pays off — once your DKIM scph record is verified you get DKIM alignment, and once your custom bounce domain is verified you get SPF alignment too, so a properly configured SparkPost domain passes DMARC on both mechanisms rather than leaning on DKIM alone. Watch the reports for a week or two, make sure every legitimate sender (SparkPost plus anything else you use) is authenticating, then tighten to p=quarantine and eventually p=reject. Keep exactly one _dmarc record for the whole organizational domain no matter how many senders you run — never publish a second DMARC record specifically for SparkPost.
Check it actually worked
Don't trust the dashboard's green checkmarks alone — confirm it on a real message. Send yourself a test through SparkPost from an address on the authenticated domain, open it in Gmail, and choose ⋮ → Show original. You want DKIM: PASS signed by yourdomain.com with the scph selector (not a shared SparkPost domain), SPF: PASS where the mailfrom/Return-Path shows your bounce subdomain (bounces.yourdomain.com — the tell-tale failure is a mailfrom still on sparkpostmail.com, meaning your custom bounce domain isn't set up), and DMARC: PASS. In SparkPost, Configuration → Sending Domains should show the domain verified with DKIM Signing ready, and Bounce Domains should show your bounce subdomain verified. Then run your domain through Qualisend's domain health check to confirm the DKIM TXT, the bounce CNAME, and the DMARC record all resolve cleanly, and once DMARC aggregate reports start arriving, drop one into the DMARC report analyzer — SparkPost should appear as an aligned, passing source.
Common gotchas
- DNS setup
The big trap: adding include:sparkpostmail.com to your root SPF does NOT make DMARC pass. SparkPost owns the envelope (default bounce domain = sparkpostmail.com), so your root SPF is never consulted for SparkPost mail. Alignment comes from the DKIM scph TXT plus a custom bounce-domain CNAME — not from an SPF include.
- Coverage
With the default bounce domain, SPF passes on sparkpostmail.com but doesn't align to you, so DMARC leans entirely on DKIM. Add a custom Bounce Domain to get an aligned second mechanism and survive stricter receivers.
- DNS setup
SparkPost DKIM is a TXT record (scph selector), not a CNAME. Don't switch the type — a CNAME where the scph TXT belongs breaks DKIM signing. And there's no auto key rotation: to rotate, generate a new key in SparkPost and republish the TXT.
- DNS setup
SparkPost defaults to a 2048-bit DKIM key, whose value is longer than the 255-character TXT limit. Some DNS panels make you split it into multiple quoted strings — split it, don't truncate it or add stray spaces inside the p= value.
- DNS setup
Cloudflare proxy breaks the bounce CNAME. Set the bounce-domain record to 'DNS only' (grey cloud) — an orange-cloud proxied CNAME won't resolve to sparkpostmail.com and the domain won't verify.
- DNS setup
You can't use your root/apex as a bounce domain — a CNAME on the apex collides with your other records. Use a subdomain (bounces.yourdomain.com for relaxed alignment, or reuse your exact sending subdomain for strict alignment).
- DNS setup
SparkPost EU is a separate stack: sign in at app.eu.sparkpost.com, send via smtp.eu.sparkpostmail.com / api.eu.sparkpost.com, and point the bounce CNAME at eu.sparkpostmail.com (not sparkpostmail.com). The same domain in US and EU is two independent registrations with their own DNS records.
- Breaks auth
Keep exactly one SPF TXT and one _dmarc TXT on your domain. If you do keep the legacy SparkPost include for any reason, merge it into your single v=spf1 line — two SPF records is itself a PermError.
- DNS setup
Verify in the dashboard after publishing — SparkPost won't DKIM-sign until Configuration → Sending Domains shows the domain verified. Propagation can take up to 24–48 hours; if verification stalls, re-check the record host for an appended/duplicated domain.
Build your SPF record
SparkPost 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 listSparkPost 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.