---
title: Sending domains
description: "The DNS records a sending domain needs, the daily check that keeps them honest, when sending pauses, the email admins get, and the API."
---

## Records

**Domains** lists each sending domain with the records to add at its DNS provider. The values are the same for
every domain except the three DKIM names, which Amazon SES picks.

| Record | Name | Value | Holds sending if it fails |
| --- | --- | --- | --- |
| DKIM (3) | `<token>._domainkey.<domain>` | CNAME `<token>.dkim.amazonses.com` | Yes |
| DMARC | `_dmarc.<domain>` | TXT `v=DMARC1; p=quarantine; adkim=r; aspf=r` | Yes |
| MAIL FROM MX | `bounce.<domain>` | MX `10 feedback-smtp.us-east-2.amazonses.com` | No, a warning |
| SPF | `bounce.<domain>` | TXT `v=spf1 include:amazonses.com ~all` | No, a warning |

A DMARC record counts when its policy is `p=none`, `p=quarantine` or `p=reject`, and so does one on a parent domain:
a subdomain with no record of its own uses its parent's, as receivers do (with the parent's `sp=` policy, when it
has one). The walk up to a parent does not know public suffixes, so a record published at one such as `co.uk` would
count; no registry publishes one today. Two DMARC or two SPF records at one name are wrong, because receivers then
ignore both: Domains marks the SPF record to keep, or says to merge them. Without the MAIL FROM records, SES uses its own return path: SPF stops aligning with the domain, and
DKIM still passes DMARC, so mail still goes out.

## The daily check

Every domain is checked once a day, and a domain still being set up is checked every hour for its first week.
**Check now** runs the same check at once, at most once every 10 seconds per domain. Each check:

1. Asks Amazon SES for the identity's verification, DKIM and MAIL FROM status.
2. Looks up every record above through Cloudflare's DNS over HTTPS. A required record that looks missing or wrong is
   asked again through Google's, and only fails when both agree. When Cloudflare does not answer, Google's answer is
   used, except that a required record only passes on it.
3. Keeps the result: each record as found on the domain, and one row per check in its history.

When DNS or SES does not answer, the domain keeps the state it had and is checked again in 15 minutes. A resolver
outage never pauses a domain.

| Status | Means |
| --- | --- |
| Verified | Every required check passed. It can send |
| Sending paused | It was verified, and a required check has failed since. Nothing sends from it |
| Waiting for DNS | It has not passed every required check yet |

Each record's status on **Domains** is a check mark, Missing, Wrong (with what was found), Not found yet while the
domain is being set up, or No answer. **Deliverability** lists every domain with its status and what to fix.

## When a domain is paused

Nothing sends from a paused domain: Send now and Schedule show it as the step left to do, a scheduled campaign goes
back to a draft with the reason at its time, a campaign that is sending pauses on its next batch with the record to
fix, Resume is refused, and so are test sends.

The first time a verified domain is paused, each admin of the workspace gets one email naming the records to fix,
from `alerts@backpackops.com` for now. A sandbox's email goes to Amazon's mailbox simulator. No second email comes
while the domain stays paused; one comes again only if it breaks again after a fix. When every email certainly
failed, the next daily check tries again. An email SES may have sent is never sent twice.

Once the record is fixed, **Check now** lifts the pause, or the next daily check does. Campaigns that were paused
stay paused until someone presses **Resume**, so nobody is surprised by a send.

## API

```
GET /api/v1/domains     domains:read
```

```json
{ "ok": true, "domains": [{
  "id": "dom_...", "name": "news.example.org",
  "status": "paused", "canSend": false,
  "heldReason": "The DKIM record abc._domainkey.news.example.org is missing. Add CNAME abc.dkim.amazonses.com.",
  "heldSince": "2026-10-28T17:02:11Z",
  "ses": { "identity": "SUCCESS", "dkim": "SUCCESS", "mailFrom": "SUCCESS", "checkedAt": "2026-10-28T17:02:11Z" },
  "checkedAt": "2026-10-28T17:02:11Z",
  "records": [{ "purpose": "dkim", "type": "CNAME", "name": "abc._domainkey.news.example.org", "value": "abc.dkim.amazonses.com",
    "required": true, "state": "missing", "found": [], "note": null }],
  "problems": ["The DKIM record abc._domainkey.news.example.org is missing. Add CNAME abc.dkim.amazonses.com."],
  "warnings": []
}] }
```

`status` is `verified`, `paused` or `pending`. `state` is `ok`, `missing`, `wrong` or `unknown`. Adding a domain and
Check now through the API come with the rest of the domain commands.
