# Suppressions

The addresses this team will not send to, and the reason each one is on the list.

## Why the list exists

Sending again to an address that hard-bounced or reported you as spam is the fastest way to lose the ability to send at all. So a suppressed address is skipped before the message is handed to the mail provider: the send is recorded as `email.suppressed` rather than delivered, and your webhook is told which address and why.

| Origin | Means |
| --- | --- |
| `bounce` | A hard bounce. The mailbox does not exist or refused us permanently. |
| `complaint` | The recipient marked a message as spam. |
| `manual` | You added it, through the API or the dashboard. |
| `unsubscribe` | The recipient unsubscribed through the link in a message. |

## Working with the list

- Suppressions are per team, not per domain or per key.
- Retrieving by address — `GET /suppressions/{address}` — answers "may I send to this person?" without listing anything.
- Removing a suppression a bounce created will send to an address that already rejected you. Do it when you know the mailbox is back, not to clear a number.

## Endpoints

### `POST /suppressions`

Stop sending to one address.

#### Body

| Field | Type | Description |
| --- | --- | --- |
| `email` (required) | string | The address to suppress. |

Suppress an address:

```sh
curl -X POST "https://api.rasket.com/suppressions" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "ronald.williams@example.com"
}'
```

```ts
const response = await fetch("https://api.rasket.com/suppressions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "ronald.williams@example.com"
  }),
});

const { id } = await response.json();
```

```python
import os

import requests

response = requests.post(
    "https://api.rasket.com/suppressions",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
    json={
    "email": "ronald.williams@example.com"
  },
)

id = response.json()["id"]
```

#### Response `201`

```json
{
  "object": "suppression",
  "id": "2c9a7f10-b4e8-4d61-8a3c-5f7b9e1d2a06"
}
```

- A suppression added this way has `origin: manual`. Hard bounces and complaints add their own with `origin: bounce` or `complaint`.
- Suppressions are per team. A send to a suppressed address is recorded as `email.suppressed` rather than delivered.

### `GET /suppressions`

Every suppressed address, newest first.

#### Query parameters

| Field | Type | Description |
| --- | --- | --- |
| `origin` | string | Filter by `bounce`, `complaint`, `manual` or `unsubscribe`. |
| `search` | string | Case-insensitive substring of the address. `%` and `_` match literally. 1–200 characters. |
| `start_date` | string | ISO 8601, inclusive. Suppressions added before this are excluded. |
| `end_date` | string | ISO 8601, inclusive. Suppressions added after this are excluded. |
| `limit` | integer | How many items to return, 1–100. Defaults to 20. |
| `after` | string | Return the page that follows this item ID. Mutually exclusive with `before`. |
| `before` | string | Return the page that precedes this item ID. Mutually exclusive with `after`. |

List suppressions:

```sh
curl -X GET "https://api.rasket.com/suppressions?origin=bounce&limit=20" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"
```

```ts
const response = await fetch("https://api.rasket.com/suppressions?origin=bounce&limit=20", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
  },
});

const data = await response.json();
```

```python
import os

import requests

response = requests.get(
    "https://api.rasket.com/suppressions?origin=bounce&limit=20",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
)

print(response.json())
```

#### Response `200`

```json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "2c9a7f10-b4e8-4d61-8a3c-5f7b9e1d2a06",
      "email": "ronald.williams@example.com",
      "origin": "bounce",
      "source_id": "4ef9a417-02e9-4d39-ad75-9611e0fcc33c",
      "created_at": "2026-09-09T10:16:44.902Z"
    }
  ]
}
```

- `source_id` names the email that caused the suppression, when one did.

### `GET /suppressions/{suppression}`

Look one up by ID or by address.

#### Path parameters

| Field | Type | Description |
| --- | --- | --- |
| `suppression` (required) | string | Either the suppression's ID or the suppressed email address. |

Retrieve a suppression:

```sh
curl -X GET "https://api.rasket.com/suppressions/ronald.williams@example.com" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"
```

```ts
const response = await fetch("https://api.rasket.com/suppressions/ronald.williams@example.com", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
  },
});

const { id } = await response.json();
```

