Skip to content
Back to skills

Bounce Complaint Suppression

ASecurity

Close the email feedback loop — classify hard vs soft bounces and spam complaints, enforce a suppression check before every send, and reconcile the ESP's suppression list with your own so you never re-send to a bad address. Reach for this when the user says "we keep emailing bounced addresses", "handle complaints", or "build a suppression list". Used by `email-sending-engineer` (primary).

  • 7 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentsrailsapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 23, 2026

npx -y skills add mcorbett51090/RavenClaude --skill bounce-complaint-suppression --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Bounce Complaint Suppression?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Bounce Complaint Suppression
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mcorbett51090-bounce-complaint-suppression/badge)](https://www.skillsdirectory.com/skills/mcorbett51090-bounce-complaint-suppression)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: bounce-complaint-suppression
description: Close the email feedback loop — classify hard vs soft bounces and spam complaints, enforce a suppression check before every send, and reconcile the ESP's suppression list with your own so you never re-send to a bad address. Reach for this when the user says "we keep emailing bounced addresses", "handle complaints", or "build a suppression list". Used by `email-sending-engineer` (primary).
---

# Skill: bounce-complaint-suppression

> **Invoked by:** `email-sending-engineer` (primary). Pairs with `transactional-email-integration` (which delivers the events) and `deliverability-audit` (list hygiene as a deliverability layer).
>
> **When to invoke:** "we keep sending to addresses that bounce"; "handle the complaint feedback loop"; "build/maintain a suppression list".
>
> **Output:** a classification + suppression model and the pre-send enforcement that keeps the list clean.

## Procedure

1. **Classify the event correctly — the action depends on the type:**
   - **Hard bounce** (mailbox doesn't exist, domain invalid — 5xx permanent) → **suppress immediately and permanently.** Re-sending poisons reputation.
   - **Soft bounce** (mailbox full, server temporarily down — 4xx transient) → retry a bounded number of times over a window; suppress only after repeated failures.
   - **Spam complaint** (FBL — the recipient hit "report spam") → **suppress immediately**, and treat as a strong negative reputation signal. Never email a complainer again.
   - **Unsubscribe** (List-Unsubscribe / one-click) → suppress for the relevant stream, fast.
2. **Make suppression a hard pre-send gate.** Every send path checks the suppression list **before** dispatch — a suppressed address is dropped (and logged), never sent. This check is non-optional and lives at the lowest layer so no caller can bypass it.
3. **Reconcile two lists.** The ESP keeps its own suppression list (it may silently drop) **and** you keep yours. Sync them — pull the ESP's suppressions via API/webhook into your store so your "sent" analytics and the actual deliveries agree, and so a provider switch carries the list.
4. **Scope suppression by stream.** A marketing unsubscribe should not suppress a password-reset (transactional) email — model suppression per stream/subdomain, with a global hard-bounce/complaint suppression that overrides everything.
5. **Track the rates.** Bounce rate and complaint rate are the deliverability vitals ([`../deliverability-audit/SKILL.md`](../deliverability-audit/SKILL.md)). A spike means stop and investigate the source, not push harder.

## Worked example (the data model)

```
suppression(email, reason, stream, suppressed_at)
  reason ∈ { hard_bounce, complaint, unsubscribe, manual }
  stream ∈ { global, marketing, transactional, ... }   -- global overrides all

-- enforced before every send (lowest layer, no bypass):
is_suppressed(email, stream) =
  EXISTS row WHERE email matches AND (stream = 'global' OR stream = :stream)
```

A `hard_bounce` and `complaint` write `stream='global'` (suppress everywhere). An `unsubscribe` from the newsletter writes `stream='marketing'` — receipts still send.

## Guardrails

- **Never** re-send to a hard bounce or a complainer — it's the fastest way to tank a domain's reputation.
- A complaint is worse than a bounce: it's an active negative vote the mailbox provider records. Honor it instantly and globally.
- Don't let an unsubscribe from marketing silently kill transactional mail (or vice-versa) — scope it.
- Reconcile with the ESP's list; relying only on your own (or only on theirs) drifts and re-sends.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…