Three yeses after you send
An email your code hands to a provider needs three yeses, and the API call returns only the first. The provider's API says 202 Accepted: it has the message. Then the provider finds the recipient domain's mail servers in DNS and hands the message to one over SMTP, and when that server answers the end of the message with 250 the provider logs the message as delivered. The third answer, inbox or spam folder, is decided on the receiving side and never comes back to you. Choosing the channel, and the service that does the choosing, belongs to Notifications & transactional messaging; everything here happens after the first yes.
The provider's 202 and the receiving server's 250 are reported to the sender. Where the receiving side files the message is not.
One domain, two kinds of mail
For three years the only mail leaving tallybook.example, an invoicing app for freelancers, was transactional: password resets, invoices, receipts, about 900 a day. Then marketing sent a first newsletter from news@tallybook.example, through the same provider account and the same shared sending IPs, to 41,000 addresses: 6,000 users and 35,000 leads gathered over four years from a free invoice template, most never mailed before. About 2,900 of them, 7%, no longer existed, and about 150 readers reported the newsletter as spam within a day. The next morning support had 40 tickets about reset links that never came. The provider's log said every reset was delivered. At the largest mailbox provider on the list, they were in the spam folder.
Who is allowed to send as tallybook.example
The team looked at authentication first, because a receiver that cannot tie a message to a domain has only the message and the sending IP to go on. It asks three questions, each answered by a DNS TXT record under the sending domain (the lookups themselves belong to DNS, proxies & the network edge).
Was this server allowed to send for the domain? SPF answers with a list of permitted senders, here v=spf1 include:_spf.provider.example -all: the provider's servers and nobody else. The domain it checks is the envelope sender, the bounce address in the SMTP MAIL FROM command, not the From address the reader sees, and a forwarded message usually fails it.
Did the domain sign this, and is it unchanged? With DKIM, the sender signs a hash of the body and selected headers with a private key and names its domain in the signature, and the receiver fetches the public key from that domain's DNS. A valid signature means the signing domain took responsibility for the message and the signed parts were not altered. Tallybook's provider had been signing with its own domain, which said nothing about Tallybook; it now signs for tallybook.example. The private key is the provider's to guard, or the team's if it signs its own mail (Secrets management & encryption).
Does any of that match the From line? DMARC passes a message when SPF or DKIM passes for a domain aligned with the From domain: the same one or, by default, one under the same registered domain, so bounce.tallybook.example counts. Without that check, a spammer could pass SPF for a domain of their own and still write yours in the From line. The record at _dmarc.tallybook.example also tells receivers what to do on failure, from p=none (just report) through p=quarantine to p=reject, and, through its rua address, asks them for aggregate reports. Tallybook started at p=none and tightened it after a month of reports. Large mailbox providers now require bulk senders to set up SPF and DKIM, align the From domain with one of them and publish a DMARC record, even one at p=none, together with a low complaint rate and, for marketing and subscription mail, an easy way to unsubscribe; the details vary by provider.
None of it moved the resets out of spam. Passing these checks ties a message to a domain; it does not show that anyone wants it: a phisher with a lookalike domain passes all three for that domain. What they give a receiver is a name to hang a reputation on, and Tallybook's name now carried 2,900 dead addresses and 150 spam reports.
What the 2,900 failures said
When a delivery attempt gets an SMTP reply code, the first digit decides (an attempt can also fail before any reply, on DNS, a refused connection or a timeout). 5xx is permanent: 550 5.1.1, user unknown, tells the sender not to try the same message again unchanged, a hard bounce. 4xx is temporary: a busy server, a receiver throttling an unfamiliar sender, or greylisting, which refuses a first attempt to see whether the sender comes back. That soft bounce is worth another try after a growing wait, and providers usually make those tries themselves for hours or days (timing and limits are in Retry). Receivers apply the convention loosely, and a bounce can even arrive later as a separate message, so the provider reports its verdict as events posted to an endpoint you expose, the inbound side of Webhooks & third-party integration.
Tallybook had ignored those events, so the dead addresses stayed on its lists, and every later send to them was more evidence that this sender does not clean its list. A suppression list fixes that: addresses not to send to, each with its reason, checked before a message is queued and again by the worker just before it sends, since an address can be suppressed while a long campaign is still going out. A hard bounce for an address that does not exist goes on it (a 5xx that refuses the sender instead, such as a policy block, is the sender's problem to fix, not an address to drop), and so does a complaint, a reader pressing "Report spam", which some mailbox providers forward one by one through a feedback loop while Gmail reports only an aggregate rate. Tallybook's policy is that a complaint blocks marketing mail only, so a reset the user asked for still goes out, provided the provider's own suppression settings do not block that address for all mail. A soft bounce joins the list only after the address keeps failing for days. (Duplicates from resending a call whose answer was lost are a different problem, for Idempotency & exactly-once illusions.)
Why the resets paid for the newsletter
Receivers keep a sender reputation per sending domain and per IP address, lowered by bounces, complaints and hits on spam traps (addresses no person reads: some set up as traps from the start, some abandoned addresses a provider recycled), raised by replies and by messages rescued from spam. Tallybook's resets and newsletter shared both the domain and the IPs, so they shared the damage.
So the streams were separated: resets from mail.tallybook.example, marketing from news.tallybook.example, each with its own DKIM key and IP pool. That limits the damage rather than walling it off, since receivers can still judge both partly through tallybook.example. The marketing subdomain had no history, so it was warmed up: the first campaign went to the 2,000 users who had logged in during the last 90 days, later sends grew while bounces and complaints stayed low, and the cold leads got nothing without a fresh opt-in. The newsletter worker also paces itself per receiving domain, slowing down where a large provider starts answering with 4xx deferrals, and resets have a queue of their own, so they never wait behind a campaign (Message queues & async workers has the queue side).
Resets and campaigns leave through separate queues and subdomains. The provider's bounce and complaint events feed the list every send is checked against.
A reader with no easy way out presses "Report spam" instead. With an HTTPS address in List-Unsubscribe and List-Unsubscribe-Post: List-Unsubscribe=One-Click (RFC 8058), both covered by the DKIM signature, a mail client that supports it can show its own unsubscribe button and, when the reader presses it, send Tallybook a single POST, which suppresses marketing mail only. Open rates make a poor guide to who is engaged, because privacy proxies load tracking images for messages nobody read and image blocking hides the ones people did.
Two questions for a newsletter design
The Email Newsletter Service Challenge sets two requirements this article is about. "Retry transient send failures with backoff, and suppress addresses that hard-bounce or complain": where does a bounce event go in your design, what separates a 4xx from a 5xx there, and is the suppression list read before a message is queued or only after the provider has refused it? "Send to large lists without overwhelming the email provider": what sets the pace of a 41,000-address campaign, and what does the sender do when one receiving domain starts deferring?