Suppression list includes all required sources
Why it matters
A suppression list missing any of its four required sources — unsubscribes, hard bounces, spam complaints, or manual admin adds — has gaps that will cause sends to addresses that should never receive email. CAN-SPAM § 5 mandates honoring opt-outs (unsubscribes); GDPR Art. 21 covers the right to object (maps to unsubscribes and complaints); GDPR Art. 17 covers erasure (maps to manual admin removes); CASL § 6 mirrors CAN-SPAM's unsubscribe requirement. Spam complaints are the most commonly missing source: ESPs surface them via feedback loops that must be explicitly wired to write to the suppression table — they do not suppress automatically unless configured.
Severity rationale
Medium because each missing suppression source creates a specific class of non-compliance (unsubscribes → CAN-SPAM; complaints → GDPR Art. 21) rather than a blanket deliverability failure, but the legal exposure is real.
Remediation
Centralize all four suppression sources through a single addToSuppression function so no source can bypass the global table:
type SuppressionReason = 'unsubscribe' | 'hard_bounce' | 'spam_complaint' | 'manual_add'
async function addToSuppression(email: string, reason: SuppressionReason, addedBy = 'system') {
await db.suppression.upsert({
where: { email: email.toLowerCase().trim() },
create: { email: email.toLowerCase().trim(), reason, added_by: addedBy, suppressed_at: new Date() },
update: { reason, updated_at: new Date() }
})
}
Wire this to: your POST /api/unsubscribe endpoint, your bounce webhook handler (hard bounces only — see ab-000870), your ESP complaint feedback-loop webhook, and your admin contact management UI. Verify all four by querying SELECT DISTINCT reason FROM suppressions — all four values must appear.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Data Quality & List Hygiene Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- external · CAN-SPAM-Sec5 — CAN-SPAM Act §5 — requires functioning opt-out mechanism honored within 10 business days
- gdpr · Art. 17 — GDPR Article 17 — Right to erasure obliges ceasing processing on valid request
- gdpr · Art. 21 — GDPR Article 21 — Right to object requires cessation of processing
- external · CASL-S6 — CASL Section 6 — unsubscribe mechanism required; withdrawal of consent must be processed within 10 business days
- iso-25010:2011 · functional-correctness — Functional Correctness (functional suitability)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from data-quality-list-hygiene·automated