Suppressions API
Manage unsubscribe groups and email suppressions. Suppressions prevent emails from being sent to recipients who have opted out, bounced, or complained.
Unsubscribe Groups
GET /v1/unsubscribe-groups
List all unsubscribe groups for the organization.
{
"data": [
{
"id": "grp-uuid",
"organizationId": "org-uuid",
"name": "Marketing",
"description": "Weekly newsletter and promotions",
"isDefault": true,
"createdAt": "2025-01-10T08:00:00Z"
},
{
"id": "grp-uuid-2",
"organizationId": "org-uuid",
"name": "Product Updates",
"description": "Feature announcements and release notes",
"isDefault": false,
"createdAt": "2025-01-10T08:00:00Z"
}
]
}
POST /v1/unsubscribe-groups
Create a new unsubscribe group. If isDefault is set to true, any existing default group is unset.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Group name (max 255 chars). |
description | string | No | Group description (max 2,000 chars). |
isDefault | boolean | No | Whether this is the default group (default: false). |
Response
Status: 201 Created
{
"data": {
"id": "grp-uuid",
"organizationId": "org-uuid",
"name": "Marketing",
"description": "Weekly newsletter and promotions",
"isDefault": true,
"createdAt": "2025-01-10T08:00:00Z"
}
}
PATCH /v1/unsubscribe-groups/:id
Update a group's name, description, or default status.
DELETE /v1/unsubscribe-groups/:id
Delete a group. All suppressions in the group are cascade-deleted.
Suppressions
GET /v1/suppressions
List suppressions with filtering and pagination.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number. |
limit | integer | 20 | Items per page (max 100). |
source | string | -- | Filter by source: BOUNCE, COMPLAINT, MANUAL, IMPORT, UNSUBSCRIBE. |
groupId | string | -- | Filter by unsubscribe group. |
Response
{
"data": [
{
"id": "sup-uuid",
"organizationId": "org-uuid",
"emailHash": "sha256...",
"unsubscribeGroupId": "grp-uuid",
"source": "UNSUBSCRIBE",
"createdAt": "2025-01-12T15:00:00Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 42, "totalPages": 3 }
}
POST /v1/suppressions
Manually add a suppression.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Email address to suppress. Stored as a SHA-256 hash. |
unsubscribeGroupId | string | No | Scope the suppression to a specific group. |
source | string | No | Source of the suppression: BOUNCE, COMPLAINT, MANUAL, IMPORT, UNSUBSCRIBE. Default: MANUAL. |
Response
Status: 201 Created
{
"data": {
"id": "sup-uuid",
"organizationId": "org-uuid",
"emailHash": "sha256...",
"unsubscribeGroupId": "grp-uuid",
"source": "MANUAL",
"createdAt": "2025-01-12T15:00:00Z"
}
}
If the suppression already exists, the API returns 409 Conflict.
DELETE /v1/suppressions/:id
Remove a suppression, allowing emails to be sent to that address again.
POST /v1/suppressions/import
Bulk import suppressions from a list of email addresses. Duplicates are silently skipped.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
emails | string[] | Yes | Email addresses to suppress (1 to 10,000). |
unsubscribeGroupId | string | No | Scope all suppressions to a specific group. |
Response
{
"data": {
"imported": 847,
"skipped": 153,
"total": 1000
}
}
Public Unsubscribe Endpoint
GET /v1/unsubscribe/:token
This is a public endpoint (no authentication required). It handles unsubscribe link clicks from email recipients.
The :token is an HMAC-signed payload containing the organization ID, unsubscribe group, and recipient email. When a user clicks the link:
- The HMAC token is verified
- A suppression record is created
- The action is logged in the audit trail
- A confirmation HTML page is displayed
Invalid or expired tokens display an error page.
This endpoint is called automatically when recipients click the unsubscribe link that Optail injects into emails sent with an unsubscribeGroupId.