Suppression

Suppressions API

5 endpoints under https://api.mailneo.co/api/v2. Every request carries your key in the X-API-Key header. The scopes used here: suppressions:delete, suppressions:read, suppressions:write. Each endpoint below states the one it requires. Start with the guide →

Suppressions
listSuppressions

List suppressed addresses

The addresses this team must not mail. Cursor-paginated. Pass updated_since with the synced_through value from your previous run to fetch only what changed.

This list is complete for your team. Mirror it into your own sender if you send outside Mailneo.

https://api.mailneo.co/api/v2
GET/suppressionssuppressions:read

Example request

curl "https://api.mailneo.co/api/v2/suppressions?limit=25&order=desc&sort=updated_at" \
  -H "X-API-Key: $MAILNEO_API_KEY"
Authorization
Required scope
suppressions:read. A key without it is refused before the endpoint runs.
Credential
X-API-Key: mk_live_...Authorization: Bearer mk_live_...
Query parameters7
NameTypeRequiredNotes
limitintegerNodefault 25 · 1–100
cursorstringNomax 256 chars
order"asc" | "desc"Nodefault "desc"
updated_sincestring · date-timeNoISO 8601
sort"updated_at" | "created_at"Nodefault "updated_at"
emailstringNomax 320 chars
reasonstringNomax 200 chars
Response · 200

Success

data[]Each element of the array.

FieldTypeAlways presentNotes
object"suppression"Yes
idstringYes
emailstringYes
reasonstringYes
created_atstringYes
updated_atstringYes

meta

FieldTypeAlways presentNotes
request_idstringYes
has_morebooleanYes
next_cursorstring · nullableYes
synced_throughstringNo
Suppressionswrite
addSuppressions

Add addresses to the suppression list

Suppresses up to 100 addresses per call. Every send path consults this list, so an address added here stops receiving campaign and newsletter mail from this team immediately.

Suppression is an overlay, not a deletion: contacts and subscribers with these addresses are NOT deleted or modified, their list memberships survive, and removing the suppression later restores mailability (except where a per-list opt-out also applies). To erase a person, use the contact delete or the account data-erasure flow — this endpoint only blocks sending.

Partial novelty is the normal outcome and the response says which addresses landed where: added, or already_suppressed (left completely untouched — the existing record keeps its original reason, so a bounce or complaint record is never overwritten by a manual re-post, and its updated_at does not move). Re-posting the same batch is therefore always safe, which is what a retried compliance sync needs. Addresses are normalised (trimmed and lower-cased) before anything else happens.

reason accepts only MANUAL. The other values you will see on reads (bounce:hard, bounce:complaint, unsubscribe variants) are written by the delivery pipeline about its own observations and cannot be set through the API.

suppression.added webhook events are not emitted for additions made through this endpoint.

https://api.mailneo.co/api/v2
POST/suppressionssuppressions:write

Example request

curl -X POST "https://api.mailneo.co/api/v2/suppressions" \
  -H "X-API-Key: $MAILNEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      "<string>"
    ]
  }'
Authorization
Required scope
suppressions:write. A key without it is refused before the endpoint runs.
Credential
X-API-Key: mk_live_...Authorization: Bearer mk_live_...
Idempotency
Idempotency-Key is optional.
Query parameters1
NameTypeRequiredNotes
dry_runbooleanNoReport what this call WOULD do and commit nothing. Returns data: null and a meta.impact block. Requires the resource's :read scope in addition to the scope this endpoint declares. Must be exactly true or false.
Header parameters1
NameTypeRequiredNotes
Idempotency-KeystringNoA caller-chosen unique string, at most 255 characters. Retrying with the same key replays the first response instead of repeating the work; the replay carries Idempotent-Replayed: true. Reusing a key with a different body is a 409 idempotency_key_reused. Keys are remembered for 24 hours. · max 255 chars
Request body

Body

FieldTypeAlways presentNotes
emailsstring[]Yes
reason"MANUAL"Nodefault "MANUAL"
Response · 200

Success

dataMay be null.

FieldTypeAlways presentNotes
object"suppression_batch"Yes
addedstring[]Yes
already_suppressedstring[]Yes

meta

FieldTypeAlways presentNotes
request_idstringYes
dry_runbooleanYes
impactobjectNo
impact.object"impact"Yes
impact.would_createintegerYes
impact.would_updateintegerYes
impact.would_deleteintegerYes
impact.affected_countintegerYes
impact.affected_idsstring[]Yes
impact.quotaobject · nullableYes
impact.quota.kindstringYes
impact.quota.would_consumeintegerYes
impact.quota.limitinteger · nullableYes
impact.quota.currentintegerYes
Suppressions
getSuppression

Check whether an address is suppressed

Returns the suppression record for an address, or 404 if it is not suppressed. This is the check to run before mailing someone from your own system. The address must be URL-encoded.

https://api.mailneo.co/api/v2
GET/suppressions/{email}suppressions:read

