NorthRelayNorthRelay
API Reference

Suppressions API

Manage account-level suppressions and topics (suppression groups) that stop mail to bounced, complained or opted-out recipients.

Suppressions API

Suppressions stop mail to addresses that should not receive it. NorthRelay has two layers:

  • Account-level suppressions block an address for your whole account. NorthRelay adds them automatically on hard bounces, spam complaints and "unsubscribe from all"; you can also add them yourself.
  • Topics (stored as suppression groups) let a recipient opt out of one category of mail, such as "Product updates", while still receiving the rest.

To subscribe or unsubscribe a recipient with the right side effects (contact status, list membership, webhooks), use the Subscriptions API. The routes on this page manage the underlying records directly.

Scopes: suppressions:read for GET, suppressions:write for everything else, on both /suppressions/** and /suppression-groups/**.

How suppressions apply when you send

NorthRelay filters every recipient before the message is queued. Filtered recipients are dropped and do not count against your monthly quota.

MailBlocked by
Marketing (campaigns, marketing message streams)Any account-level suppression; contact status UNSUBSCRIBED, BOUNCED, COMPLAINED or CLEANED; an opt-out of the topic the message is sent under
TransactionalOnly Bounce and Complaint suppressions and contact status BOUNCED, COMPLAINED or CLEANED. Unsubscribes do not block receipts and password resets.

Suppression reasons:

reasonAdded whenLifted by a subscribe call?
BounceHard bounce (5xx) reported by the receiving serverNever
ComplaintSpam complaint via a feedback loopNever
UnsubscribeThe recipient unsubscribed from all mail (link, one-click, preference centre or API)Only with "resubscribe": true
ManualYou added itNever; delete it yourself

List Suppressions

GET /suppressions

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger25Items per page (max 100)
reasonstring--Bounce, Complaint, Unsubscribe or Manual
searchstring--Matches part of the email address

Example Request

curl "https://app.northrelay.ca/api/v1/suppressions?reason=Bounce&limit=10" \
  -H "Authorization: Bearer nr_live_xxxxxxxxxxxx"

Example Response

{
  "success": true,
  "data": [
    {
      "id": "cmg7s0p00001qz8kab12cd34",
      "email": "invalid@example.com",
      "reason": "Bounce",
      "details": {
        "bounceCode": "550",
        "bounceReason": "5.1.1 The email account that you tried to reach does not exist",
        "messageId": "<20261003081500.a1b2c3@yourdomain.com>",
        "recordedAt": "2026-10-03T08:15:00.000Z"
      },
      "createdAt": "2026-10-03T08:15:00.000Z"
    }
  ],
  "meta": { "page": 1, "limit": 10, "total_count": 24, "has_more": true }
}

details is free-form and depends on how the suppression was created (for unsubscribes it records the method and campaignId).


Get a Suppression

GET /suppressions/{email}

Returns the suppression for one address, or 404 RESOURCE_NOT_FOUND when the address is not suppressed. URL-encode the address. To see suppression, contact status, lists and topics together, use GET /subscriptions/{email}.


Add Suppression

POST /suppressions

Request Body

FieldTypeRequiredDescription
emailstringYesEmail address to suppress
reasonstringYesBounce, Complaint, Unsubscribe or Manual
detailsobjectNoFree-form notes, for example a support ticket number

If the address is already suppressed, its reason and details are updated.

Example Request

curl -X POST https://app.northrelay.ca/api/v1/suppressions \
  -H "Authorization: Bearer nr_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "optout@example.com",
    "reason": "Manual",
    "details": { "ticket": "4521" }
  }'

Returns 201 with the suppression in data.

Adding an Unsubscribe suppression here does not change the contact's status or fire a webhook. To record an opt-out, prefer POST /subscriptions/unsubscribe.


Bulk Add or Remove

POST /suppressions/bulk

API key only.

FieldTypeRequiredDescription
actionstringYesadd or remove
emailsstring[]Yes1–10,000 addresses
reasonstringWhen action is addBounce, Complaint, Unsubscribe or Manual
curl -X POST https://app.northrelay.ca/api/v1/suppressions/bulk \
  -H "Authorization: Bearer nr_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "add",
    "reason": "Bounce",
    "emails": ["bounce1@example.com", "bounce2@example.com"]
  }'
{ "success": true, "data": { "action": "add", "requested": 2, "added": 2, "updated": 0 } }

updated counts addresses that were already suppressed with a different reason. With action: "remove" the response is { action, requested, removed }.


Remove Suppression

DELETE /suppressions/{email}
curl -X DELETE https://app.northrelay.ca/api/v1/suppressions/invalid%40example.com \
  -H "Authorization: Bearer nr_live_xxxxxxxxxxxx"
{ "success": true, "data": { "email": "invalid@example.com", "removed": true } }

Only remove a Bounce or Complaint suppression when you have confirmed the address is valid and wants your mail. Sending to addresses that bounced or complained damages your sender reputation and the shared sending IP.


Topics (Suppression Groups)

A topic is a category of mail that recipients can opt out of on its own. Each topic is a suppression group, and a member of the group is an address that opted out of that topic. "Subscribing" someone to a topic means removing them from the group.

Topics take effect on marketing mail when you send:

  • a campaign with a subscription topic set,
  • a campaign to a list that is tagged with the topic (suppressionGroupId on the list),
  • a marketing-stream API message with "suppressionGroupId": "<topicId>" on the send request.

Recipients who opted out of the topic are skipped. Transactional mail ignores topic opt-outs. Recipients can manage published topics themselves on NorthRelay's hosted preference centre ({{preferences_url}}), or on your own page through GET / PATCH /subscriptions/{email}.

Prefer the Subscriptions API for opt-ins and opt-outs: POST /subscriptions/unsubscribe with scope: "topic" also removes the recipient from lists tagged with the topic and fires contact.unsubscribed. The member routes below only edit the group.

List topics

GET /suppression-groups
ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger25Items per page (max 100)
publishedboolean--true returns only topics shown on the hosted preference centre, in display order
{
  "success": true,
  "data": [
    {
      "id": "cmg7t0p1c0003qz8k7h2d4pqr",
      "name": "product-updates",
      "description": "Release notes and feature announcements",
      "isDefault": false,
      "publicLabel": "Product updates",
      "publicDescription": "New features and release notes, about twice a month.",
      "isPublishedOnUnsub": true,
      "sortOrder": 0,
      "createdAt": "2026-09-01T10:00:00.000Z",
      "updatedAt": "2026-09-01T10:00:00.000Z",
      "_count": { "members": 12 }
    }
  ],
  "meta": { "page": 1, "limit": 25, "total_count": 1, "has_more": false }
}

_count.members is the number of addresses that opted out.

Create a topic

POST /suppression-groups
FieldTypeRequiredDescription
namestringYes1–100 characters, unique in your account
descriptionstringNoInternal description, max 500 characters
isDefaultbooleanNoMark as the default topic

Get, update or delete a topic

GET    /suppression-groups/{id}
PATCH  /suppression-groups/{id}
DELETE /suppression-groups/{id}

PATCH accepts name, description, isDefault, and the public fields recipients see:

FieldTypeDescription
publicLabelstring | nullName shown to recipients (max 120 characters)
publicDescriptionstring | nullOne-line explanation shown to recipients (max 500 characters)
isPublishedOnUnsubbooleanShow the topic on the hosted preference centre
sortOrderintegerDisplay order (0–10000)

Deleting a topic deletes its opt-outs; those addresses become eligible for that mail again.

Topic opt-outs (members)

GET    /suppression-groups/{id}/members
POST   /suppression-groups/{id}/members          { "email": "jane@example.com" }
DELETE /suppression-groups/{id}/members/{email}

GET returns { email, createdAt } rows (paginated with page and limit). POST opts an address out (idempotent, returns 201). DELETE removes the opt-out. The older paths /suppression-groups/{id}/suppressions, /suppressions/{email} and /suppressions/bulk remain available.


Suppression Object Reference

FieldTypeDescription
idstringUnique suppression identifier
emailstringSuppressed email address
reasonstringBounce, Complaint, Unsubscribe or Manual
detailsobject | nullFree-form details
createdAtstringISO 8601 creation timestamp

On this page