Suppressions

Suppression lists, the addresses on them, and the opt-outs detected in replies that await review.

Guides: Suppression lists.

MethodPathOperationScope
GET/v1/suppressionsList suppression listsread
POST/v1/suppressionsCreate a suppression listwrite
PATCH/v1/suppressions/{listId}Update a suppression listwrite
DELETE/v1/suppressions/{listId}Delete a suppression listwrite
GET/v1/suppressions/{listId}/entriesList suppressed addressesread
POST/v1/suppressions/{listId}/entriesSuppress addresseswrite
DELETE/v1/suppressions/{listId}/entries/{address}Release an addresswrite
GET/v1/suppression-reviewsList opt-outs to reviewread
POST/v1/suppression-reviews/{reviewId}/approveApprove an opt-outwrite
POST/v1/suppression-reviews/{reviewId}/dismissDismiss an opt-outwrite

List suppression lists

GET
/v1/suppressions

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.

Response Body

OK

application/json
  1. response
items*array<>
Example Request
curl -X GET 'https://api.workwae.com/v1/suppressions'
Example Response
{  "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"    }  ]}
POST
/v1/suppressions

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.

Request Body

application/json
  1. body
id*string
Match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
name*string
Length1 <= length <= 100
description?|null

Response Body

OK

application/json
  1. response
id*string
name*string
description*string|null
count*integer
counts*
createdAt*|null
Example Request
curl -X POST 'https://api.workwae.com/v1/suppressions' \  -H 'Content-Type: application/json' \  -d '{  "id": "string",  "name": "string"}'
Example Response
{  "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"}
PATCH
/v1/suppressions/{listId}

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.

Path Parameters

listId*string
Match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$

Request Body

application/json
  1. body
name?string
Length1 <= length <= 100
description?|null

Response Body

OK

application/json
  1. response
id*string
name*string
description*string|null
count*integer
counts*
createdAt*|null
Example Request
curl -X PATCH 'https://api.workwae.com/v1/suppressions/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "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"}
DELETE
/v1/suppressions/{listId}

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.

Path Parameters

listId*string
Match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$

Query Parameters

withEntries?|
Defaultfalse

Response Body

OK

application/json
  1. response
Example Request
curl -X DELETE 'https://api.workwae.com/v1/suppressions/string'
Example Response
null
GET
/v1/suppressions/{listId}/entries

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.

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.

Path Parameters

listId*string
Match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$

Query Parameters

address?string
Lengthlength <= 320
source?string
Value in"unsubscribe""bounce""api""reply""complaint""inactive"
limit?integer
Range1 <= value <= 200
Default50
cursor?string
Length1 <= length <= 512

Response Body

OK

application/json
  1. response
items*array<>
nextCursor*|null
Example Request
curl -X GET 'https://api.workwae.com/v1/suppressions/string/entries'
Example Response
{  "items": [    {      "address": "ada@example.com",      "source": "unsubscribe",      "reason": "string",      "createdAt": "2026-05-04T09:30:00.000Z"    }  ],  "nextCursor": "eyJ0eG5pZCI6IjQyIiwiaWQiOjEwMDF9"}

Suppress addresses

POST
/v1/suppressions/{listId}/entries

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.

Path Parameters

listId*string
Match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$

Request Body

application/json
  1. body
addresses*array<>
Items1 <= items <= 1000
reason?string
Length1 <= length <= 200

Response Body

OK

application/json
  1. response
added*integer
alreadyListed*integer
Example Request
curl -X POST 'https://api.workwae.com/v1/suppressions/string/entries' \  -H 'Content-Type: application/json' \  -d '{  "addresses": [    "ada@example.com"  ]}'
Example Response
{  "added": 0,  "alreadyListed": 0}

Release an address

DELETE
/v1/suppressions/{listId}/entries/{address}

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.

Path Parameters

listId*string
Match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
address*string
Length1 <= length <= 320

Response Body

OK

application/json
  1. response
Example Request
curl -X DELETE 'https://api.workwae.com/v1/suppressions/string/entries/ada@example.com'
Example Response
null

List opt-outs to review

GET
/v1/suppression-reviews

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.

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.

Query Parameters

listId?string
Match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
limit?integer
Range1 <= value <= 200
Default50
cursor?string
Length1 <= length <= 512

Response Body

OK

application/json
  1. response
items*array<>
nextCursor*|null
Example Request
curl -X GET 'https://api.workwae.com/v1/suppression-reviews'
Example Response
{  "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"}

Approve an opt-out

POST
/v1/suppression-reviews/{reviewId}/approve

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.

Path Parameters

reviewId*string
Formatuuid

Response Body

OK

application/json
  1. response
added*boolean
Example Request
curl -X POST 'https://api.workwae.com/v1/suppression-reviews/db1f2b3d-aad8-44c8-9b8d-3f8f03dd5531/approve'
Example Response
{  "added": true}

Dismiss an opt-out

POST
/v1/suppression-reviews/{reviewId}/dismiss

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.

Path Parameters

reviewId*string
Formatuuid

Response Body

OK

application/json
  1. response
Example Request
curl -X POST 'https://api.workwae.com/v1/suppression-reviews/db1f2b3d-aad8-44c8-9b8d-3f8f03dd5531/dismiss'
Example Response
null