Suppression list API
The list of addresses that no longer receive email from your team.
The suppression list holds addresses that should no longer receive email from your team. Permanent bounces (bounce) and spam complaints (complaint) are added automatically; you can also add addresses yourself (manual). Suppressed recipients are removed from the send and generate the email.suppressed event. An address on the list also never becomes a contact: creating it answers 422 email_suppressed and the import skips it. In endpoints with {id}, you can use either the ID or the email address itself.
#List suppressions
GET/suppressions
Accepts limit, after and before. source_id is the email that caused the bounce or the complaint.
cURL
curl https://api.postal.so/suppressions \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/suppressions', {
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
},
});
const data = await response.json();
Python
import os
import requests
response = requests.get(
"https://api.postal.so/suppressions",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->get('suppressions', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "list",
"has_more": false,
"data": [
{
"object": "suppression",
"id": "019a1530-6d7e-7f80-9a1b-2c3d4e5f6a7b",
"email": "[email protected]",
"origin": "bounce",
"source_id": "019a1b2c-4d5e-7f60-8a9b-0c1d2e3f4a5b",
"created_at": "2026-10-20T09:12:00.000000Z"
}
]
}
#Add an address
POST/suppressions
Adds the address with origin manual. If it is already on the list, returns the existing record with status 200. Triggers suppression.added.
Request body
emailstringrequiredEmail address, up to 320 characters.
Errors
- 422
validation_errorA field is invalid. The message says which one.
cURL
curl -X POST https://api.postal.so/suppressions \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]"
}'
Node.js
const response = await fetch('https://api.postal.so/suppressions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: '[email protected]',
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.post(
"https://api.postal.so/suppressions",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"email": "[email protected]",
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->post('suppressions', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'json' => [
'email' => '[email protected]',
],
]);
$data = json_decode($response->getBody(), true);
{
"object": "suppression",
"id": "019a1c20-8f90-7aa1-8b2c-3d4e5f6a7b8c",
"email": "[email protected]",
"origin": "manual",
"source_id": null,
"created_at": "2026-10-20T09:12:00.000000Z"
}
#Add in bulk
POST/suppressions/batch/add
Request body
emailsstring[]requiredFrom 1 to 100 addresses.
Errors
- 422
validation_errorA field is invalid. The message says which one.
cURL
curl -X POST https://api.postal.so/suppressions/batch/add \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": ["[email protected]", "[email protected]"]
}'
Node.js
const response = await fetch('https://api.postal.so/suppressions/batch/add', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
emails: ['[email protected]', '[email protected]'],
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.post(
"https://api.postal.so/suppressions/batch/add",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"emails": ["[email protected]", "[email protected]"],
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->post('suppressions/batch/add', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'json' => [
'emails' => ['[email protected]', '[email protected]'],
],
]);
$data = json_decode($response->getBody(), true);
{
"data": [
{
"object": "suppression",
"id": "019a1c21-0a1b-7c2d-9e3f-4a5b6c7d8e9f"
},
{
"object": "suppression",
"id": "019a1c21-0a1c-7d3e-8f4a-5b6c7d8e9f0a"
}
]
}
#Remove in bulk
POST/suppressions/batch/remove
Removes by address or by ID (one of the two). Items that are not on the list are ignored.
Request body
emailsstring[]From 1 to 100 addresses.idsstring[]From 1 to 100 IDs. Use instead ofemails.
Errors
- 422
validation_errorNeither field, or both together.
cURL
curl -X POST https://api.postal.so/suppressions/batch/remove \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": ["[email protected]"]
}'
Node.js
const response = await fetch('https://api.postal.so/suppressions/batch/remove', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
emails: ['[email protected]'],
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.post(
"https://api.postal.so/suppressions/batch/remove",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"emails": ["[email protected]"],
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->post('suppressions/batch/remove', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'json' => [
'emails' => ['[email protected]'],
],
]);
$data = json_decode($response->getBody(), true);
{
"data": [
{
"object": "suppression",
"id": "019a1c21-0a1b-7c2d-9e3f-4a5b6c7d8e9f",
"deleted": true
}
]
}
#Get a suppression
GET/suppressions/{id}
Path parameters
idstringrequiredID or email address.
Errors
- 404
not_foundThe resource does not exist or belongs to another team.
cURL
curl https://api.postal.so/suppressions/[email protected] \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/suppressions/[email protected]', {
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
},
});
const data = await response.json();
Python
import os
import requests
response = requests.get(
"https://api.postal.so/suppressions/[email protected]",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->get('suppressions/[email protected]', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "suppression",
"id": "019a1530-6d7e-7f80-9a1b-2c3d4e5f6a7b",
"email": "[email protected]",
"origin": "bounce",
"source_id": "019a1b2c-4d5e-7f60-8a9b-0c1d2e3f4a5b",
"created_at": "2026-10-20T09:12:00.000000Z"
}
#Remove an address
DELETE/suppressions/{id}
The address can receive email again. If it was suppressed because of a bounce, first confirm that the problem has been fixed. Triggers suppression.removed.
Path parameters
idstringrequiredID or email address.
Errors
- 404
not_foundThe resource does not exist or belongs to another team.
cURL
curl -X DELETE https://api.postal.so/suppressions/019a1530-6d7e-7f80-9a1b-2c3d4e5f6a7b \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/suppressions/019a1530-6d7e-7f80-9a1b-2c3d4e5f6a7b', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
},
});
const data = await response.json();
Python
import os
import requests
response = requests.delete(
"https://api.postal.so/suppressions/019a1530-6d7e-7f80-9a1b-2c3d4e5f6a7b",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->delete('suppressions/019a1530-6d7e-7f80-9a1b-2c3d4e5f6a7b', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "suppression",
"id": "019a1530-6d7e-7f80-9a1b-2c3d4e5f6a7b",
"deleted": true
}