# Suppression lists

A suppression list is the record of addresses that must not be contacted, checked at send time rather than when a list is built. Connect checks suppression, unsubscribe, complaints and do-not-contact in one place before any outreach leaves, and the Connect Assistant cannot clear a do-not-contact entry — removing one is a human decision on purpose.

- **Status:** Available
- **Audience:** both
- **Channels:** email
- **In the app:** #/prospects
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/technology/suppression/

## Why it is a separate thing from a list

Every marketing system already has lists, segments and audiences, and it is tempting to handle opt-outs by removing people from them. That fails the moment a second list exists, and it fails permanently the first time somebody re-imports a spreadsheet exported before the opt-out. The person who unsubscribed in March is back in the audience in June, having done nothing, and there is no record explaining it.

A suppression list inverts the logic: rather than absence from every list, it is presence on one. It is consulted at the moment of sending, after the audience has been assembled, so a re-import cannot defeat it and a new campaign inherits it without anyone remembering to apply it.

That also means the address has to be **kept**, not deleted. Deleting the record of someone who asked not to be contacted destroys the only evidence that would stop you contacting them again — which is why suppression lists are frequently stored as hashes when the underlying address itself is sensitive.

## What belongs on it, and what does not

| Event | Suppress? | Reasoning |
|---|---|---|
| Unsubscribe request | Yes, permanently | The person asked. Scope it to the business, not to one campaign |
| Spam complaint | Yes, permanently | A stronger statement than an unsubscribe, and it damages reputation as well |
| Hard bounce (`5.1.1`, unknown domain) | Yes | The address does not exist; retrying is pure waste |
| Explicit do-not-contact | Yes, and hardest of all | Set by a person for a reason the system may not know |
| Soft bounce (mailbox full) | Not immediately | Transient. Suppress only after it stops being transient |
| Policy rejection (`5.7.1`) | No | The rejection is about the sender. Suppressing the recipient hides the cause |
| No opens for six months | No | Disengagement is a targeting decision, not a prohibition. Mixing the two loses both |

> **Note** Keep the origin and the timestamp with every entry. Months later the only question that matters about a suppression is *who put this here and why*, and a list of bare addresses cannot answer it.

## Does Connect use a suppression list, and where?

Compliance is checked in one place rather than at each call site, so a new outreach path cannot be written that quietly skips it. Suppression, unsubscribe, complaints and do-not-contact are evaluated together before any outreach message leaves.

**Outreach and a reply are two different paths.** A message Connect sends to someone who has not written to you passes the outreach gates. A reply to a customer who wrote to you first is a different path with different gates, and the two are never merged. Keeping them apart is what allows a prohibition on cold contact to be strict without making Connect refuse to answer somebody who is standing at the door asking a question.

A block is stored as a Memory row tagged for the channel — in the tag list, never in the body text, because only the tags are read when directives are resolved. The practical result is that a block set during one conversation holds across channels and across future conversations, rather than expiring with the thread it was set on.

And the Assistant cannot lift a do-not-contact entry. Every other kind of record it can help you edit; this one is deliberately outside its reach, because a hard stop that a conversational instruction can undo is not a hard stop.

## Failure modes worth designing against

**The list is per campaign** — The first cross-campaign send re-contacts everyone who opted out of the other one.
**Suppression is applied at list build** — Anything queued before the opt-out still goes. Check at send time.
**An address is suppressed but a variant is not** — Address normalisation matters: case, plus-addressing and provider-specific dot handling can produce two keys for one human.
**Suppression is easy to clear** — A single mis-click or an over-helpful automation undoes a legal position. Removal should be manual, attributed and rare.
**The suppressed person is also a customer** — Suppression governs outreach. Service mail they are actually waiting for is a different question, answered on [transactional and marketing email](/docs/technology/transactional-vs-marketing/).

## Questions

### Should a suppression stop a reply to someone who emailed us?

Usually not, and Connect does not treat it that way: outreach and replies are separate paths with separate gates. Someone who unsubscribed from marketing and then wrote to ask about an invoice has not asked to be ignored. A do-not-contact entry is the stronger case and is set precisely when the answer should be 'no contact of any kind'.

### Can I remove someone from the suppression list if they ask?

For an ordinary unsubscribe, yes — a person re-subscribing is a normal event, and it should be recorded with the same care as the opt-out. A do-not-contact entry is different: the Assistant cannot clear one at all, and a person doing it should know what the entry was for before they do.

### Does suppression apply across channels?

A block held as a tagged Memory row does, by design — that is why it lives there rather than on a thread. Whether a given opt-out *should* extend from email to phone is a judgement about what the person asked for, and the safe reading of an ambiguous request is the broader one.

## Related

- [One-click unsubscribe](https://connectbyjbrh.com/docs/technology/unsubscribe/)
- [Complaint feedback loops](https://connectbyjbrh.com/docs/technology/feedback-loop/)
- [Bounces](https://connectbyjbrh.com/docs/technology/bounce/)
- [Prospecting in Connect](https://connectbyjbrh.com/docs/prospects/)
- [Memory in Connect](https://connectbyjbrh.com/docs/memory/)

## What this page is based on

- Source pack: email — `docs-source/sources/CHANNELS.md` §1 (compliance checked in one place; blocking as a tagged memory row; outreach and reply as separate paths)
- Connect capability registry (`docs-source/facts.py`) — `suppression_dnc`, `block_directive`
- RFC 3463 — Enhanced Mail System Status Codes, for the bounce classes referenced (https://www.rfc-editor.org/rfc/rfc3463)
