Suppressions
Addresses that sends skip, after a bounce, a complaint or an unsubscribe.
Each environment has its own suppression list. When you send, every recipient (to, cc and bcc)
with a matching entry is skipped: it gets the status suppressed and an email.suppressed event, and
is never handed to the mail provider. If no recipient is left, the email fails with
all_recipients_suppressed.
Scopes
An entry's scope is * (every email) or a category. A send with
category: "marketing" skips addresses suppressed for * or marketing; a send without a category
only skips * entries.
Automatic entries
A permanent bounce or a complaint adds a * entry for that address, with reason bounce or
complaint and the email_id that caused it. Mailbox simulator addresses
(@simulator.amazonses.com) are never suppressed, so they keep working for tests.
Managing the list
Manage entries in the dashboard (Suppressions) or through the API. Adding an entry for an address and scope that already has one returns the existing entry.
// A recipient unsubscribed from marketing email.
await ...({ : "ada@example.com", : "marketing" });
// Would a marketing email reach them?
const { : } = await ...({
: "ada@example.com",
: "marketing",
});
// They resubscribed.
if (?.) {
for (const of .) {
await ...(.);
}
}Removing an entry lets later sends reach the address again. Remove automatic entries with care: repeatedly sending to addresses that bounce or complain hurts your sending reputation.
Importing and exporting
Move whole lists in and out, for example when you switch from another provider. import takes any
number of entries and sends them 1,000 per request. Each entry is validated on its own: invalid ones
are skipped and reported by their position, and entries already on the list are left unchanged, so
importing the same list again is safe. Imported entries have the reason import.
const { : } = await ...({
: [
{ : "ada@example.com" },
{ : "grace@example.com", : "marketing" },
],
});
// result?.created, result?.existing, result?.invalid
// The whole list as CSV: address,scope,reason,created_at,email_id,id (here only bounces).
const { : } = await ...({ : "bounce" });The dashboard's Suppressions page imports a CSV file of up to 10,000 rows and downloads the same
export. A file needs an address (or email) column and may have a scope (or category)
column; a file without a header row has the address first and an optional scope second. An export
imports again as is. Cells a spreadsheet would run as a formula (starting with =, +, - or @)
are exported with a leading ', which the import removes.