Suppressions
The addresses your organization will not send to — read, add, import, export, and remove them.
Every organization has a suppression list: addresses we refuse to send to. A send
to a suppressed address is skipped silently and the email is recorded with status
suppressed; if every recipient of a send is suppressed, the
request fails with ALL_SUPPRESSED.
Addresses land on the list two ways:
| Reason | Added by |
|---|---|
bounce | Automatically, on a hard bounce (a permanent rejection from the receiving server). |
complaint | Automatically, when a recipient reports the message as spam. |
manual | By you, via the API or the dashboard. |
The list is per-organization and applies across every API key and sending domain you own. It is never shared between organizations.
Removing an address that hard-bounced or complained lets you mail it again. Doing that repeatedly is what damages a sender's reputation — remove an entry when you know the address was fixed or the complaint was a mistake, not to retry a list that is failing.
Suppression applies to live sending only. Test-mode API keys can read the list but cannot modify it.
List suppressions
/suppressions| Parameter | Type | Description |
|---|---|---|
email | string | Filter to addresses containing this substring. Pass a domain ("@acme.com") to see every suppressed address there. |
reason | string | Filter by reason: bounce, complaint, or manual. |
cursor | string (UUID) | Pagination cursor — pass next_cursor from the previous response. |
limit | number | Results per page. Default: 50. Max: 100. |
curl "https://api.eusend.dev/suppressions?reason=bounce&limit=50" \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx"{
"data": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c1d-0e9f8a7b6c5d",
"email": "[email protected]",
"reason": "bounce",
"created_at": "2026-05-20T10:00:00.000Z"
}
],
"next_cursor": null
}Add an address
/suppressions| Parameter | Type | Description |
|---|---|---|
emailrequired | string | The address to suppress. |
reason | string | bounce, complaint, or manual. Defaults to manual. |
curl -X POST https://api.eusend.dev/suppressions \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]" }'Returns 201 with the new entry. If the address is already suppressed the call
returns 200 with the existing entry — an add never overwrites the reason an
address was suppressed for, so a manual add cannot mask a real bounce.
Import a list
/suppressions/batchUp to 1000 addresses per call. Items may be bare strings or objects, so a column lifted straight out of a CSV works as-is.
curl -X POST https://api.eusend.dev/suppressions/batch \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"emails": [
"[email protected]",
{ "email": "[email protected]", "reason": "complaint" }
]
}'{
"count": 2,
"already_suppressed": 0,
"duplicates": 0
}count is what was written, already_suppressed was on the list before, and
duplicates is how many rows the payload repeated. The three add up to the number
of items you sent.
Migrating from another provider? Export their suppression list and import it here before your first send, so addresses that already bounced or complained don't get a fresh attempt from a new IP. The dashboard has a CSV importer that handles the export formats from SendGrid, Mailgun, Postmark, and SES.
Remove an address
/suppressions/:idThe path accepts either the entry id or the address itself, so you can un-suppress
from your own records without looking up an id first.
curl -X DELETE https://api.eusend.dev/suppressions/[email protected] \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx"{ "deleted": 1 }Returns 404 if the address is not on the list.
Export
/suppressions/exportReturns the whole list as CSV (email,reason,created_at), streamed — safe to call
on a list of any size.
curl "https://api.eusend.dev/suppressions/export" \
-H "Authorization: Bearer eu_live_xxxxxxxxxxxx" \
-o suppressions.csv