Suppressions
Suppression lists, the addresses on them, and the opt-outs detected in replies that await review.
Guides: Suppression lists.
| Method | Path | Operation | Scope |
|---|---|---|---|
GET | /v1/suppressions | List suppression lists | read |
POST | /v1/suppressions | Create a suppression list | write |
PATCH | /v1/suppressions/{listId} | Update a suppression list | write |
DELETE | /v1/suppressions/{listId} | Delete a suppression list | write |
GET | /v1/suppressions/{listId}/entries | List suppressed addresses | read |
POST | /v1/suppressions/{listId}/entries | Suppress addresses | write |
DELETE | /v1/suppressions/{listId}/entries/{address} | Release an address | write |
GET | /v1/suppression-reviews | List opt-outs to review | read |
POST | /v1/suppression-reviews/{reviewId}/approve | Approve an opt-out | write |
POST | /v1/suppression-reviews/{reviewId}/dismiss | Dismiss an opt-out | write |
Runs in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
The global list first, then every named list by listId, with its counts by source.
Required scope: read.
OK
application/json- response
items*array<>curl -X GET 'https://api.workwae.com/v1/suppressions'{ "items": [ { "id": "string", "name": "string", "description": "Production", "count": 0, "counts": { "unsubscribe": 0, "bounce": 0, "api": 0, "reply": 0, "complaint": 0, "inactive": 0 }, "createdAt": "2026-05-04T09:30:00.000Z" } ]}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
id is what sends name as listId; it cannot change later, the name and description can. A send or add naming a list that does not exist creates it too, named after its id.
Required scope: write.
application/json- body
id*string^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$name*string1 <= length <= 100description?|nullOK
application/json- response
id*stringname*stringdescription*string|nullcount*integercounts*createdAt*|nullcurl -X POST 'https://api.workwae.com/v1/suppressions' \ -H 'Content-Type: application/json' \ -d '{ "id": "string", "name": "string"}'{ "id": "string", "name": "string", "description": "Production", "count": 0, "counts": { "unsubscribe": 0, "bounce": 0, "api": 0, "reply": 0, "complaint": 0, "inactive": 0 }, "createdAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Only the fields given change; description null clears it. The global list cannot be changed.
Required scope: write.
listId*string^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$application/json- body
name?string1 <= length <= 100description?|nullOK
application/json- response
id*stringname*stringdescription*string|nullcount*integercounts*createdAt*|nullcurl -X PATCH 'https://api.workwae.com/v1/suppressions/string' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "string", "name": "string", "description": "Production", "count": 0, "counts": { "unsubscribe": 0, "bounce": 0, "api": 0, "reply": 0, "complaint": 0, "inactive": 0 }, "createdAt": "2026-05-04T09:30:00.000Z"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Deletes the list and its pending reviews and, with ?withEntries=true, every address on it: later sends naming it reach those addresses again (unless the global list holds them), and the next one naming it creates it anew. The global list cannot be deleted.
Required scope: write.
listId*string^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$withEntries?|falseOK
application/json- response
curl -X DELETE 'https://api.workwae.com/v1/suppressions/string'nullRuns in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
Addresses on one list, by address; a list without addresses is empty, not missing. address keeps those containing it, source those that came from it.
Required scope: read.
listId*string^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$address?stringlength <= 320source?string"unsubscribe""bounce""api""reply""complaint""inactive"limit?integer1 <= value <= 20050cursor?string1 <= length <= 512OK
application/json- response
items*array<>nextCursor*|nullcurl -X GET 'https://api.workwae.com/v1/suppressions/string/entries'{ "items": [ { "address": "ada@example.com", "source": "unsubscribe", "reason": "string", "createdAt": "2026-05-04T09:30:00.000Z" } ], "nextCursor": "eyJ0eG5pZCI6IjQyIiwiaWQiOjEwMDF9"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Puts up to 1000 addresses on the list in one call; a repeated address counts once. added counts the addresses put on the list, alreadyListed those that were on it already, which are left as they were. A list that does not exist is created, named after its listId. Answers 200: entries are listed, not fetched one by one. Emits no suppression.created: that event reports what recipients and bounces did.
Required scope: write.
listId*string^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$application/json- body
addresses*array<>1 <= items <= 1000reason?string1 <= length <= 200OK
application/json- response
added*integeralreadyListed*integercurl -X POST 'https://api.workwae.com/v1/suppressions/string/entries' \ -H 'Content-Type: application/json' \ -d '{ "addresses": [ "ada@example.com" ]}'{ "added": 0, "alreadyListed": 0}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Later sends naming the list reach the address again (unless another list they consult holds it).
Required scope: write.
listId*string^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$address*string1 <= length <= 320OK
application/json- response
curl -X DELETE 'https://api.workwae.com/v1/suppressions/string/entries/ada@example.com'nullRuns in your browser against api.workwae.com with the key you enter. Use a read-only key, limited to a test account if you can.
Detected opt-outs waiting for a person, newest first; listId keeps one list's. Holds AI-classified opt-out replies while optOutHandling is review, and auto-replies saying the person is no longer at the address (source inactive, on the global list) while it is review or suppress. A detection of an address already on its list, or already waiting, is not queued again.
Required scope: read.
listId?string^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$limit?integer1 <= value <= 20050cursor?string1 <= length <= 512OK
application/json- response
items*array<>nextCursor*|nullcurl -X GET 'https://api.workwae.com/v1/suppression-reviews'{ "items": [ { "id": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "listId": "string", "address": "ada@example.com", "source": "reply", "accountId": "6f1c2a4e-8b3d-4e5f-9a7b-1c2d3e4f5a6b", "messageId": "c4e6a8b0-1d3f-4a5c-8e7b-9d1f3a5c7e9b", "probability": 0, "alternateContacts": [ "string" ], "createdAt": "2026-05-04T09:30:00.000Z" } ], "nextCursor": "eyJ0eG5pZCI6IjQyIiwiaWQiOjEwMDF9"}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Puts the address on the review's list with the review's source and removes the review. added is false when the address was on the list already. Emits suppression.created when it was not.
Required scope: write.
reviewId*stringuuidOK
application/json- response
added*booleancurl -X POST 'https://api.workwae.com/v1/suppression-reviews/db1f2b3d-aad8-44c8-9b8d-3f8f03dd5531/approve'{ "added": true}Runs against the live API with the key you enter: this change really happens. Use a key limited to a test account.
Removes the review without suppressing anything; a later detection of the same address queues it again.
Required scope: write.
reviewId*stringuuidOK
application/json- response
curl -X POST 'https://api.workwae.com/v1/suppression-reviews/db1f2b3d-aad8-44c8-9b8d-3f8f03dd5531/dismiss'null