SonarSend API Endpoints Suppression

Suppression

Hard-blocking an address, account-wide.

4 endpoints Base URL · https://api.sonarsend.com Auth · X-API-Key
The Suppression object 4 fields
created_atdate-time · nullable
emailstring

The blocked address, normalised to lowercase.

reasonstring · nullable

Free-text audit note. Nothing branches on it; re-suppressing replaces it.

tenant_iduuid

List suppressed addresses

GET /t/{slug}/api/suppressions/

Every address on the account's suppression list — a hard send block that applies regardless of any contact's subscription state, and even to addresses with no contact record. The whole list is returned in one page; there is no pagination on this endpoint today. Requires suppression:read.

This is distinct from unsubscribing (a preference on a contact) and from a per-sender block (an address a contact bounced on for one identity). Suppression is account-wide and address-level.

A page of Suppression objects, under data.

200

The full suppression list.

400

The request failed validation, or a referenced record was rejected.

404

The tenant slug, or the record the path names, does not exist.

Request
curl -X GET "https://api.sonarsend.com/t/acme/api/suppressions" \
  -H "X-API-Key: $SONARSEND_API_KEY"
Response 200
{
  "data": [
    {
      "tenant_id": "9c21895d-57f0-4a15-a1df-4dc6835d4f80",
      "email": "jamie@example.com",
      "reason": "string",
      "created_at": "2026-01-15T09:30:00.000Z"
    }
  ],
  "next_cursor": "eyJpZCI6IjljMjE4OTVkIn0",
  "has_more": true
}

Suppress an address

POST /t/{slug}/api/suppressions/

Adds an address to the suppression list. Requires suppression:write. The address is lowercased and trimmed on the way in, so Blocked@Example.com and blocked@example.com are the same entry.

Keyed on (tenant, email), so re-suppressing an address already on the list upserts rather than erroring — but note it replaces the stored reason, so re-posting without one clears the previous note. reason is free text for your own auditing; nothing branches on it. Returns 201 with the row.

This blocks the address; it does not change any contact's subscription status. To suppress a contact AND mark them unsubscribed, use the bulk endpoint with contact IDs.

emailstringRequired

Address to block. Normalised to lowercase.

reasonstring

Optional free-text audit note. Replaces any existing note on re-suppress.

The Suppression object.

201

The address was suppressed.

400

The request failed validation, or a referenced record was rejected.

404

The tenant slug, or the record the path names, does not exist.

Request
curl -X POST "https://api.sonarsend.com/t/acme/api/suppressions" \
  -H "X-API-Key: $SONARSEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jamie@example.com",
    "reason": "string"
  }'
Response 201
{
  "tenant_id": "9c21895d-57f0-4a15-a1df-4dc6835d4f80",
  "email": "jamie@example.com",
  "reason": "string",
  "created_at": "2026-01-15T09:30:00.000Z"
}

Un-suppress an address

DELETE /t/{slug}/api/suppressions/

Removes an address from the suppression list, lifting the send block. Requires suppression:write. The address goes in the query string, not the path, because it contains @ and dots — URL-encode it. Case is normalised here too.

Idempotent: removing an address that is not on the list is also a 204. Lifting a block does not resubscribe anyone — if the contact is unsubscribed they stay unsubscribed, which is separate state. Returns 204 with no body.

email string Required

Address to un-suppress. URL-encode it; case is normalised.

204

The block was lifted (or the address was already absent).

400

The request failed validation, or a referenced record was rejected.

404

The tenant slug, or the record the path names, does not exist.

Request
curl -X DELETE "https://api.sonarsend.com/t/acme/api/suppressions?email=" \
  -H "X-API-Key: $SONARSEND_API_KEY"

Suppress many contacts at once

POST /t/{slug}/api/suppressions/bulk

Suppresses a selection of contacts by ID — the "act on this list of contacts" path behind the app's sunset-candidates flow. Requires suppression:write. Unlike the single-address endpoint, this takes contact IDs, and for each contact it both adds the address to the suppression list AND flips the contact to unsubscribed (if not already). Contacts with no email, or that do not exist, are skipped.

1–500 IDs per call; over 500 returns 400 TOO_MANY, so batch larger jobs client-side. reason defaults to "sunset" here (it is null when omitted on the single-address endpoint). Returns { suppressed }, the number actually acted on.

contact_idsstring[]Required

Contact UUIDs, 1–500 per call.

reasonstring

Audit note stored on each suppression. Defaults to sunset.

suppressedinteger
200

How many contacts were suppressed.

400

The request failed validation, or a referenced record was rejected.

404

The tenant slug, or the record the path names, does not exist.

Request
curl -X POST "https://api.sonarsend.com/t/acme/api/suppressions/bulk" \
  -H "X-API-Key: $SONARSEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_ids": [
      "string"
    ],
    "reason": "string"
  }'
Response 200
{
  "suppressed": 0
}