Pre-send QA: 20 checks that save your campaign
Every email team has a horror story. A broken link sent to 80,000 people. A subject line that still reads "[TEST] FW: final v3 REAL". A personalization tag that greeted half the list with "Hi, {first_name}". It happens at companies of every size, and the root cause is almost always the same: no checklist, or a checklist that nobody follows.
Why a pre-send checklist matters
Email is unforgiving. There is no "edit after publish" button. Once you hit send, the message exists in inboxes, cached on servers, forwarded to colleagues. A typo on a blog post is a quiet fix. A typo in a subject line seen by 50,000 people is a support ticket avalanche and a screenshot on social media.
The 20 checks below turn "ready to send?" from a gut feeling into something you can verify. Most of them are quick, and a good half can be handed to a script.
Run through them in order. The sequence matters: content first, then technical, then delivery infrastructure. Fixing a broken link does little good if a big chunk of the list is dead addresses.
Content & copy
Subject line: length, clarity, no leftover test text
Phones cut long subject lines short, so put the point in the first few words. As a rule of thumb rather than a rule, aim for roughly 50 characters or fewer. Read it out loud. If it sounds like something you would skip in your own inbox, rewrite it. Search for "test", "draft", "v2". They survive into production more often than anyone admits.
Preheader text
If you leave the preheader empty, the email client pulls the first line of body text, often "View in browser" or "Having trouble viewing this email?". That is wasted real estate. Write a line that adds to the subject instead of repeating it. Somewhere around 40 to 90 characters is a fair guide; clients don't agree on an exact cutoff.
Personalization tokens
Send a test to yourself and check every dynamic field. What does the email look like when first_name is empty? If your fallback is "there" and the result reads "Hi there," that is fine. If the fallback is missing and it reads "Hi ," with a hanging comma, fix it before sending.
Spelling and grammar
Run a spellcheck. Then have a second person read it. Automated tools catch "teh". They do not catch "We are excited to announce our new produce" when you meant "product".
CTA: one primary action, visible without scrolling
People skim an email in a few seconds. In that time, can they tell what you want them to do? One button, above the fold. Repeat it at the bottom if the email is long, but the first instance needs to be visible immediately.
Links & images
Every link works
Click every single one. Hovering is not enough. Check that the destination page loads, that tracking redirects resolve, and that UTM parameters are correct. A broken main CTA link means the entire campaign is wasted.
Unsubscribe link present and functional
CAN-SPAM requires every commercial email to carry a working way to opt out and gives you 10 business days to honor the request. In the EU, GDPR Article 7(3) lets people withdraw consent at any time and says withdrawing must be as easy as giving consent. Since February 2024 Gmail and Yahoo also expect bulk senders to support one-click unsubscribe through the List-Unsubscribe and List-Unsubscribe-Post headers (RFC 8058), plus a visible link in the body. Yahoo asks for unsubscribes to be honored within two days. Test both parts: click the link, then look for the headers in the raw source of your test message.
Images load, have alt text, and look right without images
Outlook does not download pictures from the internet until the recipient allows it, and most other clients let people switch remote images off. Your email needs to make sense with empty rectangles where the images should be. For that reader, alt text is the only hint of what was there.
Design & rendering
Mobile rendering
Send a test to your phone. Check that text is readable without pinching, buttons are tappable with a thumb, and nothing overflows horizontally. Test at least the Gmail app, Apple Mail and Outlook mobile. Our piece on rendering across clients covers where they differ.
Dark mode
Dark mode inverts or adjusts colors in ways you did not plan for. A logo with a transparent background disappears. Light gray text on white becomes invisible on dark. Turn on dark mode and look at the email. If the CTA button vanishes, you have a problem, and the dark mode design guide shows how to build for it up front.
Plain-text version
Some clients default to plain text. SpamAssassin, for one, has a rule called MPART_ALT_DIFF that adds points when the HTML and plain-text parts differ a lot. If your ESP auto-generates the plain-text version, review it. Auto-generated text from complex HTML layouts often looks like garbage.
List & segmentation
Correct segment selected
Double-check the segment name, size, and filters. "All subscribers" and "Active subscribers last 90 days" can differ in size several times over. Sending a win-back email to your most active users is embarrassing. Sending a premium offer to your entire list instead of paying customers is expensive.
List is validated
When was the last time you ran this list through a validator? The longer it sits, the more of it stops working. People change jobs, abandon inboxes, get their accounts deleted. A pass through uChecker before sending sorts addresses into good, bad and unknown, and gives a reason for each bad one: a syntax error or a server rejection (a domain that doesn't exist lands there too). A live spam trap that behaves like an ordinary mailbox will not show up in any check, though. How you collect the list is what keeps those out.
Suppression lists applied
Unsubscribes, hard bounces, spam complainers and legal opt-outs all have to be excluded. Most ESPs handle this automatically, but if you imported a list or switched platforms recently, verify that suppressions carried over. Sending to a previous complainer is one of the fastest ways to tank domain reputation.
Technical & deliverability
From name and reply-to address
The from name is the first thing people see. Is it your brand name, a person at your company, or a generic "noreply"? Make sure it matches what the recipient expects. And if someone replies, does the reply-to go somewhere that is actually monitored?
SPF, DKIM, DMARC are passing
Send a test to a Gmail address. Open it, click the three dots, select "Show original." You should see SPF: PASS, DKIM: PASS, DMARC: PASS. If any of these fail, fix the DNS records before sending to your full list. You can paste the same headers into our email header analyzer. Since February 2024 Gmail has required all three from anyone sending more than 5,000 messages a day to Gmail accounts, with the From domain aligned to the SPF or DKIM domain. Yahoo requires SPF, DKIM and DMARC from bulk senders too, but does not put a number on what counts as bulk.
Spam score check
Run the email through Mail Tester or GlockApps before sending, and read the list of deductions rather than the headline number. Spammy phrases, missing headers, links to blocklisted domains. Mail Tester scores out of 10 and names 10/10 as the goal; where you draw the line for worry is a rule of thumb, not a rule. Fixing the deductions before sending is easier than dealing with deliverability afterwards.
Keep in mind that a tester scores your email against its own rules. Gmail and Outlook keep their filters private, and they weigh domain reputation, which is nowhere in the message itself. The same email can land in different folders for a sender with years of history and for a new domain still warming up.
Tracking and analytics
Are open tracking and click tracking enabled? Are UTM parameters on every link? Do they match the campaign name you will look for in Google Analytics later? A campaign you cannot measure is a campaign you cannot improve.
Send time and time zone
Is the scheduled time in your time zone or the recipients'? Sending at 10:00 AM EST to a list that is mostly in Moscow means it arrives at 6:00 PM. If your ESP supports send-time optimization, turn it on. If not, at least make sure you are not sending at 3 AM local time for your main audience.
Final test send
Send the final version to yourself and at least one colleague. Not a preview, but an actual send through the production pipeline. Open it on phone, desktop, and webmail. This is the last chance to catch everything the previous 19 checks missed.
The goal of a QA checklist is not perfection. It is catching the obvious mistakes that feel catastrophic once they reach 50,000 inboxes. Fifteen minutes of checking saves hours of damage control.
Quick reference: check order
- Subject line and preheader read well, no junk words
- Personalization fallbacks work
- Copy proofread by a second person
- One CTA button, visible immediately
- Every link clicked and resolving correctly
- Unsubscribe link and one-click header in place
- Images load and have alt text
- Mobile rendering tested on a real device
- Nothing disappears in dark mode
- Plain-text version is readable
- Right segment, right size
- List recently validated
- Suppressions applied
- From name and reply-to correct
- SPF, DKIM and DMARC all PASS
- Spam tester deductions reviewed
- Tracking and UTM in place
- Send time set for the right time zone
- Test send opened on phone and desktop
- Colleague has reviewed and approved
Which checks you can automate
Plenty of the list above is clerical work, and clerical work is where people get sloppy first. Three campaigns a week plus a handful of triggered flows already means more email variants than anyone will click through by hand. So the mechanical checks go to a script or a service. Judgment calls stay with a person.
Links and HTML
A crawler requests every URL, follows each redirect chain to its end and records the final status code. A 200 proves less than it seems. The page can be a soft 404, a "nothing found" placeholder served with a normal status, which is why it pays to compare the landing page title with the link text; a wrong URL pasted into the button shows up right away. The same pass can check UTM tags against your campaign naming scheme. For the HTML, a linter is the start, and a list of known email client quirks is the rest, because perfectly valid markup can still fall apart in Outlook for Windows.
Rendering
Litmus and Email on Acid take screenshots of your email in a long list of clients. Paging through dozens of them is tedious. Let software diff each shot against the design and you only look at what changed, such as overlapping blocks, clipped buttons or text that vanished on a dark background.
What a language model is good for, and what it is not
An LLM makes a decent second reader. Hand it the assembled email and ask it to flag a subject line that promises something the body never delivers, a CTA buried in the third paragraph, images without alt text, or a tone that is too stiff for a welcome series. Paste in a few past campaigns and it will also notice when the new one drifts from your usual voice. What to do about any of it is still your call.
It cannot tell you what Gmail's or Outlook's spam filter will decide, for the same reason a spam tester can't (see the spam score check above). Services that quote an "inbox placement probability" score you against their own rules and seed mailboxes. Useful as a hint, not as a promise.
Two rules for the pipeline
Test the assembled email, not the template. A template has no merged names, no conditional blocks, no dynamic products, and those are exactly the parts that break. Build the message for a couple of test subscribers (one with a first name, one without) and run every check on those.
A critical failure should block the send, not raise a warning. Near a deadline, warnings get dismissed unread. If the main link is broken, the unsubscribe header is missing or DMARC fails, the send button should simply not work.
The list belongs in the same run
A flawless email sent to a neglected list still collects bounces and still dents your domain reputation. Checking the segment fits naturally into the same step as the content checks and can run alongside them. In uChecker you upload the list to the dashboard as a .txt file or paste it in, or send it through the API. Every address comes back good, bad or unknown. Drop the bad ones. Look at unknown separately: it holds catch-all domains that accept any address and servers that never answered, and those are worth rechecking later.
Sources
- Google: Email sender guidelines
- Yahoo Sender Hub: Sender requirements and recommendations
- RFC 8058: Signaling One-Click Functionality for List Email Headers
- CAN-SPAM, 15 U.S.C. § 7704: opt-out requirements
- Microsoft: Block or unblock automatic picture downloads in Outlook
- Gmail Help: Trace an email with its full header
- SpamAssassin rules: MPART_ALT_DIFF
- Mail Tester: FAQ (scoring)
- GDPR (Regulation (EU) 2016/679), Article 7(3): withdrawal of consent
“List is validated” is the check to settle before you hit send. Upload your list to uChecker. The first 100 checks are free.
Mark Avrilov · Author
Published Updated
