API reference / Contacts
Contact lists
A list is a named group of contacts. Campaigns send to lists, so you'll use lists to decide who a campaign reaches. A contact can be on any number of lists. To label contacts without changing who a campaign reaches, use tags.
Routes
| Method | Route | Scope | What it does |
|---|---|---|---|
GET |
/contact/public/lists |
lists:read |
List your lists |
POST |
/contact/public/lists |
lists:write |
Create a list |
GET |
/contact/public/lists/{list_id} |
lists:read |
Get one list with its counts |
GET |
/contact/public/lists/{list_id}/contacts |
lists:read |
Page through the contacts on a list |
PUT |
/contact/public/lists/{list_id} |
lists:write |
Rename a list |
DELETE |
/contact/public/lists/{list_id} |
lists:write |
Delete a list |
POST |
/contact/public/contacts/{contact_id}/lists |
lists:write |
Add a contact to lists |
DELETE |
/contact/public/contacts/{contact_id}/lists/{list_id} |
lists:write |
Remove a contact from a list |
POST |
/contact/public/contacts/{contact_id}/lists/move |
lists:write |
Move a contact from one list to another |
List your lists
Returns a page of your lists with a contact_count for each. Page with offset and limit. The built-in Unlisted list, which holds contacts that aren't on any other list, comes first.
| Field | Type | Required | Description |
|---|---|---|---|
search_term |
string | No | Matches list names, including partly typed words. |
sort_by |
string | No | created_at (default), list_name, modified_at or contact_count. |
sort_order |
string | No | desc (default) or asc. |
limit |
integer | No | Page size. Default 25. |
offset |
integer | No | Number of lists to skip. Default 0. |
curl "https://api-v2.dropcowboy.com/contact/public/lists?sort_by=list_name&sort_order=asc&limit=25" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"lists": [
{
"list_id": "3b2f0314-e849-4799-9969-af93349bef75",
"list_name": "October webinar signups",
"brand_id": "070df69e-101c-41d8-b5f3-b2d79f77d2a9",
"owner": "d8ea4045-3e3c-45e6-b2ba-3917287c378c",
"contact_count": 1240,
"created_at": 1790870333466,
"created_by": "d8ea4045-3e3c-45e6-b2ba-3917287c378c",
"modified_at": 1790870333466
}
],
"next_cursor": null
},
"meta": { "request_id": "35f86685-859f-4a8d-926a-45ec7fba7ddc" }
}
Keep requesting the next offset until a page has fewer lists than limit.
Create a list
Creates an empty list. Add contacts with Create contacts and add_list_ids, or with Add a contact to lists. List names are unique in your account.
| Field | Type | Required | Description |
|---|---|---|---|
list_name |
string | No | Name of the list. Defaults to My List. |
compliance |
boolean | No | Send true to store a compliance acknowledgement on the list. We record your user id, the time and your IP address. |
curl -X POST "https://api-v2.dropcowboy.com/contact/public/lists" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "list_name": "October webinar signups" }'
The response is 201 with the new list.
{
"data": {
"list_id": "3b2f0314-e849-4799-9969-af93349bef75",
"list_name": "October webinar signups",
"brand_id": "070df69e-101c-41d8-b5f3-b2d79f77d2a9",
"owner": "d8ea4045-3e3c-45e6-b2ba-3917287c378c",
"created_at": 1790870333466,
"created_by": "d8ea4045-3e3c-45e6-b2ba-3917287c378c",
"modified_at": 1790870333466,
"deleted_at": null
},
"meta": { "request_id": "22b934c0-e7e6-4f07-8608-e2bc91f06e39" }
}
Get a list
Returns one list with its contact and phone counts. The list is in data.list.
The number of contacts on the list is import.accepted_count.
curl "https://api-v2.dropcowboy.com/contact/public/lists/3b2f0314-e849-4799-9969-af93349bef75" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"list": {
"list_id": "3b2f0314-e849-4799-9969-af93349bef75",
"list_name": "October webinar signups",
"import": { "status": "done", "accepted_count": 1240 },
"total_phone_numbers": 1302,
"wireless_count": 911,
"landline_count": 287,
"voip_count": 104,
"email_capable_count": 1188,
"created_at": 1790870333466,
"modified_at": 1790870333466
}
},
"meta": { "request_id": "5292b8c9-4b2d-44c5-84b7-5dd37627aeb8" }
}
List a list's contacts
Pages through every contact on a list, in a stable order. Use it to read a whole list, or to follow the more_via link in a list webhook. Pass the next_cursor from each response as after_id on the next call, and stop when has_more is false.
| Field | Type | Required | Description |
|---|---|---|---|
after_id |
string | No | The next_cursor from the previous page. Leave it out for the first page. |
limit |
integer | No | Page size, 1 to 500. Default 25. |
curl "https://api-v2.dropcowboy.com/contact/public/lists/3b2f0314-e849-4799-9969-af93349bef75/contacts?limit=500&after_id=7352269114606e7c55c244d9" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"contacts": [
{
"_id": "146f9b4b080717ef5e4c3fd0",
"contact_id": "756c1b7d-c27d-4faf-9365-bb83f0cbed66",
"field_data": [
{ "field_id": "8e42bc36-efeb-42c1-b99b-41ae9c60aa66", "type": "first_name", "value": "Dana" }
],
"phone_numbers": ["+13125550142"],
"list_ids": ["3b2f0314-e849-4799-9969-af93349bef75"],
"dnc": false,
"tags": [],
"created_at": 1790870333466,
"modified_at": 1790870333466
}
],
"next_cursor": "146f9b4b080717ef5e4c3fd0",
"has_more": true
},
"meta": { "request_id": "c99a62ba-d867-42e7-8814-c718d2254493" }
}
Field values are in field_data. For the flattened fields, consent flags and everything else, call Get a contact.
Rename a list
Changes the list's name.
| Field | Type | Required | Description |
|---|---|---|---|
list_name |
string | Yes | New name. Must not match another of your lists. |
curl -X PUT "https://api-v2.dropcowboy.com/contact/public/lists/3b2f0314-e849-4799-9969-af93349bef75" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "list_name": "Webinar signups (October)" }'
The response is the updated list, in the same shape as Create a list.
Delete a list
Deletes the list. Its contacts are removed from the list and stay in your account. To delete the contacts as well, send delete_contacts: true. That needs permission to delete contacts.
| Field | Type | Required | Description |
|---|---|---|---|
delete_contacts |
boolean | No | true also deletes every contact on the list. Default false. |
curl -X DELETE "https://api-v2.dropcowboy.com/contact/public/lists/3b2f0314-e849-4799-9969-af93349bef75" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "delete_contacts": false }'
{
"data": {
"list_id": "3b2f0314-e849-4799-9969-af93349bef75",
"contacts_deleted": 0
},
"meta": { "request_id": "34f38d24-632d-4a9c-bf89-b9371a722b35" }
}
A list that's protected from deletion in the app isn't deleted. Check with Get a list if you need to be sure.
Add a contact to lists
Adds one contact to one or more lists. Lists are added in order, and the call stops at the first list that fails, so the lists before it keep the contact.
| Field | Type | Required | Description |
|---|---|---|---|
list_ids |
array | Yes | One or more list ids. |
curl -X POST "https://api-v2.dropcowboy.com/contact/public/contacts/756c1b7d-c27d-4faf-9365-bb83f0cbed66/lists" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "list_ids": ["3b2f0314-e849-4799-9969-af93349bef75", "5292b8c9-4b2d-44c5-84b7-5dd37627aeb8"] }'
The response is the contact, in the same shape as Get a contact. Check its list_ids.
Remove a contact from a list
Takes the contact off one list. The contact stays in your account and on its other lists.
curl -X DELETE "https://api-v2.dropcowboy.com/contact/public/contacts/756c1b7d-c27d-4faf-9365-bb83f0cbed66/lists/3b2f0314-e849-4799-9969-af93349bef75" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"success": true,
"list_id": "3b2f0314-e849-4799-9969-af93349bef75",
"contact_ids": ["756c1b7d-c27d-4faf-9365-bb83f0cbed66"],
"skipped": [],
"skipped_brand_mismatch": []
},
"meta": { "request_id": "a29a27a4-9b92-4696-bf96-ecc7fe7a5366" }
}
Move a contact from one list to another
Takes the contact off from_list_id and adds it to to_list_id in one step. Use it for pipelines, such as moving a lead from "New" to "Qualified".
| Field | Type | Required | Description |
|---|---|---|---|
from_list_id |
string | Yes | List to take the contact off. |
to_list_id |
string | Yes | List to add the contact to. |
curl -X POST "https://api-v2.dropcowboy.com/contact/public/contacts/756c1b7d-c27d-4faf-9365-bb83f0cbed66/lists/move" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"from_list_id": "3b2f0314-e849-4799-9969-af93349bef75",
"to_list_id": "5292b8c9-4b2d-44c5-84b7-5dd37627aeb8"
}'
The response has the same shape as Remove a contact from a list, with list_id set to to_list_id. If skipped_brand_mismatch lists the contact, the target list belongs to a different brand and the contact wasn't added. Pick a list of the contact's brand.
Errors
On these routes, the type URL in an error doesn't tell errors apart. Branch on status.
| Status | When | What to do |
|---|---|---|
400 |
list_ids is missing, empty, or has an empty id. |
Send an array of list ids. |
400 |
Moving without both from_list_id and to_list_id. |
Send both. |
400 |
after_id isn't a cursor this route returned. |
Start again without after_id, then pass each next_cursor unchanged. |
400 |
Sending visibility when you create or rename a list. |
Leave it out. Visibility follows the list's owner. |
400 |
Deleting the Unlisted list. | Leave it. It's built in and can't be deleted. |
400 |
Creating a list when your account files every list under a brand (Assign this list to a brand before creating it.). |
Create the list in the app, where you can pick its brand. |
402 |
Creating a list, or adding or moving a contact, while your subscription is inactive. | See Payment required. |
403 |
delete_contacts: true without permission to delete contacts. |
Delete the list without delete_contacts, or ask an admin. |
404 |
The list doesn't exist or you can't see it. | Check the list_id with List your lists. |
409 |
The name matches another of your lists, or is reserved. | Choose a different name. |
For everything else, see Responses, errors and limits.