---
title: "List your email suppressions"
method: GET
path: "/products/notify/suppressions"
tags: ["notify"]
---

# List your email suppressions

`GET /products/notify/suppressions`

The addresses that opted out of THIS account's mail, newest first. Account-scoped rows ONLY: a hard bounce, a complaint, and a platform-wide opt-out are recorded as GLOBAL rows carrying no account, and the sparse index this reads does not contain them. That is structural, not a filter — there is no parameter here that reaches a global row or another tenant's.

## Query parameters

- `limit` integer
- `cursor` string

## Response `200`

A page of your suppressions.

- object
  - `data` NotifySuppressionListResponse, required
    - `suppressions` NotifySuppression[], required — Newest first.
      - `email` string, required — The suppressed address, normalized (lower-cased, trimmed).
      - `type` 'bounce' | 'complaint' | 'unsubscribe' | 'manual', required — The stored vocabulary. In practice this listing returns `unsubscribe`: a bounce and a complaint are facts about the ADDRESS and are recorded GLOBALLY, so they are not in this index at all.
      - `source` 'ses_webhook' | 'user_request' | 'admin', required — What recorded the row.
      - `reason` string, nullable — Free-form detail, when the recording path supplied one.
      - `created_at` integer, nullable — Unix seconds the row was written.
    - `cursor` string, nullable, required — Opaque continuation token — the same cursor contract `/sends` and `/receipts` use. Pass it back as `cursor` to read the next page, and loop until it comes back null. It carries the whole page pointer, so it is never assembled from a field on a row.
  - `meta` ResponseMeta — Envelope metadata present on every successful response.
    - `api_version` string
    - `request_id` string
    - `response_ms` integer
    - `timestamp` integer — Unix seconds.
    - `pools` object — Storage and bandwidth capacity snapshot for the account.
    - `billing` object
      - `past_due` boolean
    - `quota` object — This minute of the account request budget. Present on authenticated success responses that passed the throttle; absent otherwise.
      - `limit` integer
      - `used` integer
      - `remaining` integer
      - `resets_at` integer — Unix seconds.

## Other responses

- `400` — VALIDATION_ERROR — the message names the offending field. INVALID_CURSOR — the cursor decoded but is not a key of this index: a hand-made cursor, or one issued by a different list surface. Cursors are never portable between surfaces; start the listing again without one.
- `401` — AUTHENTICATION_ERROR — missing or invalid credentials.
- `403` — FORBIDDEN — the caller may not act on this account.
- `429` — RATE_LIMIT_EXCEEDED — the account exceeded 5000 requests this minute. `Retry-After` carries the seconds to wait, and `details` carries limit/resets_at, plus `used` whenever the request was counted. A request refused because the limiter itself was unavailable reports no `used`.
- `503` — SUPPRESSIONS_PROVISIONING — the suppression index is not queryable on this deployment. Temporary; retry shortly. Sending and delivery are unaffected, and clearing a suppression needs no index and always works.

---

[API](https://skmtc.dev/sparkvault/apis/sparkvault-api.md) · [All operations](https://skmtc.dev/sparkvault/apis/sparkvault-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/sparkvault/sparkvault-api/revisions/a7807da394b8/schema)
