Suppression lists
8 endpoints. Every path below is relative to the API base URL and already includes the /api/v1 prefix — see conventions for authentication, pagination, errors and idempotency.
| Endpoint | ||
|---|---|---|
| GET | /suppression-lists | List every suppression list in the organization by name with its entry count |
| POST | /suppression-lists | Create a suppression list, deriving a unique URL-safe key from the name when none is supplied |
| GET | /suppression-lists/{suppressionListId} | Retrieve one suppression list with its type, campaign scope and entry count |
| PATCH | /suppression-lists/{suppressionListId} | Update a suppression list's name, description, type, campaign scope or enabled flag |
| DELETE | /suppression-lists/{suppressionListId} | Delete a suppression list and return an empty body |
| GET | /suppression-lists/{suppressionListId}/entries | List a suppression list's numbers, optionally narrowed by a search substring match |
| POST | /suppression-lists/{suppressionListId}/entries | Add up to 10000 numbers in bulk, normalising to E.164 and reporting added, duplicate and invalid |
| DELETE | /suppression-lists/{suppressionListId}/entries/{entry} | Remove one number from a suppression list and refresh the list's entry count |
Endpoints
List every suppression list in the organization by name with its entry count
GET/suppression-lists
- Requires
campaign.read. - Unpaginated and returns no meta block, unlike every other list endpoint in this API
bash
curl -X GET "$CALLAGENT_API_URL/suppression-lists" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
200 | data-wrapped array |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.read scope |
Example response, generated from the schema:
json
{
"data": [
"string"
]
}Create a suppression list, deriving a unique URL-safe key from the name when none is supplied
POST/suppression-lists
- Requires
campaign.write.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | max 255 chars |
key | string | null | — | max 96 chars |
description | string | null | — | |
type | dnc · opt_out · internal · imported · litigator · null | null | — | |
applies_to_all_campaigns | boolean | null | — |
bash
curl -X POST "$CALLAGENT_API_URL/suppression-lists" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Support Line",
"type": "dnc",
"applies_to_all_campaigns": true
}'js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Support Line",
"type": "dnc",
"applies_to_all_campaigns": true
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Support Line',
'type' => 'dnc',
'applies_to_all_campaigns' => true,
]),
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.post(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
json={
"name": "Support Line",
"type": "dnc",
"applies_to_all_campaigns": True
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
201 | data-wrapped object |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.write scope |
422 | Field validation failed |
Example response, generated from the schema:
json
{
"data": {
"id": "01JQ0000000000000000000000",
"name": "Support Line",
"key": "string",
"description": "string",
"type": "string",
"applies_to_all_campaigns": true,
"enabled": true,
"entries_count": 1
}
}Retrieve one suppression list with its type, campaign scope and entry count
GET/suppression-lists/{suppressionListId}
- Requires
campaign.read.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
suppressionListId | string | yes |
bash
curl -X GET "$CALLAGENT_API_URL/suppression-lists/01JQ0000000000000000000000" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists/01JQ0000000000000000000000`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists/01JQ0000000000000000000000');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists/01JQ0000000000000000000000",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
200 | data-wrapped object |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.read scope |
404 | No suppression list with that id in this organization |
Example response, generated from the schema:
json
{
"data": {
"id": "01JQ0000000000000000000000",
"name": "Support Line",
"key": "string",
"description": "string",
"type": "string",
"applies_to_all_campaigns": true,
"enabled": true,
"entries_count": 1
}
}Update a suppression list's name, description, type, campaign scope or enabled flag
PATCH/suppression-lists/{suppressionListId}
- Requires
campaign.write. - The body is not validated, so this endpoint cannot return 422; an out-of-range
typeis written straight through
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
suppressionListId | string | yes |
bash
curl -X PATCH "$CALLAGENT_API_URL/suppression-lists/01JQ0000000000000000000000" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists/01JQ0000000000000000000000`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists/01JQ0000000000000000000000');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.patch(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists/01JQ0000000000000000000000",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
200 | data-wrapped object |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.write scope |
404 | No suppression list with that id in this organization |
Example response, generated from the schema:
json
{
"data": {
"id": "01JQ0000000000000000000000",
"name": "Support Line",
"key": "string",
"description": "string",
"type": "string",
"applies_to_all_campaigns": true,
"enabled": true,
"entries_count": 1
}
}Delete a suppression list and return an empty body
DELETE/suppression-lists/{suppressionListId}
- Requires
campaign.write. - This response is not
data-wrapped. - Deletes even when campaigns still reference the list in suppression_list_ids; no reference check is performed
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
suppressionListId | string | yes |
bash
curl -X DELETE "$CALLAGENT_API_URL/suppression-lists/01JQ0000000000000000000000" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists/01JQ0000000000000000000000`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists/01JQ0000000000000000000000');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.delete(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists/01JQ0000000000000000000000",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
204 | No content |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.write scope |
404 | No suppression list with that id in this organization |
List a suppression list's numbers, optionally narrowed by a search substring match
GET/suppression-lists/{suppressionListId}/entries
- Requires
campaign.read. - Page size comes from
limit(default 50, max 500); meta carries onlytotal, no page number
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
suppressionListId | string | yes |
bash
curl -X GET "$CALLAGENT_API_URL/suppression-lists/01JQ0000000000000000000000/entries" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists/01JQ0000000000000000000000/entries`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists/01JQ0000000000000000000000/entries');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists/01JQ0000000000000000000000/entries",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
200 | data-wrapped array |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.read scope |
404 | No suppression list with that id in this organization |
Example response, generated from the schema:
json
{
"data": [
{
"id": "01JQ0000000000000000000000",
"phone_number": "+40712345678",
"reason": "string",
"source": "string",
"expires_at": "2026-01-01T12:00:00+00:00"
}
],
"meta": {
"total": 1
}
}Add up to 10000 numbers in bulk, normalising to E.164 and reporting added, duplicate and invalid
POST/suppression-lists/{suppressionListId}/entries
- Requires
campaign.write. - Un-normalisable numbers are returned verbatim in
invalidrather than rejecting the request; re-adding an existing number counts as a duplicate
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
suppressionListId | string | yes |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
numbers | string[] | yes | min 1 items. max 10000 items |
reason | string | null | — | max 128 chars |
source | manual · import · api · ivr_opt_out · call_opt_out · null | null | — | |
expires_at | string | null | — | date-time |
default_country | string | null | — | max 8 chars |
bash
curl -X POST "$CALLAGENT_API_URL/suppression-lists/01JQ0000000000000000000000/entries" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"numbers": [
"string"
],
"source": "manual",
"expires_at": "2026-01-01T12:00:00+00:00"
}'js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists/01JQ0000000000000000000000/entries`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"numbers": [
"string"
],
"source": "manual",
"expires_at": "2026-01-01T12:00:00+00:00"
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists/01JQ0000000000000000000000/entries');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'numbers' => [
'string',
],
'source' => 'manual',
'expires_at' => '2026-01-01T12:00:00+00:00',
]),
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.post(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists/01JQ0000000000000000000000/entries",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
json={
"numbers": [
"string"
],
"source": "manual",
"expires_at": "2026-01-01T12:00:00+00:00"
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
201 | data-wrapped object |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.write scope |
404 | No suppression list with that id in this organization |
422 | Field validation failed on numbers, source or expires_at |
Example response, generated from the schema:
json
{
"data": {
"added": 1,
"duplicates": "string",
"invalid": [
"string"
]
}
}Remove one number from a suppression list and refresh the list's entry count
DELETE/suppression-lists/{suppressionListId}/entries/{entry}
- Requires
campaign.write. - This response is not
data-wrapped.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
suppressionListId | string | yes | |
entry | string | yes |
bash
curl -X DELETE "$CALLAGENT_API_URL/suppression-lists/01JQ0000000000000000000000/entries/01JQ0000000000000000000000" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/suppression-lists/01JQ0000000000000000000000/entries/01JQ0000000000000000000000`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();php
<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/suppression-lists/01JQ0000000000000000000000/entries/01JQ0000000000000000000000');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];python
import os, requests
response = requests.delete(
f"{os.environ['CALLAGENT_API_URL']}/suppression-lists/01JQ0000000000000000000000/entries/01JQ0000000000000000000000",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Responses
| Status | Body |
|---|---|
204 | No content |
Errors
| Status | When it happens |
|---|---|
403 | The API key does not carry the campaign.write scope |
404 | No such suppression list, or no such entry on that list |