Skip to main content
Before you can send a single email you have to prove you own the domain you want to send from. That proof is a set of DNS records you publish in your own zone. This page is the whole of it: what to add, where, and how to tell when it worked.

Why DNS is manual

We never write records in your zone, and we never ask for your registrar credentials. Your DNS is the control plane for your entire online presence: handing a vendor write access to it so they can add three CNAMEs is a bad trade, and it is one you cannot easily undo. We generate the exact records; you publish them. This is the one part of setup that needs someone with access to your DNS provider. Everything after it happens in the app.

Adding a domain

Sending domains are added on Admin > Domains, which is the one page for every domain the platform uses. Click Add domain and you type your root domain once:
1

Enter your root domain

candidate.com, not a subdomain. This is the organizational domain everything else hangs off.
2

Pick what it is for

Tick any combination of the three uses. Email is the sending domain. Link tracking is the host your click and unsubscribe links use. App is a branded dashboard hostname. Most people adding email want email and link tracking together, so the links in your mail carry your domain rather than ours.
3

Accept or edit the subdomains

Each use gets a suggested subdomain, prefilled and editable: mail. for email, links. for tracking, app. for the dashboard.
4

Publish the records

One table lists every record for every use you picked. Add them at your DNS provider and the page tracks them as they land.
Before it generates anything the dialog runs a pre-flight check against the host you are creating. It names your DNS provider, warns about a conflicting SPF record, and refuses to continue while there is a hard conflict such as a CNAME on an apex you also need other records at. This is much cheaper to find out now than after a failed send.

Use a subdomain

Send from mail.candidate.com, not from candidate.com itself. A subdomain keeps campaign sending reputation separate from the domain your staff email from, so a bad list cannot damage your day-to-day mail. It is the default the dialog suggests, and it is the right one for almost everyone.

The records

Publish all of them. There are six, or seven if we generate a DMARC record for you. Four things worth knowing about that table:
  • The bounce host is always bounce. under your sending domain. For mail.candidate.com it is bounce.mail.candidate.com. That pair of records is what gives you SPF alignment: DKIM alone will authenticate your mail, but publishing both is what satisfies the bulk-sender requirements at Gmail and Yahoo.
  • The DMARC record is omitted entirely if your root domain already publishes one. We will not ask you to add a second _dmarc record, because two of them is a permanent error that breaks the policy you already have. Your existing policy is inherited and satisfies alignment on its own. See DMARC progression for moving an existing policy forward.
  • DMARC and Postmaster records go on the ROOT domain, not the sending subdomain. Everything else goes on the sending subdomain. This is the single most common place to get it wrong.
  • The Postmaster record has no value at first. It stays blank until Google issues a token, usually within minutes. Publish it once the value appears. It is optional: nothing about your sending depends on it, and it only unlocks reporting. See Google Postmaster Tools.

How each record is confirmed

A record is not done because we saw it once. Seeing a record in DNS proves it resolves; it does not prove the service that needs it has accepted it. So every record has a confirming signal beyond our own lookup, and the capability it belongs to turns on only when that signal fires: The practical effect: a DKIM record that resolves perfectly but has not yet been accepted upstream shows as Verifying, not Active. That is not a bug, and the usual fix is to wait a few minutes.

Per-record status

Each row in the table carries its own state, so you can see exactly which record is holding things up rather than staring at one domain-level “pending”:

Verify now

Verify now on the domain’s row re-checks immediately rather than waiting for the next scheduled poll. It works in every state, which is the useful part: on a pending domain it pushes verification forward, and on an active domain it re-checks a record that may have been removed, so a broken record surfaces on demand instead of silently breaking your links. Use it after publishing records rather than refreshing the page repeatedly. If you hit it many times in a few minutes you may be rate limited; wait a moment and try again.

Drift detection

DNS records get deleted. A zone gets migrated, a provider gets changed, someone tidying up removes a CNAME they did not recognize. Without detection, the first you would hear of it is a campaign that stopped authenticating. Active domains are re-checked on a schedule, and a record that no longer matches is flagged as Changed, with its capability downgraded until it is fixed. Drift is declared in two cases, deliberately not one:
  • Immediately, when your zone is serving a different value. Someone edited the record, which is not ambiguous.
  • On the second consecutive miss, when the record is simply not found. A single lookup failure is usually a resolver hiccup or mid-propagation, not a deleted record, and flapping a healthy domain to broken and back helps nobody.
The counter resets the moment the record is seen again.

When verification stalls

In rough order of how often each one turns out to be the cause:
  1. The record went in the wrong zone. Added at the root when it belonged on the sending subdomain, or the reverse. DMARC and Postmaster go on the root; DKIM and the bounce pair go on the sending subdomain.
  2. The registrar appended the domain to an already-complete host name, producing x._domainkey.mail.candidate.com.candidate.com. Many DNS UIs add the zone for you. If yours does, enter only the part before your domain.
  3. A proxy is on. A record set to “proxied” rather than “DNS only” is rewritten in the answer, so what we see is not what you published.
  4. It has not propagated yet. Usually minutes, occasionally longer if the old record had a long TTL.

Domain statuses

Deleting a domain

A domain with live sender identities on it cannot be deleted; the request returns 409 CONFLICT. Remove or move the identities first. This is deliberate: deleting the domain out from under an active identity would break sending mid-campaign rather than at the moment you asked for it.

Over the API

The response carries dns_records. Publish them, then poll GET /v1/email/domains/{id} until status is active. Full request and response shapes are in the API reference.

What comes next

Once the domain is active, create a sender identity on it. A domain by itself cannot send; the identity is the From address, and it carries the physical address and disclaimer that go in every footer.