API reference / Contacts
Do-not-contact list
Your do-not-contact list blocks sends to the phone numbers and emails on it, whatever consent you hold for them. Use these routes to check a number before you send, to add people who asked you to stop through another system, and to remove entries you added by mistake. Contacts add themselves when they reply STOP or unsubscribe, as Consent describes. A send blocked by the list fails with an outcome such as 4016 or 5014.
Routes
| Method | Route | Scope | What it does |
|---|---|---|---|
GET |
/dnc/public/dnc |
dnc:read |
Check whether numbers or emails are listed |
GET |
/dnc/public/dnc/{phone_number} |
dnc:read |
Check one number |
GET |
/dnc/public/dnc/email/{email} |
dnc:read |
Check one email |
POST |
/dnc/public/dnc |
dnc:write |
Add numbers or emails |
DELETE |
/dnc/public/dnc/{phone_number} |
dnc:write |
Remove a number |
DELETE |
/dnc/public/dnc/email/{email} |
dnc:write |
Remove an email |
POST |
/dnc/public/dnc/bulk-delete |
dnc:write |
Remove several numbers or emails |
Send phone numbers in E.164 format, like +13125550142. Matching is exact, so a number in another format won't match. In a URL, write + as %2B.
An entry blocks either one brand or all your brands. Leave brand_id out when you add an entry and it blocks sends from every brand.
Entries a contact made themselves can't be removed. That covers a STOP reply, an RCS opt-out suggestion, a keypress opt-out during a call, and an email unsubscribe.
Check numbers or emails
Tells you whether any of the numbers or emails you send are listed. Check before you send to a list you built outside Drop Cowboy®.
| Field | Type | Required | Description |
|---|---|---|---|
phone_numbers |
string | One of phone_numbers or emails |
Comma-separated numbers. |
emails |
string | One of phone_numbers or emails |
Comma-separated emails. Case doesn't matter. |
brand_id |
string | No | The brand you'll send from. Matches that brand's entries and the entries for all brands. Without it, any entry counts. |
curl "https://api-v2.dropcowboy.com/dnc/public/dnc?phone_numbers=%2B13125550142,%2B13125550187" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"on_dnc": true,
"phone_numbers": ["+13125550142", "+13125550187"],
"emails": [],
"matched": ["+13125550142"],
"data": [
{
"brand_id": null,
"phone_number": "+13125550142",
"email": null,
"method": "sms",
"reason": "STOP keyword",
"self_added": true,
"created_at": 1790870333466,
"updated_at": 1790870333466
}
]
},
"meta": { "request_id": "bb48e07b-8e58-4772-a6b3-c7c8f0f397c5" }
}
on_dnc is true when anything matched. matched lists the numbers and emails that are listed, and the inner data holds their entries. A brand_id of null means the entry blocks every brand. self_added: true means the contact opted out themselves.
Check one number or email
GET /dnc/public/dnc/{phone_number} and GET /dnc/public/dnc/email/{email} check a single identifier. A listed one returns 200 with the same body as above. One that isn't listed returns 404, so treat 404 as "OK to send". Both accept brand_id.
curl "https://api-v2.dropcowboy.com/dnc/public/dnc/%2B13125550142?brand_id=2c9d4e1f-7a3b-4f6c-8d2e-9b1a5c7e3f40" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
Add numbers or emails
Adds one or more numbers or emails. Contacts with a matching number or email get dnc: true. Adding an identifier that's already listed for the same brand updates its entry rather than duplicating it.
| Field | Type | Required | Description |
|---|---|---|---|
phone_number |
string or array | One of phone_number or email |
A number, or an array of numbers. |
email |
string or array | One of phone_number or email |
An email, or an array of emails. |
brand_id |
string | No | Block sends from this brand only. Leave it out to block every brand. |
reason |
string | No | Why you're adding it, shown with the entry. Default api. |
method |
string | No | Where the request came from, such as phone or crm. Default api. |
curl -X POST "https://api-v2.dropcowboy.com/dnc/public/dnc" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"phone_number": ["+13125550142", "+13125550187"],
"reason": "Asked to stop on a call with sales"
}'
The response is an array with two results for each number or email you sent: the entry, then the contacts it updated. If any were already listed, the array ends with an information_message.
{
"data": [
{ "success": true },
{ "acknowledged": true, "matchedCount": 1, "modifiedCount": 1, "upsertedId": null, "upsertedCount": 0 },
{ "success": true },
{ "acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": null, "upsertedCount": 0 },
{ "information_message": "Some entries are already in the list" }
],
"meta": { "request_id": "aeb42ad3-fde0-48d0-b97b-987c9f7b57fa" }
}
Remove a number
Removes a number you added. Contacts with that number get dnc: false. Removing a number that isn't listed still succeeds.
| Field | Type | Required | Description |
|---|---|---|---|
phone_number |
string | Yes | Path. The number, with + written as %2B. |
brand_id |
string | No | Query. Remove the entry for this brand. Without it, the most recently updated entry for the number is removed. |
A number can be listed for all brands and for one brand at the same time. To clear every entry for it in one call, use Remove several numbers or emails.
curl -X DELETE "https://api-v2.dropcowboy.com/dnc/public/dnc/%2B13125550187" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": [
{ "success": true },
{ "acknowledged": true, "matchedCount": 1, "modifiedCount": 1, "upsertedId": null, "upsertedCount": 0 }
],
"meta": { "request_id": "181c5b49-e44d-4dc7-a775-c22c9a88630e" }
}
Remove an email
Works like Remove a number, with the email in the path.
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | Yes | Path. The email, URL-encoded. |
brand_id |
string | No | Query. Remove the entry for this brand. |
curl -X DELETE "https://api-v2.dropcowboy.com/dnc/public/dnc/email/jordan%40example.com" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
The response has the same shape as Remove a number.
Remove several numbers or emails
Removes every entry you added for each number and email, across all brands unless you pass brand_id. Entries the contact made themselves are skipped, not refused, so one protected number doesn't stop the rest.
| Field | Type | Required | Description |
|---|---|---|---|
phone_numbers |
array | One of phone_numbers or emails |
Numbers to remove. |
emails |
array | One of phone_numbers or emails |
Emails to remove. |
brand_id |
string | No | Remove only this brand's entries. |
curl -X POST "https://api-v2.dropcowboy.com/dnc/public/dnc/bulk-delete" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"phone_numbers": ["+13125550142", "+13125550187"],
"emails": ["jordan@example.com"]
}'
{
"data": {
"deleted": ["+13125550187", "jordan@example.com"],
"skipped": [
{ "phone_number": "+13125550142", "email": null, "reason": "self_added_opt_out" }
]
},
"meta": { "request_id": "fd3f3fbd-9dcc-4524-a65f-71ccf42bcb84" }
}
deleted lists everything you sent that the contact didn't opt out of themselves, including identifiers that weren't listed. skipped lists the ones that stay blocked. An identifier with both kinds of entry appears in both.
Errors
On these routes, the type URL in an error doesn't tell errors apart. Branch on status.
| Status | When | What to do |
|---|---|---|
400 |
No number or email was sent. | Send at least one. |
400 |
Removing a single entry the contact made themselves (dnc contact cannot be deleted). |
Leave it. The contact asked you to stop, and you can't override that. |
For everything else, see Responses, errors and limits.
While Drop Cowboy provides tools to support compliance efforts, customers remain solely responsible for obtaining proper consent, maintaining opt-out lists, and complying with all federal and state telemarketing regulations. Consult with your legal counsel to ensure your specific use case and consent mechanisms comply with applicable laws.