POST /api/v1/lists/{listId}/contacts
Ajoute un contact à une liste, ou complète celui qui s'y trouve déjà — l'adresse e-mail est la clé, au sein de cette liste. C'est l'endpoint qu'appelle un tunnel ou un lead magnet : contrairement à l'import en masse, il déclenche des effets de bord, si bien qu'un événement d'inscription est émis et qu'un e-mail de confirmation double opt-in part quand l'organisation en exige un.
Autorisation
| Rôle dans l'organisation | Cet endpoint |
|---|---|
OWNER | Autorisé |
ADMIN | Autorisé |
MEMBER | Refusé — 403 |
Paramètres de chemin
| Paramètre | Type | Description |
|---|---|---|
listId | string | Obligatoire. La liste que rejoint le contact. Un contact appartient à une seule liste |
Corps de la requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
email | string | oui | La clé de l'ajout-ou-mise-à-jour, avec la liste. Doit être une adresse valide |
firstName | string | non | Jusqu'à 100 caractères |
tags | string[] | non | Noms de tags, de 1 à 50 caractères chacun. Créés dans l'organisation s'ils n'existent pas encore |
doubleOptIn | boolean | non | Champ hérité, accepté mais ignoré. Seul le réglage d'inscription de l'organisation décide si une confirmation est requise |
json
{
"email": "ada@example.com",
"firstName": "Ada",
"tags": ["vip", "webinar-march"]
}Exemple
bash
curl -X POST -H "x-api-key: $AGENTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "ada@example.com", "firstName": "Ada", "tags": ["vip"]}' \
"https://www.agentsmail.io/api/v1/lists/$LIST_ID/contacts"Réponse
200 OK— le contact, créé ou complété. Pas201: la sémantique est celle d'un ajout-ou-mise-à-jour, et l'appel ne permet pas de savoir lequel des deux a eu lieu.400 Bad Request— adresse invalide, tag de plus de 50 caractères, corps mal formé ;detailsporte les erreurs champ par champ.401 Unauthorized— clé absente ou invalide, ou son propriétaire a quitté l'organisation.403 Forbidden— le propriétaire de la clé estmemberde l'organisation, pasadmin.404 Not Found— liste inexistante, ou elle appartient à une autre organisation. L'API ne confirme jamais qu'un identifiant existe à un appelant qui n'y a pas droit.429 Too Many Requests— plus de 120 requêtes en une minute pour cette clé.
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
success | boolean | Indique si l'opération a réussi |
data.id | string | Identifiant unique du contact |
data.email | string | Son adresse — unique au sein de sa liste |
data.firstName | string | null | Ce que vous savez de la personne |
data.lastName | string | null | Jamais renseigné par cet endpoint ; provient d'un import ou de l'interface |
data.status | string | pending, subscribed, unsubscribed, bounced, complained |
data.listId | string | La liste à laquelle il appartient |
data.list | object | {id, name} de cette liste |
data.tags | array | {id, name} de chaque tag porté après l'appel |
data.createdAt | string | Date de création ISO |
data.updatedAt | string | Date ISO de la dernière modification |
Exemple de réponse
json
{
"success": true,
"data": {
"id": "4d19…",
"email": "ada@example.com",
"firstName": "Ada",
"lastName": null,
"status": "subscribed",
"listId": "0b7c…",
"list": {"id": "0b7c…", "name": "Newsletter"},
"tags": [{"id": "7c2e…", "name": "vip"}],
"createdAt": "2026-08-23T10:22:05.000Z",
"updatedAt": "2026-08-23T10:22:05.000Z"
}
}Remarques
- Un contact existant est complété, jamais réinitialisé. Son
statusn'est pas touché : quelqu'un qui s'est désabonné reste désabonné, quoi que porte cet appel. Remettre un contact ensubscribedest un acte explicite — voir Réabonner un contact. - Seul le réglage de l'organisation décide du statut d'un nouveau contact. Activé :
pendingavec un e-mail de confirmation. Désactivé :subscribedsans e-mail de confirmation, même sidoubleOptIn: trueest fourni. Le booléen hérité est accepté mais ignoré. lastNamen'est pas accepté ici. L'ajout unitaire ne prend quefirstName; un nom complet passe par Importer des contacts en masse ou par l'interface.- Les tags sont ajoutés, jamais remplacés : un contact conserve les étiquettes qu'il portait déjà.
- Une liste supprimée répond
404. Rien ne peut entrer dans une liste que vous avez supprimée — dirigez l'appel vers une liste active, ou créez-en une.