Suppressions

Asked once to stop, and it stops

Bounces, complaints, unsubscribes and a reply that just says stop all land on a list. Every send is checked against it on the way out.

Sending q4-outreachChecked on the way out
132sent12asked to stopYour code passed no list.

One send, 144 recipients. Twelve had asked to stop at some point — a bounce, a complaint, an unsubscribe, a reply — so twelve never got it.

How an address lands on one

Six ways off your list, all of them handled

Five happen without your code running at all.

jana@oldcorp.deDoesn’t exist

550 5.1.1 — user unknown

Hard bounce

Lands on the organisation's list. Nothing tries it again.

Report spam

When the provider reports it, we file it.

Complaint

Filed against the list that message named, the moment it is reported.

Nora · Northwind

Hamburg, DE

Unsubscribe

Unsubscribe link

Ours, hosted, branded. A scanner clicking it suppresses nobody.

NMNorthwind Metalsnora@northwind.ioUnsubscribe

List-Unsubscribe-Post

One-click header

What Gmail and Outlook now ask bulk senders for. Answered for you.

Please stop emailing me.

Unsubscribedread from the words

A reply saying stop

Read as the opt-out it is. The rest of the thread is left alone.

Email preferences

Product updates

suppressions.add()

Your own page

One call, up to a thousand addresses, with a note on where they came from.

Which list

A list per thing somebody can leave

Every send carries a suppression_key — per campaign, per product, per customer — and is checked against that list and the organisation’s. So leaving one list leaves one list, and a hard bounce stops everything.

grace@example.comUnsubscribedfrom product-updates, scope optional

What shipped in August

She left this list · unsubscribe: true

product-updatesSuppressed

Your receipt for invoice 4471

Not on any list she is on

— none —Sent

Reset your password

Not on any list she is on

— none —Sent

Had she marked it as spam instead, the entry would land on product-updates with scope all — nothing on that list reaches her, unsubscribe or not. The receipt and the reset still go.

Sending for your own customers? Give each of them a space, and their opt-outs stay theirs.

In the console

Every list, and what each one has stopped

Suppressions

Addresses we will not send to, and the lists they sit on.

Check an address, or find a list…

Organisation list

Checked on every send

Hard bounces, and everyone who asked the company — rather than one of its lists — to stop. A send naming no key answers to this list alone.

*

9,412 sends stopped · 128,400 checked in 30 days · last send 2m ago

1,284suppressed

Keyed lists

One per suppression_key your sends have named
q4-outreach0.34% complaints

1,204 sends stopped · 21,800 checked in 30 days · last send 6m ago

318suppressed
product-updates

6,388 sends stopped · 96,500 checked in 30 days · last send 1h ago

2,140suppressed
acme-inc

210 sends stopped · 4,120 checked in 30 days · last send yesterday

76suppressed

t.neves@vestra.com

Nothing reaches this address. The organisation’s list is checked on every send, whatever key it names.

Organisation listMarked as spamAll mailLift
q4-outreachUnsubscribedMarketing onlyLift

Type an address, get the whole answer — across every list at once.

Complaints, last 30 days

0.34%

0.1%0.3%

Gmail asks bulk senders for under 0.1%. Past 0.3% providers filter the whole domain, not just this list.

Unsubscribes are the system working. Complaints are the domain.

In your code

Nothing to check before you send

No list to load, no table of your own to join against. The dropped recipients come back on the response.

1emails.sendfiltered before it leaves, nothing to check first
const email = await aiinbx.emails.send({  ...campaign,  suppression_key: "q4-outreach",  unsubscribe: true, // link + one-click headers}) await recordSkipped(email.suppressed)
2suppressions.addfor the opt-out that happened in your app
await aiinbx.suppressions.add({  addresses: ["grace@example.com"],  key: "q4-outreach",  scope: "optional", // marketing only; receipts still go  note: "Unsubscribed from the preferences page",})
3email.unsubscribedso your own database hears about ours
if (event.type === "email.unsubscribed") {  const { address, key, scope, source } = event.data   // "link", "one_click", or "reply" — they wrote back  await recordOptOut(address, key, scope, source)}

Around it

The rest of what a list decides

A send to nobody failsEvery recipient suppressed comes back recipients_suppressed, not a send that never happened.
Receipts stay out of itunsubscribe: true marks a message optional, and a link unsubscribe only stops those. A reply saying stop stops everything.
Taking one offAny entry can come off. The console says what that means first — for a complaint, that the next send risks your domain.
It counts what it stopsHundreds of blocks on one entry means a code path still mailing somebody who left.

Give your product an inbox. The hard parts are already handled.

Get started