Suppression Lists
Suppression lists prevent email from being sent to addresses that have previously bounced, complained, unsubscribed, or been manually opted out. PostMTA maintains an always-on workspace-level suppression list and supports custom named lists for campaign-specific exclusions.
Automatic Suppression on Hard Bounce
When PostMTA receives a hard bounce (SMTP 5xx) from the remote MTA, the recipient address is automatically added to the workspace-level suppression list with reason bounce_hard. Soft bounces (4xx) do not trigger automatic suppression but are tracked and escalated if they persist across multiple delivery attempts.
Hard bounce suppression is permanent by default. The address will never be sent to again unless manually un-suppressed by an operator with the owner role.
Manual Suppression via API
Add individual recipients to the suppression list manually. Useful for opt-out flows, user-initiated unsubscribes, or manual operator decisions.
{manual_suppress}Fields:
| Field | Type | Required | Description |
|---|---|---|---|
recipient | string | Yes | Email address to suppress. |
reason | string | Yes | One of: manual, unsubscribed, bounce_hard, bounce_soft, complained, policy_violation. |
expires_at | string (ISO 8601) | No | UTC timestamp at which this entry expires and is auto-removed. Null = permanent. |
list_id | string | No | Named suppression list to add this entry to. Omit to add to the workspace default list. |
Complaint-Based Suppression via OmniFBL
PostMTA integrates with major ISPs (Gmail, Yahoo, Outlook/Microsoft) via the OmniFBL (Feedback Loop) protocol. When an ISP forwards an abuse complaint (ARF report) to PostMTA's feedback address, the complained recipient is automatically added with reason complained.
Configure your FBL feedback address in the dashboard or via API:
{fbl_setup}Complaint suppression is permanent unless the auto_suppress setting is disabled per-ISP. Suppressions via FBL are stored with reason: "complained" and cannot be un-suppressed via the normal un-suppress flow; they require an owner with documented justification to manually override.
Named Suppression Lists
Create multiple named lists for different campaigns or use cases:
{create_suppression_list}Add entries to a named list:
{add_suppressions}Suppression List Management Dashboard
All suppression lists are visible and manageable in the PostMTA dashboard under App → Suppressions. From the dashboard you can:
- View entry counts per list and reason breakdown.
- Search for specific email addresses across all lists.
- Add or remove individual entries.
- Bulk import via CSV upload (up to 100,000 rows).
- Export to CSV or JSON.
- Set per-list retention windows.
{dashboard_view}Export Suppression List
Export any suppression list in CSV or JSON format. Exports are streamed as a file download to avoid memory pressure on large lists.
{export_suppressions}CSV format:
recipient,reason,created_at,expires_at,created_by
alice@example.com,bounce_hard,2026-06-15T08:00:00Z,,system
bob@example.com,manual,2026-07-01T10:30:00Z,2026-12-31T23:59:59Z,operator@example.comJSON format returns an array of objects with the same fields.
Suppression Bypass for Transactional Email
Transactional messages that represent a security-sensitive event (account alerts, password resets, payment receipts) can bypass per-recipient suppression. Bypass requires an explicit flag and a documented reason in the API call.
{bypass_transactional}Valid bypass_suppression.reason values:
transactional_security_alert— account security notificationstransactional_payment_receipt— billing receipts and invoicestransactional_legal_notice— legally required noticestransactional_account_verification— email verification codes
Suppression Window (Configurable Retention)
By default, suppression entries do not expire. You can set a retention_days value per named list to automatically purge entries after a configurable period. This is useful for time-limited campaigns where addresses suppressed due to a temporary issue (e.g. a temporary server outage) can be re-sent to after the window elapses.
{suppression_window}The workspace-level default suppression list has no retention window (permanent). Named lists default to 365 days if retention_days is not specified.
Expired entries are permanently deleted during the nightly cleanup job. Expired entries are not included in export or lookup operations before deletion.
Remove a Suppression Entry
Reinstate a previously suppressed address. Only works for entries with reason: "manual" or reason: "unsubscribed". Entries with reason bounce_hard or complained cannot be un-suppressed via this endpoint.
{remove_suppression}Query Suppressions
List suppression entries with optional filters:
{list_suppressions}Supports filtering by reason, list_id, and pagination via limit / offset.
Bulk Import Suppressions
For large-scale imports, use the CSV bulk-upload endpoint. Files must be under 100,000 rows and under 50 MB. The file must have a header row with columns: recipient, reason, expires_at (optional).
curl -X POST https://api.postmta.com/v1/suppressions/lists/spl_01HXSUPP001/import \
-H "Authorization: Bearer ***" \
-H "Content-Type: multipart/form-data" \
-F "file=@suppressions_bulk.csv" \
-F "reason=manual" \
-F "dedupe_strategy=skip"Import options:
| Option | Values | Default | Description |
|---|---|---|---|
dedupe_strategy | skip, replace, error | skip | Behaviour when recipient already exists in the list. |
default_reason | string | from file or manual | Reason applied to rows that do not have one in the file. |
dry_run | boolean | false | Validate the file and return row counts without committing changes. |
After upload, a background job processes the file. Poll GET /v1/suppressions/imports/:job_id to check progress.
Suppression Audit Trail
Every addition and removal from a suppression list is recorded in the immutable audit log with the operator key ID, timestamp, reason, and the list affected. Use the audit log to track when a specific address was suppressed and by which credential:
curl "https://api.postmta.com/v1/audit?resource_type=suppression&recipient=alice@example.com&limit=20" \
-H "Authorization: Bearer ***"This is useful for compliance investigations, GDPR data requests, and fraud analysis where you need to prove when and why a particular address entered or left a suppression state.