Transactional email
Email set · 14 checks
Fourteen checks for email triggered by your customer's own action and carrying data they are waiting for — receipts, order and shipping confirmations, password resets, verification codes, invoices. Seven of them block. The test we apply is not "is this untidy" but "does the recipient end up unable to do the thing they came to do": a merge tag that never filled in, a dead reset link, a verification code with no plain-text version, images with no alt text in an inbox that blocks images. Everything else reports. ⚠ Run this against a test send, not a live one. Three of these checks follow the links and images in your email, and in transactional mail those links do things — they confirm addresses, sign people in, authenticate order access. Validating a real message addressed to a real person can consume a one-time token or register activity in your own systems. Deliberately absent: the unsubscribe link (you cannot opt out of the mail that runs your account), campaign tracking checks (there is no campaign to attribute a receipt to), and the call-to-action assertion (half of transactional senders correctly have no CTA at all).
Checks in this set
No placeholder / merge-tag text
RequiredYour customer is waiting for this email and about to act on it, and it carries more merge fields than anything else you send — order number, amount, date, tracking link, reset link. This catches the ones that did not fill in. That is why it blocks. A receipt showing `{{order_total}}` or a confirmation whose button reads `%%reset_password_link%%` is worse than sending nothing: the recipient cannot complete what they started, and they learn not to trust your mail. We found exactly that in real mail — an unrendered reset link inside an email titled "NEW ACCOUNT CONFIRMATION". Across real transactional email we find this in about one message in thirty, roughly ten times the rate in marketing campaigns, because transactional templates have far more to fill in and get far less proofreading. Runs with no configuration. The default patterns cover the documented merge delimiters — `{{tokens}}`, `%%tokens%%`, `*|MAILCHIMP|*` — plus placeholder filler, across your subject line, preview text and body. If your platform uses its own delimiters, add them. One limit worth stating: it finds tokens that never filled in, not values that filled in wrongly. A total rendering as `$0.00` is indistinguishable from free shipping, and free shipping is common — so this check will not catch it.
Links valid, reachable, and correctly redirected
RequiredA dead link in a transactional email is a total failure. Your customer clicked something, they are waiting, and the reset link, the tracking link or the "view your order" button is the entire payload — there is no second touch and no campaign to make it up on. **Run this against a test send only.** This check follows the links in your email, and in transactional mail the links *do* things: they confirm addresses, sign people in, authenticate order access. Links whose path names an account action — auth, authenticate, verify, confirm, activate, revoke, reset, unlock, magic, passwordless — are refused before any request is made, and listed in the result with the reason, so the shapes we can recognise are no longer touched. Treat that as a mitigation, not a guarantee: the rule reads the shape of a URL, so an action endpoint behind a neutral path is still fetched, and every ESP click-redirector is still followed. We have seen this in shipped mail — a "this isn't my account" link that revokes the recipient's own email verification. Point it at a test message with test data. Never at a live send. Links are inspected with HEAD only, and the GET fallback is suppressed: a destination that refuses HEAD is reported as *unverifiable* rather than re-requested with GET. RFC 9110 requires HEAD to be safe, but Express routes it into the GET handler, Rack strips the body after the action has already run, and Django aliases head to get — so on a real framework the only reliable protection is not making the second request. Within that constraint it catches what proofreading cannot: a personalisation token that never resolved inside an href (`{{...}}`, `%%...%%`), a scheme-less URL that Outlook.com silently strips, an empty or bare-`#` link, and destinations that are provably dead. In real transactional mail we found all three, including a `%%track%%` token that never rendered, sitting inside the href of a "Confirm your email" message. None of that requires the network — the source layer is pure and always safe. Failures are trustworthy by design. Bot-protection responses (401/403/429) are reported as *unverifiable* rather than failed, because Cloudflare-class protection serves those to automated checkers and never to a human with a browser; transient errors are retried once before any verdict.
From-domain match
RequiredChecks that the `From:` address on your transactional mail is a domain you actually own, using DMARC relaxed alignment — `mail.yourbrand.com` matches `yourbrand.com`, because only whoever controls your DNS can create that subdomain, while `yourbrand-mail.com` never matches. This matters more here than on a campaign. A password reset or an order confirmation is the email people are primed to act on without thinking, and the sending domain is the only thing distinguishing yours from a convincing fake. Every time your own mail arrives from an unexpected domain, you teach your customers that unfamiliar senders are normal — which is exactly the habit a phishing attempt needs. **List every domain you send from, including the ones your platform sends on your behalf.** This is where transactional email catches people out: dedicated transactional streams often go out from a separate registered domain rather than a subdomain — `lyftmail.com` for Lyft, `hulumail.com` for Hulu — and a separate domain does not align, however similar it looks. If your ESP sends from its own domain, list that too. Until you provide the list, the check is skipped rather than failed, and it is not charged. One limit: this reads the `From:` header against your list. It does not verify SPF, DKIM or DMARC, and it cannot detect someone else spoofing you — it catches your own mail leaving from a domain you did not intend.
Plain-text alternative part present
RequiredEvery email you send should carry a plain-text version alongside the HTML one. This confirms yours does, and that it is not empty. It matters more for transactional mail than for a campaign, because of what transactional mail carries. A verification code, an order number, a tracking link — these are the payload, not the packaging. Anywhere the HTML does not render, a plain-text part is the difference between the recipient getting what they asked for and being stuck: notification previews, smartwatches, plain-text-only corporate clients, and screen readers all read it. We found real login-verification emails shipping with no plain-text part at all, which means the code exists only inside markup the reader may never see. About a third of the transactional senders we measured have this defect. It is also a long-standing deliverability signal — an HTML-only message is one of the oldest and cheapest things a spam filter can hold against you. Runs with no configuration. A quick warning about what a pass means: we confirm a plain-text part is present and non-empty, not that it says the same thing as your HTML. A stub reading "This email requires an HTML-capable client" passes this check and helps nobody.
Images have usable ALT text
RequiredChecks that the images in your email carry alt text a person can actually use — not missing, not `"image"`, not an unlabelled linked graphic. This blocks, and the reason is the law rather than good practice. The European Accessibility Act has applied since 28 June 2025, enforced through EN 301 549, which adopts WCAG 2.1 AA. It covers services sold to EU consumers, and transactional email is in scope — an order confirmation is part of the service you sold, not an advertisement for it. There is a practical reason too. Corporate Outlook blocks images by default, so alt text is what a large share of your recipients actually see. Most transactional email survives that because the order number is in the text — about 88% of the mail we checked — but roughly one sender in five puts details only in an image, and for their customers a blocked image is a receipt with the important part missing. Expect to fail this the first time. Across real transactional email, only about a third of images carry usable alt text at all. Most of the fix is one pass over your template, not per-send work — the same logo, the same icons, the same header image, every time. An email with no images passes at no cost. Runs with no configuration and makes no model call.
Images render and scale correctly
RequiredResolves every image your email references — attached, embedded, or hosted — and checks the dimensions you declared against the file's real ones. It catches images that cannot be fetched at all, declared sizes that contradict the natural aspect ratio (the squashed logo), and images upscaled far enough to render soft. **Run this against a test send only.** It fetches every image, and 96% of transactional email carries a 1x1 open-tracking pixel — so on a live send this will register an open you did not earn, on an audience small enough for that to visibly distort your own numbers. One caveat we would rather state than have you discover: the upscale rule currently flags differences too small to see — a 28px icon declared at 32px will be reported. We are fixing the threshold. Until then, treat upscale findings as worth a look rather than as defects, and trust the unresolvable-image and distortion findings, which are exact. An email with no images passes at no cost.
Image sources resolve and are permitted
RequiredChecks that every image your email points at actually resolves to real image bytes over a sound path. It catches dead references, dangling content-ids for images you meant to attach, redirect chains that run past five hops, and http-only sources whose https upgrade fails — that last one is why images pass in your test client and break for the recipient. **Run this against a test send only**, for the same reason as the image-rendering check: it fetches every image, and almost all transactional email carries an open-tracking pixel. Optionally restricts images to hosts you approve, checked at the original source and at the final redirect destination. Leave the list empty and there is no host restriction. It overlaps the image-rendering check on unresolvable images, so a broken URL will be reported by both. Their unique halves differ: this one owns the delivery path, that one owns dimensions. An email with no images passes at no cost.
Layout not broken at any viewport
RecommendedJudged from the rendered screenshot at every viewport you selected — mobile, tablet and desktop, in both Gmail and Outlook — reporting what specifically broke rather than a bare pass or fail. Transactional email is opened on a phone more than anything else you send: the notification arrives and the person taps it. That is where layout breaks live. Across our own runs, every failure we have recorded was at mobile or tablet width and none at desktop — an email that looks correct on your monitor is not evidence about the screen your customer is holding. Outlook is the other half of the risk, because it renders through the Word engine and breaks structures that are perfectly safe in a browser. This is the check that makes your bill jump, and you should know why before you choose this tier. Most of the others read your email's source and cost a credit each. This one has to actually render your email in a real mailbox, at three widths, in two clients — so it carries the cost of the renders as well as the judgement. It reports rather than blocks, deliberately. It can tell you something is cut off; it cannot tell you whether the cut-off thing was a legal footnote or your "Reset password" button. That call is yours.
Images unclipped and displayed properly
RecommendedJudged visually per client, and the question is not whether an image is cropped but whether the crop destroys its meaning — text cut off inside an image, a truncated product shot, framing broken badly enough to change what the picture communicates. Tight but deliberate crops pass. A clipped image in a receipt is not cosmetic when the image is the product your customer just bought, or a QR code they need at a counter, or a map of where their parcel is. Those are the cases worth paying a render to catch. An email with no meaningful images passes at no cost.
Subject line within length limit
RecommendedFlags subject lines longer than 60 characters. For transactional mail the subject is not a headline, it is a label — the thing your customer scans for in a crowded inbox and searches for weeks later when they need the receipt. Which is why what matters most here is *where your order number sits*, not the total length. Mobile clients cut the subject at roughly 35–40 characters, and this check's limit is 60 — so it will pass subjects whose identifier is already invisible on a phone. Read a pass as "not obviously too long", never as "your customer can see the order number". Front-load it: **"Order #4821 shipped — arriving Tuesday"** survives the cut; **"Your order from Acme Supply Co. has shipped, #4821"** does not. Most transactional senders already do this well — in real mail we see the identifier survive the clip about 97% of the time. This is a cheap safety net for the few that do not, not a common failure. Runs with no configuration, and it cannot tell you a subject is too vague or too short. That judgement stays yours.
Preheader / inbox preview text intentional
RecommendedThe line of text beside your subject in the inbox is the second thing your customer reads, and for transactional mail it is often all they need: *"Order #4821 has been delivered"* answers the question without them opening anything. This predicts what that line will actually show and checks that your own boilerplate has not got in front of it. The common failure is a "View in browser" link sitting at the top of the template, which then becomes the first thing in the preview — we have found it on a new-sign-in security alert and on an account welcome, in both cases pushing the actual message out of view. It also catches leaked merge tokens, bare URLs, and hidden-preheader padding characters that leak into your plain-text part as literal `͏` garbage. **You almost certainly do not need to add a hidden preheader block.** Fewer than one in ten of the real transactional emails we checked uses one, and they do not need it — the first visible line of a shipping notice or a receipt is already the confirmation. If your preview is wrong, the fix is usually to move boilerplate below your opening line, not to bolt a preheader on top. Runs with no configuration. One thing it does not check: whether your preview is *appropriate* to show. We have seen account emails put the recipient's own email address in the preview, where anyone glancing at their phone can read it — this check will not flag that.
Physical mailing address present
RecommendedReports whether your email carries a physical postal address. It reports rather than blocks, because most transactional mail genuinely does not need one — and yours may well be fine without it. **The exemption is real.** CAN-SPAM's postal-address duty applies to *commercial* email, and a message confirming a transaction the recipient agreed to is excluded (15 U.S.C. §7702(2)(B), §7704(a)(5)(A)(iii)). Across real transactional mail we found about 99% qualifying cleanly. Roughly half of senders include no address, and most of them are compliant. **The exemption is also per-message, and easy to lose without noticing.** Under 16 CFR §316.3 your receipt becomes commercial if a recipient reading the subject line would think it contains an ad, **or** if the transactional content is not at the beginning of the body. A promotional nav bar above the order summary is enough — we found a receipt sitting behind a `COUPONS · NEW TOOLS · DEALS` strip. Whoever added that block changed the email's legal status, and penalties run to $53,088 per email. So the question to ask is not "am I transactional?" but "is there promotional content in here, and is my receipt still at the top?" If there is promotional content, treat the message as marketing — it owes an address, an unsubscribe, and the rest of that standard. Note also that Canada does not offer this exemption: CASL's transactional carve-out removes only the *consent* requirement, and its identification rules still ask for a mailing address. One reason to include an address even when exempt: transactional email is the most impersonated mail there is, and a real postal address is a trust signal a phishing copy of your order confirmation usually will not carry. The check anchors on a postcode that agrees with its region, and recognises US, UK, Canadian, European, PO box, private mailbox and military formats. It fails an incomplete address on purpose — a city name alone is not an address.
Brand logo visible in header
RecommendedConfirms your logo is visible and fully rendered at the top of the email, in Gmail and Outlook, on mobile and desktop. On a campaign this is a branding question. On transactional mail it is closer to a security one. Order confirmations, shipping notices and password resets are the most impersonated email there is — nobody bothers faking a newsletter. Your customer's ability to spot a fake depends on knowing what the real one looks like, and every unbranded receipt you send erodes that a little. It also catches the plain failure: a logo hosted somewhere that stopped resolving, rendering as a broken-image icon or an empty box at the top of every receipt you send. That is the kind of defect nobody notices internally, because your own mail client has the image cached. It reports rather than blocks. A missing logo is a real defect and not a fatal one.
Email opens fully in Gmail
RequiredGmail stops rendering a message at roughly 102KB of HTML and hides the rest behind a "View entire message" link. On a receipt or an order confirmation, the part below that cut is usually the part the reader came back for — the totals, the support route, the tracking link. 2.6% of a real inbox is over the limit. Transactional mail is rarely the culprit, because it is generated rather than designed; when it happens it is almost always an item table that grew with the order, so the biggest orders are the ones that clip. It blocks. A receipt the reader has to expand to finish reading is a receipt that did not do its job, and the fix is never a redesign — it is finding the one thing that made the document too big.
Run the Transactional email set
One call runs every check above and returns a single verdict.