Aller au contenu

Tape un mot pour chercher dans les pages.

↑↓ Choisir↵ OuvrirÉchap Fermer

API

Créer, lire, modifier, lister et supprimer des contacts par HTTP, avec leur statut, leurs propriétés et la pagination.

Un contact est une personne qui peut recevoir tes e-mails. On le retrouve par son id ou par son adresse e-mail : /contacts/lea@exemple.ch marche aussi bien que /contacts/kn4d7b2x9q1m6v3r8c0w5h2t. Encode les caractères spéciaux de l’adresse, comme + (%2B).

Forme d’un contact

{
"object": "contact",
"id": "kn4d7b2x9q1m6v3r8c0w5h2t",
"email": "lea@exemple.ch",
"first_name": "Léa",
"last_name": "Martin",
"unsubscribed": false,
"status": "subscribed",
"properties": { "entreprise": "Atelier Nord" },
"created_at": "2026-10-11T08:00:00.000Z"
}
ChampTypeDescription
idstringIdentifiant du contact.
emailstringAdresse du contact. Elle identifie le contact et ne se modifie pas.
first_name, last_namestring ou nullPrénom et nom. null quand ils ne sont pas renseignés.
unsubscribedbooleantrue dès que le statut n’est pas subscribed.
statusstringsubscribed, unsubscribed, bounced (adresse qui rebondit) ou complained (signalé comme indésirable).
propertiesobjetLes champs libres du contact, sous forme de texte.
created_atstringDate de création, en ISO 8601.

Les propriétés s’utilisent comme variables dans les modèles : {{entreprise}}. Un contact accepte 50 propriétés au plus, chacune avec un nom de 64 caractères au plus et une valeur de 500 caractères au plus. Les nombres et les booléens sont enregistrés comme texte.

POST /contacts

Ajoute un contact, ou le met à jour.

Si l’adresse existe déjà dans ton espace, le contact est mis à jour au lieu d’être dupliqué : rejouer l’appel est sans risque. Les propriétés envoyées s’ajoutent à celles qui existent.

ChampTypeObligatoireDescription
emailstringOuiAdresse valide, 320 caractères au plus.
first_namestring ou nullNonPrénom, 100 caractères au plus.
last_namestring ou nullNonNom, 100 caractères au plus.
unsubscribedbooleanNontrue pour enregistrer le contact comme désabonné.
propertiesobjetNonChamps libres, texte à texte, 50 au plus.
list_idsstring[]NonListes où ajouter le contact, 20 au plus. Une liste inconnue donne 422.
cURL
curl -X POST https://api.mail.hgdc.ch/contacts \
-H "Authorization: Bearer $AGENTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "lea@exemple.ch",
"first_name": "Léa",
"last_name": "Martin",
"properties": { "entreprise": "Atelier Nord" },
"list_ids": ["jd7q4v2m8x1r5n9c3b6z0h4w"]
}'
Node
const response = await fetch("https://api.mail.hgdc.ch/contacts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AGENTMAIL_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "lea@exemple.ch",
first_name: "Léa",
last_name: "Martin",
properties: { entreprise: "Atelier Nord" },
list_ids: ["jd7q4v2m8x1r5n9c3b6z0h4w"],
}),
})
const contact = await response.json()
SDK
import { Agentmail } from "./agentmail"
const mail = new Agentmail()
const contact = await mail.contacts.create({
email: "lea@exemple.ch",
first_name: "Léa",
last_name: "Martin",
properties: { entreprise: "Atelier Nord" },
list_ids: ["jd7q4v2m8x1r5n9c3b6z0h4w"],
})

Réponse : statut 200.

{
"object": "contact",
"id": "kn4d7b2x9q1m6v3r8c0w5h2t"
}

GET /contacts

Lit une page de contacts, du plus récent au plus ancien.

