Skip to content

Contact lists

Download .md

The contact lists a campaign sends to (audience.list), and the contacts in them. How-to: Run a campaign, Keep contacts.

Generated from /openapi/v1.json; interactive version: API reference.

methodpathwhat it doessuccess
GET/v1/listsList contact lists, for a campaign’s audience.list200
POST/v1/listsCreate a contact list, with its contacts201
GET/v1/lists/{id}Read a contact list200
PATCH/v1/lists/{id}Rename a contact list200
DELETE/v1/lists/{id}Delete a contact list no campaign is using200
GET/v1/lists/{id}/contactsList the contacts in a list200
POST/v1/lists/{id}/contactsAdd contacts to a list200
DELETE/v1/lists/{id}/contacts/{contact}Take one contact out of a list200

List contact lists, for a campaign’s audience.list.

Parameters

nameintypedescription
limitqueryinteger
1–200
Page size, 1 to 200 (default 50).
afterquerystringThe previous page’s next_cursor.

Answers 200 with ContactListList. Errors use the error envelope; common codes: contact lists, lists.

Create a contact list, with its contacts.

Makes a list (source: api) and imports contacts into it through the same import as a campaign’s audience.contacts: a number a contact already has reuses that contact, never a second one. Each phone is stored for SMS, calls and WhatsApp alike, so the list works for a campaign on any channel. Storing a number is not consent: opt-outs stay on the number. contact_ids adds contacts you already have, by id, as POST /v1/lists/{id}/contacts does; an id that is not one of your live contacts is skipped and named in import.errors. A request that names people (contacts and/or contact_ids) and would add none of them is 400 empty_audience_input and creates no list. Pass the list’s id as a campaign’s audience.list.

Parameters

nameintypedescription
idempotency-keyheaderstring
≤ 255 chars
Send one with every create. A retry with the same key makes no second list: it answers the first one as it is now, with the first import. Rules: Idempotency.

Request body: ContactListCreate.

Answers 201 with ContactListWithImport. Errors use the error envelope; common codes: contact lists, lists.

Read a contact list.

Parameters

nameintypedescription
idpathstring, requiredThe list’s cl-… id or UUID.

Answers 200 with ContactList. Errors use the error envelope; common codes: contact lists, lists.

Rename a contact list.

Changes the list’s name; nothing else. Any list GET /v1/lists shows can be renamed, whatever its source: a campaign list keeps its source and is still removed with its campaign’s draft. The same name is no change. A rename is idempotent, so no Idempotency-Key is needed (one sent is ignored). Add contacts with POST /v1/lists/{id}/contacts.

Parameters

nameintypedescription
idpathstring, requiredThe list’s cl-… id or UUID.

Request body: ContactListUpdate.

Answers 200 with ContactList. Errors use the error envelope; common codes: contact lists, lists.

Delete a contact list no campaign is using.

The list disappears from GET /v1/lists and can no longer be an audience.list. Its contacts, and their opt-outs, stay. Refused while a draft, queued, running or paused campaign uses it; a finished campaign does not keep it.

Parameters

nameintypedescription
idpathstring, requiredThe list’s cl-… id or UUID.

Answers 200 with the object below. Errors use the error envelope; common codes: contact lists, lists.

fieldtypedescription
idstring, required
objectstring, required
always contact_list
deletedboolean, required
always true

Example: see Run a campaign.

List the contacts in a list.

Parameters

nameintypedescription
idpathstring, requiredThe list’s cl-… id or UUID.
limitqueryinteger
1–200
Page size, 1 to 200 (default 50).
afterquerystringThe previous page’s next_cursor.

Answers 200 with ContactListMemberList. Errors use the error envelope; common codes: contact lists, lists.

Add contacts to a list.

Imports contacts into the list, as POST /v1/lists does, and adds contact_ids, contacts you already have. Answers the list and what the import did: an id that is not one of your contacts is skipped and named in import.errors.

Parameters

nameintypedescription
idpathstring, requiredThe list’s cl-… id or UUID.
idempotency-keyheaderstring
≤ 255 chars
Send one with every add. A retry with the same key imports nothing twice: it answers the list as it is now, with the first import. Rules: Idempotency.

Request body: ContactListAddContacts.

Answers 200 with ContactListWithImport. Errors use the error envelope; common codes: contact lists, lists.

Take one contact out of a list.

contact is the contact’s ct-… id or UUID, or a phone number in E.164 (URL-encode the + as %2B). The contact itself, its numbers and its opt-outs are untouched.

Parameters

nameintypedescription
idpathstring, requiredThe list’s cl-… id or UUID.
contactpathstring, requiredct-…, a UUID, or E.164.

Answers 200 with the object below. Errors use the error envelope; common codes: contact lists, lists.

fieldtypedescription
idstring, required
objectstring, required
always contact_list_member
liststring, required
deletedboolean, required
always true

Example: see Run a campaign.

fieldtypedescription
objectstring, required
always list
dataarray of ContactList, required
has_moreboolean, required
next_cursorstring or null, requiredPass as after for the next page; null on the last.

Example: see Finding ids.