Example request

curl "https://api.mailneo.co/api/v2/suppressions/{email}" \
  -H "X-API-Key: $MAILNEO_API_KEY"
Authorization
Required scope
suppressions:read. A key without it is refused before the endpoint runs.
Credential
X-API-Key: mk_live_...Authorization: Bearer mk_live_...
Path parameters1
NameTypeRequiredNotes
emailstringYesmax 320 chars
Response · 200

Success

data

FieldTypeAlways presentNotes
object"suppression"Yes
idstringYes
emailstringYes
reasonstringYes
created_atstringYes
updated_atstringYes

meta

FieldTypeAlways presentNotes
request_idstringYes
Suppressions
listUnsubscribes

List unsubscribe events

The unsubscribe events behind the suppression list — who opted out, from where, and from which campaign. Cursor-paginated.

updated_since is not supported here: the underlying record has no modification timestamp. Unsubscribes are append-only, so page by unsubscribed_at and keep the newest value you have seen as your high-water mark.

https://api.mailneo.co/api/v2
GET/unsubscribessuppressions:read

Example request

curl "https://api.mailneo.co/api/v2/unsubscribes?limit=25&order=desc&sort=unsubscribed_at" \
  -H "X-API-Key: $MAILNEO_API_KEY"
Authorization
Required scope
suppressions:read. A key without it is refused before the endpoint runs.
Credential
X-API-Key: mk_live_...Authorization: Bearer mk_live_...
Query parameters7
NameTypeRequiredNotes
limitintegerNodefault 25 · 1–100
cursorstringNomax 256 chars
order"asc" | "desc"Nodefault "desc"
sort"unsubscribed_at" | "created_at"Nodefault "unsubscribed_at"
emailstringNomax 320 chars
sourcestringNomax 100 chars
campaign_idstringNomax 64 chars
Response · 200

Success

data[]Each element of the array.

FieldTypeAlways presentNotes
object"unsubscribe"Yes
idstringYes
emailstringYes
reasonstring · nullableYes
sourcestringYes
campaign_idstring · nullableYes
unsubscribed_atstringYes
created_atstringYes

meta

FieldTypeAlways presentNotes
request_idstringYes
has_morebooleanYes
next_cursorstring · nullableYes
Suppressionsdestructive
deleteSuppression

Remove an address from the suppression list (un-suppress)

Removes one suppression record, RE-ENABLING mail to an address that was deliberately blocked: every campaign and newsletter send path in this team will treat the address as mailable again the moment this returns. There is no undo beyond re-adding the suppression — call with ?dry_run=true first.

Check the record's reason before deleting. MANUAL rows were typed in by a person; bounce:hard, bounce:soft and bounce:complaint rows were recorded by the delivery pipeline, and UNSUBSCRIBED/unsubscribe rows record an opt-out. Removal is allowed whatever the reason — the same rule as the in-app suppression screen — but removing a bounce- or complaint-sourced record does not fix what caused it, and the pipeline will re-create the suppression automatically if the condition recurs (another hard bounce, another complaint). Un-suppressing an opt-out and then mailing the address is a compliance decision that is yours, not the platform's.

Only the suppression record is removed. The unsubscribe EVENT history (GET /unsubscribes) is untouched, and a per-list opt-out (an UNSUBSCRIBED list membership) still stands and still blocks that list's sends — this endpoint lifts the team-wide block, nothing else.

Find the id via GET /suppressions or GET /suppressions/{email}. The response deliberately does not echo the address.

https://api.mailneo.co/api/v2
DELETE/suppressions/{suppressionId}suppressions:delete

Example request

curl -X DELETE "https://api.mailneo.co/api/v2/suppressions/{suppressionId}" \
  -H "X-API-Key: $MAILNEO_API_KEY"
Authorization
Required scope
suppressions:delete. A key without it is refused before the endpoint runs.
Credential
X-API-Key: mk_live_...Authorization: Bearer mk_live_...
Path parameters1
NameTypeRequiredNotes
suppressionIdstringYesmax 64 chars
Query parameters1
NameTypeRequiredNotes
dry_runbooleanNoReport what this call WOULD do and commit nothing. Returns data: null and a meta.impact block. Requires the resource's :read scope in addition to the scope this endpoint declares. Must be exactly true or false.
Response · 200

Success

dataMay be null.

FieldTypeAlways presentNotes
object"suppression"Yes
idstringYes
deletedtrueYes

meta

FieldTypeAlways presentNotes
request_idstringYes
dry_runbooleanYes
impactobjectNo
impact.object"impact"Yes
impact.would_createintegerYes
impact.would_updateintegerYes
impact.would_deleteintegerYes
impact.affected_countintegerYes
impact.affected_idsstring[]Yes
impact.quotaobject · nullableYes
impact.quota.kindstringYes
impact.quota.would_consumeintegerYes
impact.quota.limitinteger · nullableYes
impact.quota.currentintegerYes

Next Steps