Contacts & listes

Les exemples reprennent les variables BREVO_API_KEY et BREVO_BASE du démarrage rapide.

Contacts

curl -s -X POST "$BREVO_BASE/contacts" -H "api-key: $BREVO_API_KEY" \
  -H "content-type: application/json" -d '{
    "email": "jeanne@example.com",
    "attributes": { "FIRSTNAME": "Jeanne", "LASTNAME": "Martin" },
    "listIds": [3],
    "updateEnabled": true
  }'
  • POST /contacts crée un contact (201 {"id": 12}). Il faut au moins email, ext_id ou l'attribut SMS, sinon 400 missing_parameter. Si l'e-mail ou l'ext_id est déjà connu : 400 duplicate_parameter, sauf avec "updateEnabled": true (mise à jour, 204). Une liste inconnue dans listIds ou unlinkListIds renvoie 404 document_not_found.
  • GET/PUT/DELETE /contacts/{identifier} : l'identifiant est détecté automatiquement (e-mail, identifiant numérique, téléphone, sinon ext_id), ou forcé par ?identifierType=email_id|contact_id|ext_id|phone_id|whatsapp_id|landline_number_id. Un numéro composé uniquement de chiffres est lu comme un identifiant de contact : pour un téléphone, passez identifierType=phone_id ou le préfixe +. Contact introuvable : 404 document_not_found. PUT et DELETE répondent 204.
  • GET /contacts : pagination limit (50 par défaut, 1000 max.) / offset, sort (desc par défaut, sur la date de création), modifiedSince, createdSince, listIds, ids, et filter : equals(FIRSTNAME,"Jeanne"), lessThan(AGE,30), greaterThan(AGE,30). Sur EMAIL, SMS et EXT_ID, seul equals est pris en compte. Réponse {"contacts": [...], "count": 42}.
  • POST /contacts/batch : jusqu'à 100 mises à jour en une requête ({"contacts": [...]}, au-delà 400 out_of_range). Chaque élément est retrouvé par id, email, ext_id ou sms ; attributes.EMAIL change son adresse. Réponse 204.

Réinscrire un contact à une liste dont il s'était désabonné le réabonne.

Attributs

GET /contacts/attributes liste les attributs intégrés (FIRSTNAME, LASTNAME, SMS, WHATSAPP, LANDLINE_NUMBER) et vos attributs. Créez-en avec POST /contacts/attributes/{catégorie}/{nom} (catégorie normal, category, transactional, calculated ou global), modifiez ou supprimez-les par le même chemin en PUT / DELETE. Un attribut category exige enumeration ([{"value": 1, "label": "Or"}]).

Les valeurs sont converties selon leur type, comme chez Brevo :

Type Stocké comme
float nombre ("31,5" → 31.5)
boolean booléen (true/false, 1/0 acceptés)
date AAAA-MM-JJ
category libellé de l'énumération (valeur numérique ou libellé acceptés)
multiple-choice tableau de chaînes (tableau ou liste séparée par des virgules)
text texte

Une valeur qui ne correspond pas au type renvoie 400 invalid_parameter. Une valeur null efface l'attribut.

Listes et dossiers

Une liste appartient toujours à un dossier (POST /contacts/folders {name} puis POST /contacts/lists {name, folderId}, chacun répond 201 {"id"}). Supprimer un dossier supprime ses listes. GET /contacts/folders et GET /contacts/lists sont paginés (limit 10 par défaut, 50 max.) ; GET /contacts/lists/{id}/contacts accepte limit jusqu'à 500 et modifiedSince.

POST /contacts/lists/{id}/contacts/add (et /remove) accepte emails, ids ou extIds (150 max., au-delà 400 out_of_range) et répond 201 avec le détail :

{ "contacts": { "success": ["jeanne@example.com"], "failure": ["inconnu@example.com"], "total": 2 } }

/remove accepte aussi {"all": true} pour vider la liste ; la réponse porte alors un processId.

Import & export

  • POST /contacts/import : jsonBody ([{"email", "attributes"}]), fileBody (CSV ; ou ,, première ligne = noms d'attributs, colonne EMAIL) ou fileUrl ; listIds ou newList ({"listName", "folderId"}). Options : updateExistingContacts (true par défaut), emptyContactsAttributes (une cellule vide efface l'attribut), emailBlacklist, smsBlacklist, notifyUrl. Réponse 202 {"processId"} ; suivez-la avec GET /processes/{id} (adresses invalides et doublons dans info.import.invalid_emails et info.import.duplicate_email_id, séparés par des virgules).
  • POST /contacts/export : customContactFilter obligatoire, avec actionForContacts (allContacts par défaut, subscribed, unsubscribed, unsubscribedPerList) et listId (exigé pour unsubscribedPerList) ; exportAttributes choisit les colonnes, notifyUrl reçoit le résultat. Réponse 202 {"processId"}. Le processus terminé expose export_url, un lien signé vers le CSV (séparateur ;, colonnes CONTACT_ID, EMAIL puis les attributs).

Double opt-in

POST /contacts/doubleOptinConfirmation attend email, includeListIds, templateId et redirectionUrl (http ou https), plus excludeListIds et attributes en option. Il envoie le modèle templateId avec un lien de confirmation (variable {{ doubleoptin }}, valable 30 jours ; si le modèle ne la contient pas, le lien est ajouté en fin de message). Réponse 201, ou 204 si le contact existe déjà. Le contact n'est créé (ou mis à jour), ajouté à includeListIds et retiré de excludeListIds qu'au clic, puis redirigé vers redirectionUrl.