Push leads into a list
const url = 'https://app.whatsetter.com/api/v1/lists/example/leads';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"leads":[{"phone":"+33612345678","name":"Marie Dupont","email":"marie@acme.fr","custom_variables":{"offre":"Pack Pro","ville":"Lyon"}},{"phone":"not a phone"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”object
object
International format, e.g. +33612345678.
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" } ]}Responses
Section titled “Responses”Import result (valid rows imported, the rest listed in rejected)
object
object
Rows created in the list.
Valid rows skipped because the phone was already in the list.
Rows not imported, by position in leads.
object
invalid_phone: …, duplicate_in_batch, custom_variables must be an object, custom_variables exceeds 2000 characters, or a storage error message.
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
object
object
Examplegenerated
{ "error": { "code": "example", "message": "example" }}Resource not found in this workspace
object
object
Examplegenerated
{ "error": { "code": "example", "message": "example" }}leads is not an array of 1–500 objects, or no row is importable
object
object
Example
{ "error": { "code": "validation_error", "message": "No importable lead in the batch (2 rejected). First reason: duplicate_in_batch." }}