fieldtypedescription
idstring, requiredcl-…: pass as audience.list.
objectstring, required
always contact_list
uuidstring, required
namestring, required
sourcestring, required
api, dashboard, campaign
Who made it: api (POST /v1/lists), campaign (imported from a campaign’s inline contacts or csv; removed when that campaign is deleted, unless another campaign uses it), dashboard (the dashboard, a CSV upload or Octo).
contactsinteger, requiredHow many contacts the list holds (deleted contacts are not counted).
created_atstring or null, required

Example: see Finding ids.

fieldtypedescription
namestring, required
1–200 chars
contactsarray of objects
≤ 10,000 items
Up to 10,000 rows, the same rows as a campaign’s audience.contacts. Each phone is stored for SMS, calls and WhatsApp alike (one contact per number), so the list works for a campaign on any channel; that is not consent: opt-outs stay on the number. Leave it out for an empty list; an empty array is 400 empty_audience_input.
contacts[].phonestring, required
pattern ^\+[1-9]\d{6,14}$
Same as CampaignAudience.contacts[].phone.
contacts[].namestring
≤ 200 chars
Same as CampaignAudience.contacts[].name.
contacts[].emailstring
≤ 320 chars
contacts[].companystring
≤ 200 chars
contacts[].attributesmap of string to string or number or booleanCustom fields, readable as {{contact.<key>}} in variables.
contact_idsarray of string
≤ 1,000 items; each ≤ 64 chars
Up to 1,000 contacts you already have, by ct-… id or UUID, as on POST /v1/lists/{id}/contacts. One that is not a contact of this workspace (or was deleted) is skipped and named in import.errors. With contacts, both are added. A request that names people and would add nobody is 400 empty_audience_input and creates no list; an empty array is 400 empty_audience_input too.
{
"name": "October open house",
"contact_ids": [
"ct-00000000a1"
]
}

Rename a list. Its contacts are changed with POST /v1/lists/{id}/contacts.

fieldtypedescription
namestring, required
1–200 chars
The list’s new name (1 to 200 characters, trimmed).
{
"name": "November open house"
}
fieldtypedescription
idstring, requiredcl-…: pass as audience.list.
objectstring, required
always contact_list
uuidstring, required
namestring, required
sourcestring, required
api, dashboard, campaign
Who made it: api (POST /v1/lists), campaign (imported from a campaign’s inline contacts or csv; removed when that campaign is deleted, unless another campaign uses it), dashboard (the dashboard, a CSV upload or Octo).
contactsinteger, requiredHow many contacts the list holds (deleted contacts are not counted).
created_atstring or null, required
importobject, requiredWhat this request’s import did (source is contacts).
import.sourcestring or null, required
contacts, csv
Which inline audience was imported: audience.contacts or audience.csv.
import.receivedinteger, requiredRows received (blank CSV lines excluded).
import.importedinteger, requiredNew contacts made.
import.matched_existinginteger, requiredRows whose number a contact already had: that contact was used.
import.invalid_rowsinteger, requiredRows dropped because their phone number could not be read.
import.duplicate_in_fileinteger, requiredRows that repeated a number earlier in the same audience.
import.skipped_rowsinteger, requiredBlank CSV lines skipped.
import.race_lostinteger, requiredSame as Campaign.audience.import.race_lost.
import.errorsarray of objects, requiredEach dropped or partly read row: its line and why.
import.errors[].rowinteger, required
import.errors[].messagestring, required
import.warningsarray of string, requiredSame as Campaign.audience.import.warnings.

Example: see Run a campaign.

contacts, contact_ids, or both.

fieldtypedescription
contactsarray of objects
≤ 10,000 items
1 to 10,000 rows, as on POST /v1/lists. A number a contact already has reuses that contact; one already in the list stays once.
contacts[].phonestring, required
pattern ^\+[1-9]\d{6,14}$
Same as CampaignAudience.contacts[].phone.
contacts[].namestring
≤ 200 chars
Same as CampaignAudience.contacts[].name.
contacts[].emailstring
≤ 320 chars
contacts[].companystring
≤ 200 chars
contacts[].attributesmap of string to string or number or booleanCustom fields, readable as {{contact.<key>}} in variables.
contact_idsarray of string
≤ 1,000 items; each ≤ 64 chars
Up to 1,000 contacts you already have, by ct-… id or UUID. One that is not a contact of this workspace (or was deleted) is skipped and named in import.errors.
{
"contact_ids": [
"ct-00000000a1"
]
}
fieldtypedescription
objectstring, required
always list
dataarray of ContactListMember, required
has_moreboolean, required
next_cursorstring or null, requiredPass as after for the next page; null on the last.
{
"object": "list",
"data": [
{
"id": "ct-00000000a1",
"object": "contact",
"uuid": "00000000-0000-4000-8000-000000000012",
"name": null,
"phone": null,
"email": null,
"added_at": null
}
],
"has_more": false,
"next_cursor": null
}
fieldtypedescription
idstring, requiredThe contact’s ct-… id.
objectstring, required
always contact
uuidstring, required
namestring or null, required
phonestring or null, requiredE.164, or null for none.
emailstring or null, required
added_atstring or null, requiredWhen it joined the list (ISO 8601).
{
"id": "ct-00000000a1",
"object": "contact",
"uuid": "00000000-0000-4000-8000-000000000012",
"name": null,
"phone": null,
"email": null,
"added_at": null
}