Auto-configure sending-domain DNS on Cloudflare
Custom sending domains verify on SPF, DKIM, and DMARC records you publish in
your DNS provider. When that DNS lives in a Cloudflare zone, Orbit can create
the missing records for you and poke the email provider (Resend) to re-verify,
all from the deliverability card on the domain row. For domains on other DNS
providers, the same page has a provider-verify button that forces the provider
to re-read the records you publish by hand.
The action reads a Cloudflare API token scoped to the domain’s zone, resolves
the zone, pulls the exact record set the provider expects for your domain,
creates whatever is missing, then tells the provider to re-check. It runs
over the same record set the provider shows on the domain row, never the
platform-default domain.
The action is idempotent. Records already present in the zone (exact type,
name, and content match) are left alone; only missing ones are created. You
can rerun it after a partial failure and it picks up only what is still
missing.
Every record is created with Cloudflare proxying turned off (the
orange-cloud toggle). A proxied TXT, MX, or CNAME record is invisible to
mail infrastructure, so the DNS grid would show green while verification
fails. Auto-configure prevents that specific trap.
You can repeat as many times as you need. Cloudflare reports the final plan
record by record: created, already present, or rejected with the provider’s
error message.
What the flow does under the hood
- Resolve the zone. It walks up the domain’s labels
(
mail.acme.com → acme.com) until Cloudflare returns an active zone your
token can see.
- Read the required set. It asks the provider for the authoritative
record list — the same records the provider’s own dashboard shows, so a
stale provider cache cannot green-light a missing record.
- Diff against the zone. It plans an exact match on type, name, and
content per record. TXT records at the same name with different content are
additive in DNS, so a mismatch schedules a creation — it never overwrites
one of your unrelated records.
- Publish and prove. It creates each gap with proxying off, pokes the
provider to re-verify, stores the token only once it has shown it works,
and reports the provider’s live state.
2. Set up the token
Create a Cloudflare API token with Zone → DNS → Edit on the zone that
serves your sending domain (for mail.acme.com, scope the acme.com zone).
Paste it into the auto-configure dialog on the domain row. Orbit stores it
encrypted (settings.email.cloudflare_token) after the first successful run,
so subsequent reconfigures do not need to paste anything.
Give the token the narrowest scope that works — one zone, DNS edit only — and rotate it if you regenerate the Cloudflare credentials. Orbit never logs the token and never returns it in any response.
If the stored token stops working, supply a new one on the next run and it
replaces the stored value only after that run succeeds.
3. Run it from the dashboard
- Open Channels → Email, find your custom sending domain, and expand
the deliverability card.
- Choose Cloudflare auto-configure.
- Paste the token on the first run; leave the field empty on later runs
to reuse the stored one.
- Read the result per record. Anything marked
already_present was
already there; error carries the provider’s rejection so you can fix
the qualifier (for example a name collision) and rerun.
The response also reports the provider state after the re-verify kick:
sendable when the provider accepts the DNS, unverified while it is
still re-checking, or unknown when the provider gave no definitive answer.
4. Provider verify — the manual path
If your DNS is managed outside Cloudflare (Registrar DNS, another DNS
provider, or an internal resolver), publish the provider-required records
by hand — the deliverability card shows them all — then choose
Verify provider. The action forces the provider to re-read your DNS
right now, without also re-running the live DNS resolve the full refresh
does.
Provider verify also proves a manual fix on a Cloudflare domain if you
prefer to own the zone yourself. It is a no-op on the platform-default
domain, which Orbit manages.
The response tells you whether the provider accepted the kick and shows
the freshly probed provider-verification card, so a refresh loop on the
page picks up the live answer immediately.
Cloudflare deletions and edits publish quickly, but public resolvers can
cache the old answer. If provider verify still shows pending after a
manual change, wait for the TTL you saw on the previous record and verify
again.
5. Choose between the two
6. Security
- Token scope. A Zone → DNS → Edit token on one zone. Nothing else.
- Encrypted storage. The token sits next to your other provider
credentials, encrypted at rest, and is written only after a run proves it.
- No log exposure. The token is never logged and never returned.
- Owner/admins only. The auto-configure route is gated to owner and
admin roles, same as other write actions against the sending domain.
7. Troubleshooting
CLOUDFLARE_TOKEN_INVALID (400). The token was rejected. Recreate it
with Zone → DNS → Edit on the right zone and retry.
CLOUDFLARE_ZONE_NOT_FOUND (404). No active Cloudflare zone matched
any label of the domain. Check the zone status and the token’s zone scope.
CLOUDFLARE_TOKEN_REQUIRED (400). No token in the body and none
stored. Paste one or run provider verify instead.
PROVIDER_DOMAIN_UNAVAILABLE (502). The provider has no record set
for the domain yet. Re-add the sending domain under Channels → Email,
then rerun.
- A record marked
error in the plan. The provider or Cloudflare
rejected that specific record. The response carries the message; fix the
named qualifier and rerun.
- Mixed provider-matrix outcomes. Some matrix surfaces read the provider
state from their own cached probe. They re-resolve on their next poll —
the deliverability card will catch up within its normal cadence.
- Record existed but with a trailing dot or case difference. Both the
diff and lookup normalize for these, so they register as
already_present
rather than a duplicate creation.