Verify a sending domain with Cloudflare DNS
Send as your own domain: add the domain in SendBeam, put its CNAME records in your Cloudflare zone, and confirm the mail is signed and aligned.
Mail that claims to come from your domain has to prove it, and the proof lives in your DNS: a signature the receiving server can check against a key published in your zone, and a bounce address on your domain so failures come back to the right place. Since 2024, Gmail, Yahoo and Microsoft have enforced this for bulk senders rather than merely preferring it, so a campaign from an unauthenticated domain is refused at the door rather than filtered into spam. This guide takes a domain whose DNS is on Cloudflare from nothing to verified, and shows how to prove afterwards that it worked.
Why the records are needed
SendBeam delivers your mail through its own managed infrastructure. That infrastructure can sign
as yourbrand.com only if yourbrand.com publishes something that says so.
The records do two jobs. The signing records publish the public half of the key
your mail is signed with, so a receiving server can verify the signature and see
dkim=pass for your domain. The return-path record gives your mail a
bounce address on a subdomain of your own domain, which aligns the envelope sender with the From
header and lets SendBeam collect bounces and complaints and suppress dead addresses for you.
Everything you add is a CNAME pointing at a name under
dom.sendbeam.io. SendBeam hosts the real values, so your zone never names a third
party and those values can be rotated without you touching DNS again.
Prerequisites
- A SendBeam workspace, and the admin role in it — sender details and sending domains are admin-only.
- A domain you control, either an apex (
yourbrand.com) or a subdomain (news.yourbrand.com). Your plan sets how many sending domains your account may have. - Cloudflare as the DNS host: the zone exists in your account and the domain's nameservers point at it. If DNS lives elsewhere, make the changes there instead.
Steps
- Add the domain in SendBeam. Open Settings > Email & Domains
(
/settings/domains), and under Add your domain type the domain and press Add Domain. SendBeam registers it with its managed delivery and lists the records in a table with a live found / not found column, under the status Add DNS records. - Read what you have been given. Every row is a CNAME: the name is a label on
your domain, the value the matching name under
dom.sendbeam.io, derived from a stable hash of your domain so it never changes. There is nothing to add at the apex, no TXT record to merge and no MX record to touch. - If you see "Connect with Cloudflare", press it. This is Domain Connect, the open standard Cloudflare, GoDaddy, IONOS and others implement: you land on Cloudflare — signed in already, or after its own login — looking at the CNAME records with SendBeam's name on them. Approve, and Cloudflare adds them and sends you back; SendBeam re-checks straight away. SendBeam never sees a password or an API token, and the request is signed so Cloudflare knows it came from SendBeam. The button appears only once a provider has enabled SendBeam's template on its side, so if it is not there, add the records yourself — the step below is the same two records and takes a minute.
- Add them yourself. In the Cloudflare dashboard open the zone, go to
DNS > Records > Add record, choose type CNAME, copy the
name and the value from SendBeam's table, set Proxy status to
DNS only, leave TTL on Auto, and save. Repeat for each row.
Those are shapes, not values — copy the exact names from the page.Type Name (on your domain) Value (target) CNAME <label>._domainkey.yourbrand.com<label>._domainkey.<token>.dom.sendbeam.ioCNAME <label>.yourbrand.com<label>.<token>.dom.sendbeam.io - Wait for verification. A scheduler re-checks unverified domains every minute (at most once every five minutes per domain), so you need not sit on the page; the Verify button forces a check now. Add DNS records means at least one CNAME is still missing. Verifying means they all resolve and the delivery side is finishing its own check, which takes a few minutes and needs nothing from you. Verified means you can send, and Failed that the delivery side rejected the domain. Re-checks stop after 30 days unverified.
- Choose the address you send from. On a verified domain the card offers a
local part —
hello,news— and a Set as default button. The from-name lives in Sender details at the top of the same page, and replies go to the from-address.
What the connect path does not do is worth stating plainly. It creates only the CNAMEs SendBeam listed — no DMARC, no SPF, no MX — and Cloudflare shows you exactly those before anything is written. It never edits or deletes a record you already have. If you decline at Cloudflare, nothing changes and the card says so; the manual route below is always there.
Add a DMARC record
DMARC is not part of verification and SendBeam will not add it for you, but it turns passing
signatures into a policy: it tells receivers what to do with mail that claims to be you and
fails, and it is where reports about mail sent in your name come from. If
_dmarc.yourbrand.com does not exist yet, add it in Cloudflare as a TXT record:
Type: TXT
Name: _dmarc (that is _dmarc.yourbrand.com)
Value: v=DMARC1; p=none; rua=mailto:dmarc@yourbrand.com; fo=1
Start at p=none. It changes nothing about how your mail is treated, which is the
point: for a week or two the reports at the rua address tell you what else sends as
your domain — a helpdesk, an invoicing tool, a form on an old site — before a policy can bounce
any of it. Then move to p=quarantine and on to p=reject, as
Getting started > Sending domain recommends.
A strict policy on a domain you have never measured is how legitimate mail disappears quietly.
Verify it worked
- The domain shows Verified in Settings > Email & Domains, with the date, and your from-address is set on it.
- Press Send test email in Sender details. It sends to your own login address from the address you configured.
- Open the message's original or full headers. You are looking for a pass on your own domain, not on a shared one:
Authentication-Results: mx.example.com; dkim=pass header.d=yourbrand.com; spf=pass smtp.mailfrom=<label>.yourbrand.com; dmarc=pass header.from=yourbrand.com - For a second opinion, run the domain through the sender check tool, which grades your public records as a receiver sees them.
- If a record looks wrong, check it at the source, not in the dashboard:
# Is the record live, and does it point where SendBeam expects? dig +short CNAME <label>.yourbrand.com # → <label>.<token>.dom.sendbeam.io. # A proxied record answers with addresses instead of the target — that is the bug: dig +short <label>.yourbrand.com # → 104.21.x.x (grey-cloud the record)
Troubleshooting
The record ended up at the wrong name. Cloudflare's Name field is relative to
the zone, and pasting a full name into a panel that appends the zone gives you
send.yourbrand.com.yourbrand.com. After saving, read the name Cloudflare shows in the
record list — not what you typed — and confirm it matches SendBeam's table. It bites hardest when
the sending domain is itself a subdomain: for news.yourbrand.com in the
yourbrand.com zone, the record name carries the news label too.
You already have an SPF record. SendBeam does not ask you to change it: the
return path sits on a subdomain of your domain, so alignment is handled there and nothing is
needed at the apex. Leave any v=spf1 … record you have for other senders alone — a
domain may publish only one SPF record, and a second makes both invalid. If you ever do need
another sender's include, merge it into the existing record; never add a second.
The record is proxied. See the warning above. Set Proxy status to DNS only, and note that switching an existing record to grey cloud counts as a change that has to propagate.
Nothing has propagated yet. Cloudflare publishes edits within seconds, but the
resolver SendBeam queries can hold an earlier negative answer for the length of the old TTL.
If the table still says not found after ten minutes and dig on your own
machine sees the record, press Verify once more before assuming a mistake.
"That domain is already registered." A sending domain belongs to one workspace
across all of SendBeam. If it is set up in another workspace of yours, remove it there first or
use a different subdomain here. Domains also match exactly: verifying yourbrand.com
does not let a workspace send as news.yourbrand.com, and that check runs when you
save the from-address and again on every send.
The status went to Failed. The delivery side rejected the domain rather than a DNS lookup failing. Check the names once more, then remove the domain and add it again for a fresh set of records; if it fails again, get in touch — that one is not fixable from your zone.
Next steps
- Getting started > Sending domain for the shared platform addresses, plan pools and from-address rules.
- Contacts > CSV import to bring your audience in now that mail leaves as your own domain.
- Moving in from another platform if the domain is already verified somewhere else and you are switching over.
Starter kits
Once the domain is verified, these starters send from it with no change beyond the form IDs. Each is a small site you can deploy and point at your workspace:
- Astro Astro on Cloudflare Pages No API key needed · Cloudflare Pages Signup and contact components, form IDs in PUBLIC_ environment variables, and a _headers file that lets Turnstile load. sendbeam-starters/astro-cloudflare-pages
- HTML and vanilla JS Plain HTML No API key needed · Any static host One page, one script, no build step: paste the files onto any host and both forms work. sendbeam-starters/plain-html
- Hugo Hugo No API key needed · Any static host Two partials and one script in static/, with the form IDs read from site params in hugo.toml. sendbeam-starters/hugo
- Eleventy Eleventy on Netlify No API key needed · Netlify Nunjucks includes and a global data file, with a netlify.toml that sets the Content-Security-Policy for you. sendbeam-starters/eleventy-netlify
- Next.js (App Router) Next.js on Vercel No API key needed · Vercel Client components that post straight to the form endpoint, so no route handler and no secret sit in the middle. sendbeam-starters/nextjs-vercel
Every starter covers the same five things — newsletter signup, contact form, double opt-in, unsubscribe and spam protection — reads its form IDs from environment variables or site config, and is MIT licensed. Browse them all in sendbeam-starters.
Stuck, or found a gap? Ask in the community — questions, tips and every release note, with this page as the source of truth.