Guides

Protect your sending domain: warm-up, sending windows and bounces

Protect your sending domain by deciding when mail goes out, how much each mailbox sends and who is never mailed again. What SPF, DKIM and DMARC prove, why warm-up is a cap you raise, and the checks Runner runs before every send.

Updated

The short version

  • A domain's reputation is built from what it sends. Bounces, spam complaints and sudden jumps in volume are what spend it.
  • Runner holds every send to your sending window, the daily cap on each mailbox in the pool and your opt-outs, and checks each recipient again at the moment it goes.
  • A permanent bounce or a spam complaint stops that address for your whole organization. A full inbox does not.
  • Live sending ships off, and your DNS records stay with your DNS admin — nothing in Runner writes to your zone.

Inbox providers judge your domain by everything it sends

It's launch day. Someone has imported the old conference list, written a good subject line, and wants to mail all of it before lunch. Nobody knows how many of those addresses still exist, and the domain has sent almost nothing for a month.

Mailbox providers decide where your mail lands partly from your domain's history. Mail to addresses that no longer exist, people pressing the spam button, and a quiet domain suddenly sending in bulk all count against it. That's the same reputation your password resets and invoices travel on.

So protecting a domain comes down to three habits. Prove the mail is yours. Grow volume gradually. Stop mailing anyone who bounced or complained. The first is a DNS job you do once. The other two should happen on every send, whether or not anyone remembers them.

SPF, DKIM and DMARC prove the mail is yours, and your DNS admin publishes them

Three DNS records do the proving. SPF lists the servers allowed to send mail for a domain. DKIM signs each message with a private key and publishes the public half in DNS, so a receiver can check the message came from you unaltered. DMARC tells receivers what to do when neither check lines up with the domain in the From line, and where to send reports about it.

Plenty of teams send campaigns from a subdomain such as mail.example.com, so campaign reputation stays apart from the mail people send from the main domain every day.

Publishing those records is always your DNS admin's job. Nothing in Runner writes to your DNS zone, and that's deliberate: a product able to do it would need authority over your whole domain just to send mail from one corner of it.

When Runner lists the records for a sending domain, the three DKIM records are the ones Amazon SES issued for that domain, and the MX and SPF records for a custom return-path subdomain appear only when you use one. Without a working connection to SES, Runner writes and shows nothing, rather than placeholder records somebody might paste into a live zone.

Try it

In a terminal, run dig TXT _dmarc.example.com +short with your own domain in place of example.com. An answer starting v=DMARC1 is the policy receivers read. No answer means your domain has told them nothing.

Warm-up is a daily cap you raise, and Runner holds the pool's mailboxes to it

A brand-new mailbox that goes from silence to a full list in one afternoon looks a lot like a hijacked account. Warm-up is the fix: start with a small daily volume, and raise it as the mailbox builds a steady history of mail that arrives.

In Runner, each mailbox in a product's sending pool carries its own daily cap, and every send counts against it before it goes. The next send leaves from whichever mailbox has the most room left, so the day's volume spreads across the pool instead of draining one address first. When no mailbox in the pool can take it, the send is refused with the reason. It never slips out from an address nobody put in the pool.

A send the provider refuses on the spot gives its place back, so the day's count reflects mail that actually left. The product's schedule adds two more limits: a minimum gap between sends from the same mailbox, and a ceiling on how many new people the product contacts in a day.

Caps belong to mailboxes in the pool, and a cap moves when someone on your team changes it, which keeps warm-up a decision a person makes. Put a new mailbox in the pool, set it low, and raise the number as its delivery history earns it.

Sending windows hold cold mail to the hours you chose

Give a product a sending schedule — the days of the week, a start time and an end time, in the timezone you set on the schedule — and campaigns send only inside it. A send tried outside the window is refused with the rule that held it named, and nothing goes out. A timezone that doesn't resolve refuses the send rather than guessing.