ChampTypeObligatoireDescription
limitnombreNonContacts par page, de 1 à 100. Défaut : 50. Au-delà de 100, la valeur est ramenée à 100.
afterstringNonCurseur next_cursor de la page précédente. Sans lui, on lit la première page.
cURL
curl "https://api.mail.hgdc.ch/contacts?limit=100" \
-H "Authorization: Bearer $AGENTMAIL_API_KEY"
SDK
import { Agentmail } from "./agentmail"
const mail = new Agentmail()
for await (const contact of mail.contacts.listAll({ limit: 100 })) {
console.log(contact.email)
}

Réponse : statut 200.

{
"object": "list",
"data": [
{
"object": "contact",
"id": "kn4d7b2x9q1m6v3r8c0w5h2t",
"email": "lea@exemple.ch",
"first_name": "Léa",
"last_name": "Martin",
"unsubscribed": false,
"status": "subscribed",
"properties": { "entreprise": "Atelier Nord" },
"created_at": "2026-10-11T08:00:00.000Z"
}
],
"has_more": true,
"next_cursor": "eyJjdXJzb3IiOiJrbjRkN2IyeDlxMW02djNyOGMwdzVoMnQifQ"
}

Pour la page suivante, reprends next_cursor dans after : GET /contacts?limit=100&after=eyJjdXJzb3IiOi…. Sur la dernière page, has_more vaut false et next_cursor vaut null. Le SDK parcourt toutes les pages seul avec listAll.

GET /contacts/:id_ou_adresse

Lit un contact.

ChampTypeObligatoireDescription
id_ou_adressestringOui, dans le cheminIdentifiant du contact, ou son adresse e-mail.
curl https://api.mail.hgdc.ch/contacts/lea%40exemple.ch \
-H "Authorization: Bearer $AGENTMAIL_API_KEY"

Réponse : statut 200, avec la forme d’un contact décrite plus haut. Si le contact n’existe pas dans ton espace, la réponse est un 404 avec name: "not_found".

PATCH /contacts/:id_ou_adresse

Modifie un contact. N’envoie que les champs à changer : un champ absent ne change pas.

ChampTypeObligatoireDescription
id_ou_adressestringOui, dans le cheminIdentifiant du contact, ou son adresse e-mail.
first_namestring ou nullNonNouveau prénom. null l’efface.
last_namestring ou nullNonNouveau nom. null l’efface.
unsubscribedbooleanNontrue désabonne le contact, false le réabonne. Une adresse qui a rebondi ou signalé un e-mail ne se réabonne pas à la main : la réponse est un 422.
propertiesobjetNonChamps à ajouter ou à remplacer. Les autres sont gardés.
list_idsstring[]NonListes où ajouter le contact. Il n’est retiré d’aucune autre liste.

Le champ email n’est pas modifiable : il est ignoré s’il est envoyé.

curl -X PATCH https://api.mail.hgdc.ch/contacts/lea%40exemple.ch \
-H "Authorization: Bearer $AGENTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "properties": { "ville": "Lausanne" }, "unsubscribed": false }'

Réponse : statut 200, avec { "object": "contact", "id": "…" }.

DELETE /contacts/:id_ou_adresse

Supprime un contact de ton espace.

curl -X DELETE https://api.mail.hgdc.ch/contacts/lea%40exemple.ch \
-H "Authorization: Bearer $AGENTMAIL_API_KEY"

Réponse : statut 200.

{
"object": "contact",
"id": "kn4d7b2x9q1m6v3r8c0w5h2t",
"deleted": true
}

Supprimer un contact déjà supprimé renvoie un 404 avec name: "not_found".

Si ça ne marche pas

  • 404 not_found sur un contact qui existe : l’adresse n’a pas été encodée. Un + doit devenir %2B, un @ peut rester tel quel ou devenir %40.
  • 422 au réabonnement : l’adresse a rebondi ou été signalée. Elle ne peut pas être réabonnée à la main.
  • Une propriété n’apparaît pas dans un modèle : son nom doit correspondre exactement à la variable, en minuscules. Voir Variables.