curl --request POST \
--url https://api.upliftai.org/v1/contact-lists \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Al-Falah payment reminders — August",
"kind": "csv_upload",
"uploadId": "f352c8d3-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
'{
"listId": "590e4881-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"organizationId": "a12b7e74-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"projectId": "c782a4ec-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Al-Falah payment reminders — August",
"sourceKind": "csv_upload",
"sourceRef": "f352c8d3-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"summary": {
"willBeCalled": 2,
"excluded": {
"invalidPhone": 1,
"missingName": 1,
"duplicate": 1,
"dnc": 0,
"recentlyCalled": 0
},
"errors": [
{
"row": 4,
"issue": "duplicate",
"value": "+923001234567"
},
{
"row": 5,
"issue": "missingName",
"value": "+923451234567"
},
{
"row": 6,
"issue": "invalidPhone",
"value": "0300123"
}
]
},
"contactCount": 2,
"createdAt": "2026-08-18T05:20:09.138Z",
"updatedAt": "2026-08-18T05:20:09.138Z",
"version": 1
}Create a contact list
Turn rows into a stored list you can call: an upload from /contact-lists/uploads, inline CSV or pasted lines, or a Google Sheet. The import validates rows and deduplicates by phone number, keeping only contacts that can be dialed. Pass the returned listId as a campaign’s config.contacts.listId. A list is never edited — to call a different set of people, import again. To see the outcome before creating: dry-run inline rows or a sheet, re-preview an uploaded file. Column naming rules: Special column names.
curl --request POST \
--url https://api.upliftai.org/v1/contact-lists \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Al-Falah payment reminders — August",
"kind": "csv_upload",
"uploadId": "f352c8d3-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
'{
"listId": "590e4881-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"organizationId": "a12b7e74-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"projectId": "c782a4ec-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "Al-Falah payment reminders — August",
"sourceKind": "csv_upload",
"sourceRef": "f352c8d3-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"summary": {
"willBeCalled": 2,
"excluded": {
"invalidPhone": 1,
"missingName": 1,
"duplicate": 1,
"dnc": 0,
"recentlyCalled": 0
},
"errors": [
{
"row": 4,
"issue": "duplicate",
"value": "+923001234567"
},
{
"row": 5,
"issue": "missingName",
"value": "+923451234567"
},
{
"row": 6,
"issue": "invalidPhone",
"value": "0300123"
}
]
},
"contactCount": 2,
"createdAt": "2026-08-18T05:20:09.138Z",
"updatedAt": "2026-08-18T05:20:09.138Z",
"version": 1
}Authorizations
Project API key (sk_api_…).
Body
- Uploaded file
- Inline CSV or pasted rows
- Google Sheet (one-time pull)
1 - 120csv_upload An upload from /contact-lists/uploads, reusable for more than one list.
Overrides the columns detected when the file was uploaded.
Show child attributes
Show child attributes
Response
The stored list.
csv_upload, paste, google_sheets, customer_api Present only when the import supplied an uploadId or a sheet ref — inline rows have none, even when labelled csv_upload.
What the import kept and dropped.
Show child attributes
Show child attributes
Contacts stored — the same number as summary.willBeCalled.
Equal to createdAt, since a list is never edited.
Always 1.
