# Sending domains & senders

Connect the domains you send from with one CNAME record, define your senders, and see why the links in your email must ride your own domain.

Every email carries links back to your Mimeo — the unsubscribe link, click tracking, the open pixel. Connecting your sending domain puts those links on *your* domain, and senders define who your mail comes from.

## What this is

One settings page — **Settings → Domains & senders** — holds two short lists and one address:

- A **sending domain** is a domain your mail sends from (`example.org`), connected to your Mimeo with a single CNAME record.
- A **sender** is a from name plus an email address on one of those domains — the identities the From field offers when you write an email.
- The **mailing address** is the physical address your email footers show — [details below](#mailing-address).

On a fresh Mimeo, the [setup wizard](https://mimeohq.com/docs/providers/setup) builds all of it for you — your senders, sending domains, and mailing address are created as part of setup. This settings page is where they live afterward: add a domain, add a sender, or change a link subdomain any time. Do it once per domain and it never comes up again.

## Connecting a domain: one CNAME

The CNAME's target is your Mimeo's own address — the setting the app calls **your Mimeo's host**. It's detected automatically the first time you log in. Correct it under **Settings → Domains & senders → Sending domains → Change host**; the field's placeholder is `mimeo.example.com` (an `APP_HOST` environment variable overrides both). Webhook URLs and links in account email use the same value.

The example below sends mail from `example.org` and runs the Mimeo app at `mimeo.example.com`. Replace both with your own domains.

<ol>
          <li>
            Go to <strong>Settings → Domains &amp; senders</strong> and add
            the domain you send from — <code>example.org</code>. Typing the
            link host itself (<code>mimeo.example.org</code>) also works —
            Mimeo files it under the right domain.
          </li>
          <li>
            Mimeo shows you one DNS record. Add it wherever that domain's DNS
            is managed:
            <table>
              <thead>
                <tr><th>Type</th><th>Host</th><th>Value</th></tr>
              </thead>
              <tbody>
                <tr>
                  <td>CNAME</td>
                  <td><code>mimeo.example.org</code></td>
                  <td><code>mimeo.example.com</code></td>
                </tr>
              </tbody>
            </table>
          </li>
          <li>
            Wait for DNS. Adding the domain checks it immediately, and
            <strong>Check now</strong> re-checks on demand. The HTTPS certificate
            issues itself a few minutes after DNS goes live — nothing to upload,
            nothing to renew.
          </li>
        </ol>

The check is honest rather than hopeful: Mimeo fetches `https://mimeo.example.org/.well-known/mimeo-instance` through the new host and confirms the answer is its own identity token. A green check means the CNAME is live, HTTPS works, and the record points at *your* Mimeo — the three things a subscriber's click needs. When it isn't green yet, the status says why: still propagating, certificate not issued yet, or pointing somewhere that isn't your Mimeo.

## Why is this needed?

Every email you send carries links back to your Mimeo: the unsubscribe link in the footer, the click-tracking redirects, and the open-tracking pixel. The domain those links live on has to match the sending domain you verified at your provider. Links on an unrelated domain — like your Mimeo's own app host — hurt deliverability, and "from one domain, links to another" is exactly the pattern phishing filters are trained on.

With a connected domain, everything a subscriber sees rides your domain: links wrap as `https://mimeo.example.org/l/…`, the open pixel serves from `/o/…`, and the unsubscribe page and its endpoints run at `/unsubscribe/…`, `/u/…` and `/api/v1/subscription/…` on the same host. The mail and its links agree.

The app itself stays where it is. A connected domain serves only those email-facing routes — anything else requested through it redirects to the app's own host, so there's exactly one login URL and `mimeo.example.org` never grows into a second copy of the app. And the guarantee runs both ways: Mimeo refuses to send an email whose body links to the app's own host, so the host subscribers were never meant to see never leaks into their inbox.

## The provider has to verify it too

A domain needs two green lights. The CNAME proves the domain reaches your Mimeo; your provider's DKIM verification proves you may send as it. Verify the domain in the [Postmark](https://mimeohq.com/docs/providers/postmark) or [Resend](https://mimeohq.com/docs/providers/resend) dashboard the way you would for any sending — DNS records for DKIM — and Mimeo tracks both sides per domain:

| Status | What it means |
| --- | --- |
| **Waiting for DNS** | The CNAME hasn't reached your Mimeo yet. |
| **Waiting on Postmark / Resend** | DNS is done, but the provider hasn't verified the domain for sending. |
| **Not checked yet** | Mimeo hasn't been able to read the provider's verified list, so it can't say either way about this domain. A banner at the top of the page gives the reason. |
| **Connected** | Both sides agree. Mail from this domain sends. |

Mimeo reads the provider's verified list when you press **Verify connection** (Settings → Provider) or **Check now** here, and keeps the answer as a cached snapshot. The check that runs before every send is a local read of that snapshot — sending never waits on a provider API call.

If that read fails — most often a provider API key without permission to list domains — Mimeo says so and repeats the provider's own message, rather than reporting your domains as unverified. A key that can send but can't read domains leaves every domain and sender showing **Not checked yet** until you replace it.

## Senders and the From picker

A sender is a from name and an email address, defined once on the **Senders** tab of the same section. The From field in the email editor is a dropdown of your defined senders — one is marked default, and the first sender you add becomes the default without you having to say so. There's no free-typing a from address into an email: the identities you send as are declared, like custom fields are.

A sender's address has to be on a connected domain, and the provider has to have verified it. What "verified" covers depends on the shape your provider offers:

- A **DKIM-verified domain** covers every address on it — add as many senders on that domain as you like.
- A **Postmark per-address sender signature** covers exactly that one address.
- **Resend has no per-address concept** — verification is domain-level only.

## The mailing address {#mailing-address}

The mailing address is set under **Settings → General → Email footer**. Unsubscribe pages and subscription preferences have their own **Unsubscribe Flows** section under General. Both are covered here because they apply to email from every sending domain.

Anti-spam law (CAN-SPAM in the US, and its equivalents elsewhere) requires every marketing email to show a physical mailing address for the sender. A P.O. box or a registered virtual mailbox works — it doesn't have to be your home.

Set it once under Settings → General → Email footer and layouts show it with the `{{ mailing_address }}` tag, which every real send resolves at send time — change the address here and every future send picks it up, no template edits. The default layout ships with the tag already in its footer, next to the unsubscribe link.

Mimeo nudges rather than blocks: sending still works without an address, but the dashboard alerts you until one is set.

## Unsubscribe page

The `{{ unsubscribe_url }}` link in every footer opens **Mimeo's own page**, served on your connected domain at `/unsubscribe/<token>`. The page asks the person to confirm, and one press of its **Unsubscribe** button takes them off the list — loading the link alone never unsubscribes anyone. The person's record shows the result as *unsubscribe · via link*, attributed to the exact email they clicked from. Configure the subscriber experience under **Settings → General → Unsubscribe Flows**, on three tabs:

- **Mimeo unsubscribe page** — the person sees a confirmation with a **Resubscribe** button in case it was a slip. The text is yours to change: the introduction before unsubscribing, then the status line, headline, confirmation (`{email}` safely shows their address in bold), the button's text and color, and the small line under the button — plus the same for what the page says after they resubscribe. Every field has a default; clear one to get it back. **Preview page** opens the page as a subscriber sees it, and its buttons walk through the page's states.
- **Mimeo manage subscriptions page** — enable the checkbox to add tag/custom-field preferences alongside global unsubscribe. Both hosted tabs show **In use** when enabled. Disabling preferences keeps your definitions for later; enabling them clears a custom unsubscribe URL.
- **Custom unsubscribe URL** — after confirming, the person is sent straight on to a URL of yours instead. They're already unsubscribed by then, so a plain thank-you page works with no logic at all; if you want it to offer resubscribe, Mimeo adds their signed token (`?token=…`, or in place of `{token}`) for the [subscription management API](https://mimeohq.com/docs/api/subscriptions), which has a complete single-file example. Saving a custom URL disables hosted preferences but preserves their definitions. This is not a selective-preference handler: the person has globally unsubscribed before the redirect.

The click always lands on Mimeo first, so an opt-out never depends on another server being up, and neither page is ever indexed: the token is the whole address, and the bare `/unsubscribe` path is nothing. Link scanners that open every URL in an email on a recipient's behalf can't opt anyone out: GET requests never change subscription state, and only the page's own confirming POST performs the unsubscribe. Mailbox providers' own unsubscribe buttons still work in one click through Mimeo's [RFC 8058 one-click endpoint](https://mimeohq.com/docs/api/subscriptions#one-click) (`POST /u/:token`). This is always global, including with Resend; Mimeo handles it directly, without waiting for a provider webhook.

## Let people choose their subscriptions {#subscription-preferences}

With management enabled, the public page has two tabs: **Unsubscribe from everything** and **Manage my subscriptions**. Customize both labels and the default tab. Each has introductory text rather than a repeated large heading. The defaults are *{email} will stop getting all email from us.* for unsubscribe and *Choose the emails you'd like to receive at {email}.* for preferences. The address is safely rendered in bold, including in the customizable after-unsubscribe and after-resubscribe copy.

Each preference toggle has a label, an optional description, an **On when** condition that reads tags or custom fields, and separate **When user turns on** and **When user turns off** action lists. A weekly-news example:

| Setting | Example |
| --- | --- |
| Label | Weekly news |
| Description | One roundup each week. |
| On when | Person has the `weekly_news` tag. |
| When user turns on | Add the `weekly_news` tag. |
| When user turns off | Remove the `weekly_news` tag. |

Actions can add a tag, remove a tag, set a custom field, or clear a custom field. Use an existing active field with a value that matches its type. You can combine tag and field conditions with all, any, or not rules. Avoid shared targets across toggles: Mimeo rejects two toggles writing the same tag or field, and duplicate writes within one branch.

**Toggles never auto-save.** The **Save preferences** button is disabled until a toggle differs from its initial saved state. Revert all changes and it disables again; a successful save also disables it. The button text and success message are customizable. Saving runs **every toggle's selected on/off action list**, including unchanged toggles. The resulting conditions must match all selections, or the entire save is rolled back with no preference changes.

The unsubscribe and preference forms submit independently. Preference actions never change global suppression. Someone already globally unsubscribed sees management faded and disabled until they explicitly resubscribe. That resubscribe does not apply any preference actions; changing preferences is a separate save.

> [!CAUTION]
> **Wire each preference into your sending rules.** For weekly news, target a [segment](https://mimeohq.com/docs/usage/segments) that requires `weekly_news`, and add a [send-time guard](https://mimeohq.com/docs/usage/guards) requiring that tag for weekly-news emails already in the queue. Mimeo does not add these guards automatically. Removing a preference tag leaves other tags and global subscription status alone.

Agents can configure the same controls through the [settings API](https://mimeohq.com/docs/api/settings#subscription-preferences). For a custom server-side workflow, the [event API](https://mimeohq.com/docs/api/events#selective-preferences) can add and remove preference tags together without suppressing the person. Never place an operator API token in a public page.

## When something isn't verified

Enforcement happens at send time, on every send — broadcasts, sequences, flows, and test sends alike. An email from a sender whose domain isn't connected doesn't fail and doesn't disappear: it **holds in the queue**, with the reason *"Its sending domain isn't connected"* visible on the [Queue screen](https://mimeohq.com/docs/usage/queue).

The hold releases itself. Mimeo re-checks every few minutes, so within minutes of the domain or sender going green the held mail sends — no manual release, no resend button. Fix the configuration and the queue catches up on its own.

Broadcasts tell you earlier: a broadcast without a verified sender reports *"a verified sender"* among the pieces it's missing before it will schedule, so you find out at planning time rather than in the queue.

> [!NOTE]
> The Test provider used in development doesn't verify identities, so none of this gates anything in development. Enforcement switches on when a real provider — one that verifies sending domains — is connected.

## Multiple domains

Send from as many domains as you like — a newsletter domain and a product domain, say. Each one is one CNAME: `mimeo.example.org` and `mimeo.example.net`, both pointing at your Mimeo. At send time, the from address's domain picks the matching connected domain automatically, and that domain supplies the link host for everything in the message. Nothing to choose per email, per sender, or per send.

See also: [Set up sending](https://mimeohq.com/docs/providers/setup) · [Getting started](https://mimeohq.com/docs/usage/getting-started) · [Sending providers](https://mimeohq.com/docs/providers/) · [Tracking](https://mimeohq.com/docs/api/tracking)
