Contacts

Getting people into a list, one batch or one file at a time.

Two ways in, both JSON requests. Send the contacts in the body, or send a fileUrl the platform fetches (up to 10 MB, from a public http or https address, such as a pre-signed storage link). Either way the import runs in the background: the response is 202 with an import job to poll, not a result.

Each contact needs phoneNumber and fullName. firstName, lastName and email are optional, and the list's own fields go in data, keyed by fieldName. Rows are checked against the list's schema; a row that fails is counted in the job's failedRows and listed in its errors, and with continueOnError (the default) the rest still land.

A file is JSON (an array of contact objects, same shape as the inline ones) or CSV (a header row, then data). mapping renames source keys to field names, e.g. { "Phone": "phoneNumber" }; without it every column or key is imported under its own name. One import runs per list at a time; another answers 409.

Import contacts#

Queues an import of contacts given inline, or of a file at `fileUrl`. Returns the import job to poll with `GET /api/v1/import-jobs/{id}`.

POST/api/v1/contact-lists/{id}/contacts

Path parameters

idstringrequired
Contact list id.

Body

application/json
contacts
{ phoneNumber, fullName, firstName?, lastName?, email?, data? }[]
fileUrl
string (instead of contacts)
fileFormat
json | csv (required with fileUrl)
mapping
Record<sourceColumn, fieldName> (fileUrl only)
options
{ skipDuplicates?: boolean (default true), duplicateKeyField?: string (default phoneNumber), onDuplicate?: skip | merge | replace, continueOnError?: boolean (default true) }

Responses

Accepted. `totalContacts` is how many rows were handed over.

curl -X POST "https://voice.evryhealth.com/api/v1/contact-lists/{id}/contacts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{
"phoneNumber": "+14155551234",
"fullName": "Jane Doe",
"email": "jane@example.com",
"data": {
"memberId": "M-10293",
"renewalDate": "2026-03-01"
}
}
],
"options": {
"onDuplicate": "merge"
}
}'
Response202
{
"importJobId": "b0a7e4d2-5c3f-4e8a-9b1c-7d6e5f4a3b21",
"status": "queued",
"totalContacts": 1,
"links": {
"job": "/api/v1/import-jobs/b0a7e4d2-5c3f-4e8a-9b1c-7d6e5f4a3b21"
}
}

List contacts#

The contacts in a list, a page at a time.

GET/api/v1/contact-lists/{id}/contacts

Path parameters

idstringrequired
Contact list id.

Query parameters

pagenumber
Page number.
Default1
pageSizenumber
Contacts per page, up to 100.
Default50

Responses

A page of contacts. `data` holds the list's own fields.

curl -X GET "https://voice.evryhealth.com/api/v1/contact-lists/{id}/contacts" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"contacts": [
{
"id": "e3c9a1b7-2d4f-4a6e-8b0c-1f2e3d4c5b6a",
"phoneNumber": "4155551234",
"fullName": "Jane Doe",
"firstName": null,
"lastName": null,
"email": "jane@example.com",
"data": {
"memberId": "M-10293",
"renewalDate": "2026-03-01"
},
"createdAt": "2026-01-20T10:31:02.000Z",
"updatedAt": "2026-01-20T10:31:02.000Z"
}
],
"pagination": {
"page": 1,
"pageSize": 50,
"total": 500,
"totalPages": 10
}
}