Deliverability
The preflight checklist that should run before every send
Updated 3 September 2026 · 5 min read · SendKernel
A send button should not be an act of faith. Before a message leaves, eight things are worth knowing for certain: who is sending, whether the domain is authenticated, why each recipient is eligible, who has been excluded, whether the volume is expected, and whether recent delivery signals are healthy. The important design decision is that these run as blocks rather than warnings, on one code path shared by the dashboard, the API, and any automation — because a check a script can skip is not a check.
The short version
- Blocking beats warning. A warning that appears above a send button is a warning nobody reads.
- One shared path for every interface, or the API quietly becomes the compliance bypass.
- Suppression must be account-wide, so an unsubscribe cannot be undone by an import into a different list.
- Show the recipient count and the exclusions before the send, not in the report afterwards.
The eight checks
1Sender identity exists
A business or personal name and a real postal address on file. US law requires a physical address in every commercial message, so a send without one is not merely risky, it is unlawful. This is the cheapest check and the one most often deferred to 'later'.
2The domain is authenticated
SPF, DKIM, and DMARC all present and aligned with the From domain. Since Gmail, Yahoo, and Microsoft tightened their bulk sender rules, a missing DMARC record is a rejection rather than a spam-folder penalty, which makes this a hard prerequisite rather than a recommendation.
3The From address belongs to that domain
Easy to get wrong after a domain is removed or renamed, and it fails at the receiving server rather than at your end, so nothing surfaces until delivery has already failed.
4The audience has a recorded consent source
Not a checkbox asserting consent, but a stored answer to how these people opted in. Under GDPR and CASL you may have to demonstrate it, and reconstructing consent after the fact is not possible.
5Suppression has been applied account-wide
Every unsubscribe, hard bounce, and complaint excluded across the entire account, not just the list being mailed. Per-list suppression is how someone who unsubscribed in March receives a campaign in June from a re-import.
6At least one recipient remains
After suppression, the list can be empty. Better to say so plainly than to report a successful send of zero messages.
7The send fits within quota
Daily and monthly limits checked against this specific send, not the account total. A campaign that would exceed the limit halfway through should be refused before it starts rather than truncated in progress.
8Reputation is healthy
Complaint and bounce rates recomputed from delivery events, with a threshold that stops sending. Ours warns at 0.05% complaints and pauses at 0.10%, deliberately tighter than the 0.3% published ceiling, on the reasoning that a paused campaign is recoverable and a burned domain is not.
Why these block instead of warn
A warning above a send button is read once and dismissed forever. Worse, warnings put the compliance decision in the hands of whoever is in the hurry — and the person sending a campaign at five o'clock is exactly the person who will click through a yellow banner without reading it.
Blocks have a real cost, and it is worth stating plainly rather than pretending otherwise: they refuse sends at inconvenient moments, and someone occasionally cannot get a message out because a DNS record has not propagated. That is the trade being made. The alternative is a product where a non-compliant campaign is possible, and where the first time anybody notices is when the domain stops delivering.
One path, or the API becomes the bypass
This is the part that is architectural rather than procedural. If preflight lives in the dashboard's send handler, then the API, the scheduler, and any automation each need their own copy — and copies drift. The version in the API misses a check added six months later, and the compliance guarantee the product advertises becomes untrue in exactly the interface that sends the most volume.
The alternative is one function that every caller must pass through, with no privileged caller and no override flag. Then a non-compliant send is not merely prohibited by policy, it cannot be constructed — and the guarantee holds because there is no second implementation to fall out of step. For what it is worth, that is how ours is built: the UI, the assistant, and the public API all reach sending through the same preflight, and there is no bypass parameter to find.
What to show the sender before they commit
- The exact number of recipients, after suppression rather than before.
- How many were excluded, and why — unsubscribed, bounced, complained, duplicate.
- The From address and the subject line, rendered as the recipient will see them.
- Whatever is currently blocking the send, in plain language, with the specific fix.
- That the action cannot be undone, which is true and worth saying.
The exclusion count is the item people leave out and the one that catches real mistakes. A campaign showing 1,284 recipients and 37 excluded is unremarkable. The same campaign showing 1,284 recipients and 4,000 excluded means an import went wrong, and that is worth knowing thirty seconds before the send rather than in the report afterwards.
Questions people actually ask
- What should block an email send outright?
- Missing sender identity or postal address, an unverified or unauthenticated sending domain, a From address outside that domain, an audience with no consent record, an empty recipient list after suppression, a send that exceeds quota, and complaint or bounce rates over threshold. Each of these produces either a legal problem or a delivery failure, so warning about them and sending anyway is the worst of both options.
- Should the API run the same checks as the dashboard?
- Yes, and ideally through the same code rather than an equivalent copy. Two implementations drift, and the one that falls behind is invariably the API — which is also the one sending the most volume with the least human oversight. A single shared path is the only version of this guarantee that stays true.
- Is per-list suppression enough?
- No. Someone who unsubscribes has withdrawn consent from you, not from one list, and per-list suppression is precisely how they receive mail again after a re-import into a different audience. Suppression should be account-wide and permanent, and suppressed addresses should be stored free of charge so nobody has a billing incentive to delete them.
- What complaint rate should stop a send?
- The published ceiling at the major providers is 0.3%, but that is the cliff rather than the operating limit. Complaint data arrives with a delay, so a system that only reacts at 0.3% is reacting after the damage. Warning near 0.1% and pausing well before 0.3% leaves room to recover.
See a preflight result on your own account
Create a draft on the free plan and the send page shows the full preflight: who it reaches, who is excluded, and anything blocking it — before you commit to anything.
Start freeRead next
The bulk sender rules for Gmail, Yahoo, and Microsoft, and what happens when you miss one
The 5,000-a-day threshold, the 0.3% complaint ceiling, and the authentication every mailbox provider now requires — with the failure codes you will see.
Sending transactional email over an API without regretting it later
The integration decisions that are painful to reverse: retries, idempotency, bounce handling, and keeping receipts away from marketing mail.
Why your email goes to spam, in the order worth checking
A diagnostic order for spam-folder problems: authentication first, list quality second, content last. Most of the internet has this sequence backwards.