> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gork.email/llms.txt
> Use this file to discover all available pages before exploring further.

# Suppressions

> Automatic bounce and complaint suppression, send-time enforcement, and one-click unsubscribe.

A suppression stops all future sends to an address. Gork maintains one suppression list per workspace and enforces it at send time — suppressed recipients fail fast with `recipient_suppressed` (422) before any quota is consumed.

## Reasons

| Reason        | How it gets recorded                                                                                                                  |
| :------------ | :------------------------------------------------------------------------------------------------------------------------------------ |
| `hard_bounce` | Automatically, when the provider reports a permanent bounce                                                                           |
| `complaint`   | Automatically, when a recipient flags mail as spam via a feedback loop                                                                |
| `unsubscribe` | Automatically, via one-click unsubscribe (or the API)                                                                                 |
| `manual`      | By you, via `POST /v1/suppressions` (the default reason)                                                                              |
| `soft_bounce` | Reported on the `email.bounced` event for transient failures — the message is marked `bounced`, but the address is **not** suppressed |

Hard bounces and complaints also update the matched message (`status: "bounced"` / `"complained"`) and emit `email.bounced` / `email.complained` webhooks. Sustained bad reputation can pause sending workspace-wide — see [Troubleshooting](/troubleshooting).

## Send-time enforcement

Every `POST /v1/messages/send` checks all recipients (`to`, `cc`, `bcc`) against the list first:

```json Response (422) theme={null}
{
  "error": {
    "code": "recipient_suppressed",
    "message": "Cannot send email. Recipient gone@example.com is suppressed (hard_bounce).",
    "details": {
      "email": "gone@example.com",
      "reason": "hard_bounce",
      "source": "provider_webhook"
    }
  }
}
```

If you believe a suppression is stale (e.g. the mailbox was restored), remove it via the API below and retry.

## Manage via API

<CodeGroup>
  ```bash cURL theme={null}
  # List (filter by ?reason=hard_bounce, limit 1–100, default 50)
  curl "https://api.gork.email/v1/suppressions?limit=20" \
    -H "Authorization: Bearer gork_live_YOUR_KEY"

  # Add
  curl -X POST https://api.gork.email/v1/suppressions \
    -H "Authorization: Bearer gork_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{"email": "gone@example.com", "reason": "manual"}'

  # Remove
  curl -X DELETE https://api.gork.email/v1/suppressions/sup_31f9c2ab77d04e19 \
    -H "Authorization: Bearer gork_live_YOUR_KEY"
  ```

  ```typescript TypeScript theme={null}
  // List
  const list = await fetch("https://api.gork.email/v1/suppressions?limit=20", {
    headers: { Authorization: `Bearer ${process.env.GORK_API_KEY}` },
  }).then((r) => r.json());

  // Add
  await fetch("https://api.gork.email/v1/suppressions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GORK_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ email: "gone@example.com", reason: "manual" }),
  });

  // Remove
  await fetch(`https://api.gork.email/v1/suppressions/${id}`, {
    method: "DELETE",
    headers: { Authorization: `Bearer ${process.env.GORK_API_KEY}` },
  });
  ```

  ```python Python theme={null}
  import os
  import requests

  HEADERS = {"Authorization": f"Bearer {os.getenv('GORK_API_KEY')}"}

  supps = requests.get("https://api.gork.email/v1/suppressions?limit=20", headers=HEADERS).json()

  requests.post(
      "https://api.gork.email/v1/suppressions",
      headers=HEADERS,
      json={"email": "gone@example.com", "reason": "manual"},
  )

  requests.delete(f"https://api.gork.email/v1/suppressions/{supp_id}", headers=HEADERS)
  ```
</CodeGroup>

Listing requires `suppressions:read`; adding and removing require `suppressions:write`. Adding an already-suppressed address updates its reason instead of duplicating it. Removing a missing id returns `suppression_not_found` (404).

## One-click unsubscribe

Outbound mail carries an RFC 8058 `List-Unsubscribe` link pointing at `POST /v1/unsubscribe?token=…` (mail clients fire this automatically) plus a browser-friendly `GET /v1/unsubscribe?token=…` page that confirms visually. Both are public — no API key needed — and both record an `unsubscribe` suppression and emit an `email.unsubscribed` webhook.

```bash cURL theme={null}
curl -X POST "https://api.gork.email/v1/unsubscribe?token=UNSUBSCRIBE_TOKEN"
```

```json Response theme={null}
{
  "status": "success",
  "message": "Recipient tired@example.com has been unsubscribed successfully."
}
```

A missing token returns `missing_token` (400); an invalid or expired token returns `invalid_or_expired_token` (400). The `GET` variant renders the same outcomes as HTML pages for humans clicking the link.

<Note>
  Treat complaints and unsubscribes as permanent. Re-adding a `complaint` or `unsubscribe` address manually risks provider-level reputation damage — only do so with the recipient's explicit renewed consent.
</Note>