Some mail shouldn't wait for business hours, so a product, or a single campaign, can be set to send outside the schedule. That setting covers mail with a transactional purpose only, such as support, security and legal messages. A marketing, sales or research campaign stays inside the window even with it switched on, because Runner works the answer out from the campaign's purpose at send time instead of trusting the setting.

A single campaign can also keep its own days and hours. Any part of that schedule it leaves blank keeps the product's value, so narrowing one field never quietly drops another limit. A product with no schedule has no window to hold anyone to, which makes setting one the first job for a new product.

Inside the window, sends go out at a steady pace per second rather than as one burst.

Picture this

A teammate at Northwind presses send on the launch email at eleven on a Friday night. The product's window is weekdays, nine to five. Nothing leaves, and the refusal names the window. Sent again on Monday morning, the campaign goes out across the pool's mailboxes, each one inside its cap.

Runner checks every recipient again at the moment of sending

An audience is a snapshot. You build it on Monday; by Thursday one address has hard-bounced from another campaign and someone else has unsubscribed. So the snapshot is never the last word.

Before anyone is mailed, the campaign itself has to pass: not stopped, not paused for the organization or the product, not paused by the automatic breaker described below, approved, and with a sender that's ready. The approval is tied to what was approved. It covers the exact subject, body and audience size, and changing any of them makes the send a new request that needs its own go-ahead.

A send the provider accepts is recorded as accepted, not delivered, until the delivery event comes back. And before any single email goes, its recipient is checked on their own:

  • Already sent this step? Skipped, so running a campaign twice mails nobody twice.
  • On your organization's opt-out list? Skipped, and recorded that way.
  • A marketing email to someone who already had one from this product today? Skipped.
  • A personalization field with no value and no fallback? That email is marked failed with the reason, rather than arriving with a gap where a name should be.
  • Every mailbox in the pool at its cap? Refused, with the reason named.

Bounces and complaints close the address for the whole organization

A permanent bounce or a spam complaint puts the address on your organization's opt-out list, and every product in the organization stops mailing it. A soft bounce doesn't. A full inbox still belongs to a real person, and dropping them over it would lose them for good.

That list outranks every purpose, transactional included. Mailing an address that hard-bounced damages the sending domain for every product that shares it, so no consent record and no message type buys an exception.

Unsubscribing takes one click. Every campaign email that needs an unsubscribe carries the headers that put an unsubscribe button beside the sender's name, plus a visible link in the message itself, so a relay that strips headers still leaves a working way out. An unsubscribe opts that person out of the product they unsubscribed from.

When another product in your organization is already contacting the same person, a new campaign holds off on them instead of piling on, and it never learns which product that was.

And if a product's recent sends start failing at a high rate, sending for that product pauses itself, and every send attempt says why. The pause doesn't lift on a timer. One bounce on its own never trips it, because the breaker waits for enough recent sends to mean something.

Try it

Open a marketing email in your own inbox and view the original message. The List-Unsubscribe and List-Unsubscribe-Post headers are what give your mail app its one-click unsubscribe button. When they're missing, the quickest way out a reader has left is the spam button.

Live sending ships off, so your team decides when the automation starts

A new workspace sends no real campaign email. Live sending ships off for the organization and for each product until an admin turns it on, and switching either one off again holds every later send beneath it, with no release.

Above both sits a platform switch that no customer setting reaches, so live sending is never something a single row in a database turns on. With any of the three off, no real campaign email leaves: the send runs against a stand-in with nothing behind it, and says which switch held it.

Timed follow-up runs through the same checks, one contact at a time, with promises of its own. Each person stays on the version of the journey they started. Pausing a journey freezes everyone in it. Consent is read again at every step. And a step interrupted by a crash is never retried: Runner would rather miss one email than send one twice.

Send campaigns, on the product page

One system for the whole path

The mechanism above is one of the jobs Runner does on one record, under one login. Access is by application.