Suppression
The suppression list is the set of email addresses that must never be sent to: unsubscribes, bounces, and addresses added by hand. It is enforced automatically across campaigns and the lead export/push endpoints: a suppressed address is skipped, not queued. In the dashboard the list is called Do not contact.
What gets suppressed automatically
You rarely need to add anything yourself. Warmerly adds an address to the list when:
| Event | Reason recorded | Scope |
|---|---|---|
| A lead uses the unsubscribe link or the one-click unsubscribe header in a campaign email | unsubscribed | Your workspace |
| A lead replies with an unmistakable unsubscribe request (the opt-out path for mailboxes that send without our link) | unsubscribed | Your workspace |
| A campaign email hard-bounces, or the receiving server refuses it as an address that does not exist | bounced | All Warmerly workspaces |
| A recipient files a spam complaint that Warmerly can verify | complained | Your workspace and all workspaces |
| A transactional email hard-bounces or draws a complaint, or the same address soft-bounces twice in a row | bounced or complained | Your workspace |
| You or a teammate add it by hand, through the dashboard, the API or an AI assistant | manual | Your workspace |
A dead mailbox is suppressed for every workspace, because no one can reach it. That platform-wide list is not visible to customers. When one of your leads matches it, the lead is shown as Unavailable mailbox, which does not reveal who else mailed the address. A refusal that is about your message or sending reputation (a spam-filter or blocklist rejection) is not treated as a dead address and does not suppress anyone.
A reply such as "not interested" stops that lead's sequence but does not put them on the list. See What stops a campaign sequence for a lead?.
How suppression works with campaigns
Suppression is workspace-wide, not per campaign or per project. An opt-out holds across every campaign and every mailbox in the workspace, including campaigns you create later.
Warmerly checks the recipient right before each email is sent, so an address added a second ago is already honored. A suppressed lead is not sent to: its status becomes Unsubscribed or Unavailable mailbox depending on why the address is listed, and its sequence stops. Importing the same address again into another campaign does not bypass the list.
Verification is separate. Email verification checks whether an address can receive mail, and does not read or change the suppression list. Verify lists before you import them to keep bounces low, and rely on the list to honor opt-outs.
The list is write-only
POST /suppression is the only customer-callable endpoint on this resource. Adding an
address works with your API key and in the dashboard at Settings > Do not contact.
Listing, exporting and removing are staff-only and return 404 not_found for a customer
key, including an Agency one.
That split is deliberate. The list aggregates bounce evidence across every tenant, so enumerating or exporting it would expose which addresses other customers have been mailing. Adding stays open because it has to: someone who says "stop emailing me" on a call must be suppressible immediately, not after a support ticket.
If you need an address taken off the list, contact support since removal means campaigns may mail that person again, so it stays with operators and stays audit-logged.
404 here means "not available to you", not "no suppression list exists". It is
deliberately indistinguishable from a missing route.
Add addresses
/suppressionRequires X-Api-Key. Not project-scoped. The list applies to your whole active
workspace (the same one the dashboard has selected), not a single project. Send
X-Workspace-Id to choose the workspace explicitly.
| Field | Type | Required | Description |
|---|---|---|---|
emails | string (1-1,000,000 chars) | Yes | A blob of addresses separated by commas, semicolons, tabs, or newlines. Tolerates Name <a@b.com> formatting and a leading email/email_address CSV header, so you can paste a raw CSV column unedited. |
Up to 5,000 addresses per request. Every address added this way is recorded with
reason: "manual"; the unsubscribed and bounced reasons are set only by Warmerly
itself (the unsubscribe link and the bounce classifier), so a hand-typed address is never
attributed to either.
curl -X POST https://app.warmerly.com/api/v1/suppression \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "emails": "jane@example.com, john@example.com" }'201 Created:
{ "added": 2, "alreadyPresent": 0, "invalid": [] }added is new rows inserted; alreadyPresent is addresses already on the list (adding one
twice is a no-op); invalid lists tokens that looked like an email attempt (contained @)
but failed validation.
Errors:
| Status | message | When |
|---|---|---|
400 | invalid_body | emails missing, empty, or over 1,000,000 characters. |
400 | no_valid_emails | Nothing in emails parsed as a valid address. details.invalid samples up to 20 of the rejected tokens. |
400 | too_many_emails | More than 5,000 addresses parsed. details carries { max, received }. |
Every add is recorded in the workspace audit log as suppression.added (removals, when
staff perform them, as suppression.removed).
Other ways to add addresses
- Dashboard. Open Settings > Do not contact, paste addresses into Email addresses (one per line, or separated by commas; a pasted CSV column works) and click Add to do-not-contact. A toast reports how many were added, how many were already suppressed and how many were skipped as invalid.
- AI assistants. The
suppress_emailstool on the MCP server adds up to 500 addresses per call to the connected workspace, asmanual. It stays available while a workspace is billing-locked, because it only ever stops mail. - Bulk import. There is no separate import endpoint. For a large list, split it into batches
of up to 5,000 addresses and call
POST /suppressiononce per batch. Re-sending a batch is safe because duplicates are counted asalreadyPresent.
Common questions
Can I export the list or see which addresses are on it? No. The list is not visible to customers, by design. Keep your own record of the addresses you add if you need one.
Can I remove an address I added by mistake? Not yourself. The dashboard says suppressions are permanent so an opt-out can never be reversed by accident. Contact support and the request is reviewed.
Does suppressing an address stop mail already in flight? Mail that has already been sent cannot be recalled. Anything not yet sent is checked against the list at send time and skipped.
Does the list apply to other workspaces I own? No. Each workspace has its own list, so add the address in every workspace that might email them. Bounced mailboxes are the exception, since those are suppressed across the platform.
Is it case sensitive? No. Addresses are trimmed and lowercased before they are stored and checked.
Do transactional emails respect it? Yes. A transactional recipient on the list is dropped, and
if every recipient is suppressed the email is recorded as suppressed and nothing is sent. See
Transactional email.
Related
- Leads: export and push-to-campaign both filter against this list
- Campaigns: suppressed leads are skipped at send time
- Unsubscribe links: what recipients see and what happens when they click
- Troubleshooting: "my campaign is not sending" includes the suppression case
Summarize with AI

