Skip to content

Push leads into a list

POST
/lists/{id}/leads
curl --request POST \
--url https://app.whatsetter.com/api/v1/lists/example/leads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "leads": [ { "phone": "+33612345678", "name": "Marie Dupont", "email": "marie@acme.fr", "custom_variables": { "offre": "Pack Pro", "ville": "Lyon" } }, { "phone": "not a phone" } ] }'

The CRM-integration primitive: add up to 500 leads per call. Phones are deduplicated (within the batch and against the list). Imported leads go through WhatSetter’s normal verification and anti-ban sending pipeline.

Per-row rules: phone must be an international number (8–15 digits, + optional); name and email are truncated at 255 characters, never rejected; custom_variables must be an object whose JSON is at most 2000 characters. A row that breaks a rule lands in rejected with its index and a reason — invalid_phone: …, duplicate_in_batch, custom_variables must be an object, custom_variables exceeds 2000 characters, or the storage error message on a rare write failure — while the valid rows are still imported. A phone already in the list is counted in duplicates_in_list, not rejected. When no row is importable the call answers 422. Requires scope lists:write.

id
required
string
Media typeapplication/json
object
leads
required
Array<object>
>= 1 items <= 500 items
object
phone
required

International format, e.g. +33612345678.

string
name
string
<= 255 characters
email
string
<= 255 characters
custom_variables

Free-form variables usable in message personalization (JSON ≤ 2000 characters).

object
Example
{
"leads": [
{
"phone": "+33612345678",
"name": "Marie Dupont",
"email": "marie@acme.fr",
"custom_variables": {
"offre": "Pack Pro",
"ville": "Lyon"
}
},
{
"phone": "not a phone"
}
]
}

Import result (valid rows imported, the rest listed in rejected)

Media typeapplication/json
object
data
object
imported

Rows created in the list.

integer
duplicates_in_list

Valid rows skipped because the phone was already in the list.

integer
rejected

Rows not imported, by position in leads.

Array<object>
object
index
integer
reason

invalid_phone: …, duplicate_in_batch, custom_variables must be an object, custom_variables exceeds 2000 characters, or a storage error message.

string
lead_ids
Array<string>
Example
{
"data": {
"imported": 1,
"duplicates_in_list": 0,
"rejected": [
{
"index": 1,
"reason": "invalid_phone: expected international format, e.g. +33612345678"
}
],
"lead_ids": [
"68f0aa11bb22cc33dd44ee55"
]
}
}

Missing, unknown or revoked API key

Media typeapplication/json
object
error
object
code
string
message
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

Resource not found in this workspace

Media typeapplication/json
object
error
object
code
string
message
string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

leads is not an array of 1–500 objects, or no row is importable

Media typeapplication/json
object
error
object
code
string
message
string
Example
{
"error": {
"code": "validation_error",
"message": "No importable lead in the batch (2 rejected). First reason: duplicate_in_batch."
}
}