Bounces and complaints
When delivery goes wrong, the failure has a category, and the category decides what happens next. MiniMailer converts these signals into a per-domain suppression list automatically, because the worst thing you can do to your sender reputation is keep mailing an address that already told you no.
The categories
- Hard bounce — permanent failure: the address doesn't exist, the domain has no mail server. The address will not start working next week; retrying reads as negligence to mailbox providers.
- Soft bounce — temporary failure: full mailbox, greylisting, a transient server problem. Retried within the delivery window; repeated soft bounces on the same address eventually indicate a dead mailbox.
- Complaint — the recipient marked your message as spam. Their mailbox provider reports it back, and the only correct response is to never mail them again. Complaint rate is the single most damaging reputation signal there is.
- Unsubscribe — the recipient opted out, via the one-click unsubscribe header (RFC 8058, which MiniMailer sets up for you) or your own flow. Honoured immediately.
Each failure fires its webhook (email.bounced, email.complained, email.unsubscribed) as it happens, with the details in the payload.
How suppression works
A suppression is scoped to the (domain, recipient) pair and records why it exists and what it blocks — its scope:
| Reason | Created by | Scope | Removable? |
|---|---|---|---|
hard_bounce |
A permanent delivery failure | all — every send |
No — permanent |
complaint |
A spam complaint | all — every send |
No — permanent |
unsubscribe |
An opt-out | marketing — campaigns |
Yes |
soft_bounce |
Repeated temporary failures | all — every send |
Yes (may also expire on its own) |
manual |
You, via API or dashboard | all — every send |
Yes |
list_import |
A suppression list you imported | all — every send |
Yes |
Every campaign send is checked against the whole list before delivery; transactional sends are blocked only by all-scope entries. The distinction is deliberate: an unsubscribe is an opt-out from your marketing — the recipient still gets transactional mail like receipts and password resets — while a bounce or complaint is a statement about the mailbox itself and stops everything. If an unsubscribed address later hard-bounces or complains, its entry is escalated to a permanent all-sends block. A suppressed recipient is rejected with a 422 at the API instead of being sent; this check is not optional — it is the guardrail that keeps one bad list from burning the domain.
Working with the list
GET /suppressions— browse and filter your suppression list (suppressions:read).DELETE /suppressions/{suppression}— remove a suppression (suppressions:write). Removinghard_bounceandcomplaintsuppressions is refused with a422: a dead address stays dead, and re-mailing a complainer is how spam folders are earned. If a recipient genuinely wants back in after complaining, they can re-engage through your own opt-in flow.- Adding an address manually (
manual) is the right way to honour an opt-out that arrived outside MiniMailer — a support email, a legal request.
AI agents get the same controls through the MCP tools check-suppression-tool and remove-suppression-tool, with the same permanence rules enforced.
Practical guidance
- Watch the rates, not just the events. A handful of hard bounces is normal; a bounce rate above a few percent means the list itself is the problem.
- Import your existing suppressions when migrating from another provider — carrying over your opt-outs is both a legal obligation and cheap reputation insurance.
- Don't fight permanence. The two permanent reasons exist because remailing those addresses has no upside: one can't receive, the other doesn't want to hear from you — and both cost reputation to retry.