01Start with the headers, not with the content
Start here, always. The receiver already told you what it concluded about your authentication, in a header, in plain text, on the message that went to spam. Reading it takes thirty seconds and it eliminates or confirms the entire first layer of the diagnosis before you have formed a single theory.
Find the Authentication-Results block. It was added by the receiving server, which makes it the only part of the message your sending infrastructure could not have written.
| Client | How to see the source |
|---|---|
| Gmail | Open the message, then Show original |
| Outlook | View message source |
| Apple Mail | View → Message → All Headers |
The block will be near the top.
A local parse. Nothing you paste leaves your browser — this component makes no network request of any kind.
DMARC is the one that decides. A message can show spf=pass and still fail DMARC, because DMARC additionally requires that the passing domain matches the domain in the From header a reader sees.
| What you read | What it means |
|---|---|
| spf=pass | The connecting server was authorised by the envelope sender’s domain — which is not necessarily yours. |
| dkim=pass | The signature verified against a key published in the signing domain’s DNS. |
| dmarc=pass | One of those two passed and aligned with the From domain. Three passes mean your authentication is not the reason. |
| none | Not a failure. No record was published, so nothing was checked — which is a different problem from failing, and a worse one at DMARC. |
| permerror | A syntax problem in your own DNS, most often two SPF records on one name or an SPF record that exceeds the ten-lookup limit. Receivers treat both as no SPF at all. |
none and permerror are the two results people consistently misread.
02Authentication failures
The reason authentication goes first is not that it is the most common cause. It is that it is the cheapest and most certain: the answer is binary, it comes from the receiver rather than from your inference, and the fix is fully within your control and finishable this afternoon. Everything below this layer is probabilistic and slow. Never start with the slow, fuzzy layer while a fast, certain one is unresolved.
| Layer | Kind of answer | Time to fix | Why it sits here |
|---|---|---|---|
| Authentication | Binary | An afternoon | Either the header says pass or it does not. No judgement, no negotiation, and the fix is entirely in your DNS. |
| Reputation | Continuous | Weeks | A rolling history of how recipients reacted to you. Cannot be argued with, only outlived. |
| List quality | Measurable | One send | Complaint rate, unknown-user rate, engagement. You control the inputs directly and the effect is immediate. |
| Content | Fuzzy | Unknowable | The only layer where you cannot tell whether a change helped. Which is why it goes last. |
The failure that catches most people is not a missing record. It is alignment. DMARC does not ask whether SPF passed; it asks whether SPF passed for a domain that matches the From header. A message with From: [email protected] and Return-Path: [email protected] shows spf=pass in the header and still fails DMARC, because what passed was the vendor’s domain and it proved nothing about yours.
From: [email protected] ← what the reader sees Return-Path: [email protected] ← what SPF checked: not you DKIM d= yourdomain.com ← aligned: DMARC passes on this alone
This is why the bounce path belongs on a subdomain of your own domain rather than the transport’s, and why DKIM is worth publishing even when SPF already passes — DKIM alignment is the one that survives a forward. If any of that is unfamiliar, the authentication guide builds the records, and verification tells you whether what you published is what resolvers see.
| Header | What MailySend sends on every message |
|---|---|
| List-Unsubscribe | Both an HTTPS and a mailto option |
| List-Unsubscribe-Post | List-Unsubscribe=One-Click |
Transactional mail included. The large consumer providers require this from bulk senders, and it is checkable in the same header dump you already have open.
03Domain and IP reputation
Reputation is a rolling summary of how recipients behaved towards your mail, kept per-domain and per-IP by each receiver, and never shown to you. There is no score to look up, no appeal, and no lever. There is only the behaviour that produces it, which means the only way to change a reputation is to send different mail for long enough that the old mail falls out of the window.
Domain reputation is the one that matters most now, and it travels with you: changing transports does not reset it, because it is attached to the name in the From header and the DKIM d= domain, not to the machine that connected.
That is the point of DMARC alignment from the receiver’s side — it makes reputation attributable to a party that cannot walk away from it.
- Worth it above roughly 100,000 messages a month, sent on a steady schedule
- The threshold is about consistency as much as total — 100,000 a month in one monthly blast does not qualify
- Actively worse than a well-run shared pool
- Reputation is built from volume observed over time, and an IP that sends 4,000 messages one week and nothing the next never accumulates enough history for any receiver to form an opinion
- An IP with no reputation is treated with suspicion, not neutrality
04List quality beats content every time
This is where most spam problems actually live, and it is three numbers. None of them is about your writing. Receivers weigh complaint rate, unknown-user rate, and engagement, in roughly that order of severity, and they weigh them per sending domain over a rolling window.
Complaint rate is the proportion of delivered messages where a recipient pressed the spam button, and at the number above you are already in trouble. That is why a hard-to-find unsubscribe link is such a bad trade: the alternative to unsubscribing is not staying subscribed, it is complaining.
Unknown-user rate is the proportion of messages rejected because the address does not exist. A sender who repeatedly mails addresses that never existed is a sender who bought, scraped or typo-collected a list, and receivers read it exactly that way — which is why hard bounces must suppress immediately and permanently.
| Bounce | Class | Suppressed for |
|---|---|---|
| 5.1.1, 5.1.3, 5.1.6 | hard_invalid | Permanently |
| 5.1.2 | hard_domain | Permanently |
| Mailbox full | Soft | 7 days |
| Throttled | Soft | 1 day |
| Content | Soft | 3 days |
| Temporary | Soft | 2 days |
| An unrecognised diagnostic | unknown | Not at all, deliberately |
Eight classes in total, mapped from the enhanced status codes rather than guessed from the text. Not suppressing on unknown is the right trade in one direction only: an unrecognised bounce is a gap in the classifier, and guessing costs a real subscriber permanently — so a rising unknown count is a signal about the classifier, not about your list.
Engagement is opens, clicks, replies, moves out of spam, and — most strongly — the absence of any of these over a long window. A segment that has not opened in a year is not neutral weight; it is negative weight, and continuing to mail it drags the placement of the mail your engaged recipients do want. Suppressing your dormant third is the single highest-leverage deliverability action available to most senders, and it feels like giving up revenue right until placement recovers.
- HEAD-request detection
- The security-vendor user-agent list
- Apple MPP user-agent matching
- The bot list, and empty user agents
- The timing-window rule
- The ASN rule
- The multiple-links-in-two-seconds rule
- Because the tracking endpoint passes only user agent, IP, method and country to the classifier
05Content, last and least
Content is last because it is the layer with the worst ratio of effort to certainty. Per-word scoring — the “spam words” lists, the idea that writing free or guarantee in a subject line trips a filter — has not been the dominant signal for many years. Filters are trained on sender behaviour and recipient reaction, and a sender with a clean complaint rate can write free as often as they like.
The content factors that still matter are structural rather than lexical: whether the message is shaped like ordinary mail, and whether the domains it points at are trustworthy.
The folklore persists because it is actionable and the real causes are not. Rewriting a subject line takes five minutes and feels like progress; suppressing 40% of your list takes an argument with whoever owns the revenue number. The five minutes is the reason people spend a week on the wrong layer.
| Still matters | Why |
|---|---|
| A plain-text alternative | A multipart message with a real text part is normal mail. HTML-only is a weak negative on its own and a strong one in combination. |
| Link domains | Links to a domain with a bad reputation, or through a public URL shortener shared with every phishing campaign on earth, are judged separately from your sending domain. |
| The tracking domain | Open and click tracking rewrite links through a domain. If that domain is shared and unbranded, its reputation is not yours to control. |
| One giant image | A message that is a single image with no text is unreadable to a filter, to a screen reader, and to anyone with images off. All three read it the same way. |
| A visible unsubscribe | Not for the filter — for the complaint rate. Every hidden unsubscribe link converts a would-be unsubscribe into a spam report. |
MailySend generates the text alternative from your HTML on render, inlines the CSS and enforces a table layout for the same reason: those are the properties of ordinary mail, and looking ordinary is the whole content strategy.
What just happened
You have an order to work in rather than a list of tips: settle authentication from the header, then look at your complaint and unknown-user rates, and only then argue about the subject line. The thing most likely to waste your week is skipping to the last step, because content is the only layer where you cannot measure whether a change helped — rewriting an email until it feels less spammy is unfalsifiable work, and the rate that actually moved your placement was the handful of recipients per thousand who pressed the spam button.