```python
import os

import requests

response = requests.get(
    "https://api.rasket.com/suppressions/ronald.williams@example.com",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
)

id = response.json()["id"]
```

#### Response `200`

```json
{
  "object": "suppression",
  "id": "2c9a7f10-b4e8-4d61-8a3c-5f7b9e1d2a06",
  "email": "ronald.williams@example.com",
  "origin": "bounce",
  "source_id": "4ef9a417-02e9-4d39-ad75-9611e0fcc33c",
  "created_at": "2026-09-09T10:16:44.902Z"
}
```

- Passing an address is the useful form: it answers "may I send to this person?" without listing anything.

### `DELETE /suppressions/{suppression}`

Allow sending to the address again.

#### Path parameters

| Field | Type | Description |
| --- | --- | --- |
| `suppression` (required) | string | Either the suppression's ID or the suppressed email address. |

Remove a suppression:

```sh
curl -X DELETE "https://api.rasket.com/suppressions/ronald.williams@example.com" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"
```

```ts
const response = await fetch("https://api.rasket.com/suppressions/ronald.williams@example.com", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
  },
});

const { id } = await response.json();
```

```python
import os

import requests

response = requests.delete(
    "https://api.rasket.com/suppressions/ronald.williams@example.com",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
)

id = response.json()["id"]
```

#### Response `200`

```json
{
  "object": "suppression",
  "id": "2c9a7f10-b4e8-4d61-8a3c-5f7b9e1d2a06",
  "deleted": true
}
```

- Removing a suppression a hard bounce created will send to an address that already rejected you once. Do it only when you know the mailbox is back.

### `POST /suppressions/batch/add`

Up to 100 addresses in one request.

#### Body

| Field | Type | Description |
| --- | --- | --- |
| `emails` (required) | string[] | The addresses to suppress, 100 at most. |

Add suppressions in bulk:

```sh
curl -X POST "https://api.rasket.com/suppressions/batch/add" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "emails": ["ronald.williams@example.com", "ada@example.com"]
}'
```

```ts
const response = await fetch("https://api.rasket.com/suppressions/batch/add", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    emails: ["ronald.williams@example.com", "ada@example.com"]
  }),
});

const data = await response.json();
```

```python
import os

import requests

response = requests.post(
    "https://api.rasket.com/suppressions/batch/add",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
    json={
    "emails": ["ronald.williams@example.com", "ada@example.com"]
  },
)

print(response.json())
```

#### Response `201`

```json
{
  "data": [
    {
      "object": "suppression",
      "id": "2c9a7f10-b4e8-4d61-8a3c-5f7b9e1d2a06"
    },
    {
      "object": "suppression",
      "id": "71f0c4b2-ad3e-4f18-9c07-5b2e8d1a6f94"
    }
  ]
}
```

- An address already suppressed is left as it is rather than duplicated or refused.

### `POST /suppressions/batch/remove`

Up to 100 at once, by address or by ID.

#### Body

| Field | Type | Description |
| --- | --- | --- |
| `emails` | string[] | Addresses to unsuppress. Send this or `ids`, never both. |
| `ids` | string[] | Suppression IDs to remove. Send this or `emails`, never both. |

Remove suppressions in bulk:

```sh
curl -X POST "https://api.rasket.com/suppressions/batch/remove" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "emails": ["ronald.williams@example.com"]
}'
```

```ts
const response = await fetch("https://api.rasket.com/suppressions/batch/remove", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
    "User-Agent": "acme-billing/1.0",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    emails: ["ronald.williams@example.com"]
  }),
});

const data = await response.json();
```

```python
import os

import requests

response = requests.post(
    "https://api.rasket.com/suppressions/batch/remove",
    headers={
        "Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
        "User-Agent": "acme-billing/1.0",
    },
    json={
    "emails": ["ronald.williams@example.com"]
  },
)

print(response.json())
```

#### Response `200`

```json
{
  "data": [
    {
      "object": "suppression",
      "id": "2c9a7f10-b4e8-4d61-8a3c-5f7b9e1d2a06",
      "deleted": true
    }
  ]
}
```

- Send `emails` or `ids` — sending both, or neither, is `422 invalid_parameter`.
- An address that is not currently suppressed is skipped rather than refused.
