Aller au contenu

Clés API et webhooks

Mail Merge dispose d’une API REST et de webhooks sortants pour les développeurs et les créateurs sans code. Avec une clé API, vos scripts peuvent faire ce que l’application web fait : lire votre compte, lister les modèles et les contacts, envoyer des campagnes et suivre leurs destinataires. Avec un webhook, Mail Merge appelle votre point de terminaison au moment où une campagne se termine ou qu’un destinataire ouvre, clique, répond, rebondit ou se désabonne, de sorte qu’un CRM, une feuille de calcul ou un canal Slack reste synchronisé sans interrogation.

Les deux se trouvent sous Paramètres → Développeurs dans l’application web et font partie du plan Professionnel (voir Tarification). Si vous préférez parler à Mail Merge à partir d’un assistant IA plutôt que d’écrire du code, utilisez le serveur MCP à la place : il expose les mêmes fonctionnalités sous forme d’outils, sur tous les plans.

  1. Ouvrez Paramètres → Développeurs → Clés API et cliquez sur Créer une clé.
  2. Nommez-la d’après l’endroit où elle sera utilisée (Zapier, Synchronisation CRM), pour pouvoir révoquer la bonne plus tard.
  3. Copiez la clé. Elle n’est affichée qu’une fois : Mail Merge ne conserve que son hash. Si vous la perdez, révoquez-la et créez-en une nouvelle.

Vous pouvez avoir jusqu’à 10 clés par compte. La révocation d’une clé fait échouer immédiatement chaque demande effectuée avec elle ; la ligne disparaît de la liste.

Envoyez la clé en tant que jeton Bearer à chaque demande, par rapport à l’URL de base affichée sur la carte :

Fenêtre de terminal
curl https://merge.email/api/v1/me \
-H "Authorization: Bearer mm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Une clé agit comme le compte qui l’a créée, exactement comme une session connectée : la même autorisation Google, le même quota quotidien, les mêmes limites de plan. Il n’y a pas d’« utilisateur API » séparé.

L’API est la même surface /v1 que l’application web utilise, donc tout ce que vous pouvez faire sur un écran a un point de terminaison derrière. Ceux que les intégrations utilisent le plus :

AppelCe qu’il fait
GET /v1/meLe compte : plan, quota quotidien (max, utilisé, restant), fuseau horaire, métadonnées de modèle.
GET /v1/templates · GET /v1/templates/{templateId}Vos modèles enregistrés ; le corps se charge par modèle.
GET /v1/contacts · POST /v1/contactsLe carnet de contacts (paginé avec limit / cursor → nextCursor).
POST /v1/campaignsEnvoyer, planifier ou autopilote une campagne à partir d’une feuille Google Sheets. Le corps est le même que celui que le générateur de campagne publie : la feuille, la colonne des destinataires, l’objet et le corps avec {{merge tags}}, et les options d’envoi.
GET /v1/campaigns · GET /v1/campaigns/{campaignId}/recipientsVos campagnes et le statut de chaque destinataire (envoyé, lu, cliqué, répondu, rejeté, désabonné).
POST /v1/campaigns/{campaignId}/statusMettre en pause, reprendre ou arrêter une campagne en cours.
POST /v1/recipients/verifyLe vérificateur d’email.

Les corps de demande et de réponse sont en JSON. La surface typée complète est générée à partir du serveur en tant que document OpenAPI ; contactez-nous si vous avez besoin du schéma pour un générateur de client.

Les défaillances sont des statuts HTTP réels avec une enveloppe :

{ "error": { "code": "professional_plan_required", "message": "L'accès à l'API est une fonctionnalité du plan Professionnel" } }
StatutcodeSignification
401Clé inconnue ou révoquée, ou l’accès Google du compte doit être reconnecté.
403professional_plan_requiredLe compte de la clé n’est plus sur le plan Professionnel. Les clés ne sont pas supprimées lors d’une rétrogradation ; elles fonctionnent à nouveau quand le plan le fait.
429rate_limitedPlus de 600 demandes par minute sur une clé. Attendez une minute et réessayez.
400 / 404 / 409bad_request, not_found, conflict, …La demande elle-même, avec un message indiquant ce qu’il faut corriger.

La limite de débit est comptée par clé sur chaque instance de serveur API, donc le plafond effectif est « environ 600 par minute » : ne concevez pas autour de l’atteinte.

  1. Ouvrez Paramètres → Développeurs → Webhooks et cliquez sur Ajouter un webhook.
  2. Entrez une URL HTTPS (le http:// simple est refusé) et cochez les événements qu’il doit recevoir.
  3. Cliquez sur Envoyer un test sur la nouvelle ligne : Mail Merge publie un ping et le toast vous indique comment votre point de terminaison a répondu.

Chaque point de terminaison obtient son propre secret de signature (whsec_…), affiché sur la ligne avec un bouton de copie. Vous pouvez avoir jusqu’à 5 points de terminaison par compte.

ÉvénementQuanddata
campaign.completedLe dernier email d’une campagne a été traité.campaignId, name, status: "completed", sentCount, campaignSize
campaign.paused · campaign.resumed · campaign.stoppedVous avez mis en pause, repris ou arrêté une campagne.campaignId, name, status (paused / active / stopped), sentCount
email.openedUn destinataire a ouvert un email, première fois seulement par campagne.campaignId, recipient, at
email.clickedUn destinataire a cliqué sur un lien suivi, à chaque clic.campaignId, recipient, at, url
email.repliedUne réponse a été détectée sur un fil envoyé.campaignId, recipient, at
email.bouncedUn rebond a été détecté.campaignId, recipient, at
recipient.unsubscribedUn destinataire a utilisé le lien de désabonnement, première fois seulement par campagne.campaignId, recipient, at, method

Les ouvertures et les clics nécessitent que le suivi soit activé pour la campagne ; les réponses et les rebonds proviennent de l’analyse des réponses qui suit chaque campagne envoyée.

Mail Merge envoie un POST par événement par point de terminaison abonné, avec un corps JSON :

{
"id": "6f1c2d3e-…",
"event": "email.opened",
"createdAt": "2026-10-15T14:03:21.512Z",
"data": { "campaignId": "…", "recipient": "ada@example.com", "at": "2026-10-15T14:03:21.498Z" }
}

et trois en-têtes :

En-têteValeur
X-MailMerge-EventLe nom de l’événement, identique à event dans le corps.
X-MailMerge-DeliveryL’id de livraison, identique à id. Utilisez-le pour ignorer un doublon.
X-MailMerge-Signaturesha256= suivi du HMAC-SHA256 hexadécimal du corps brut, clé avec le secret du point de terminaison.

Répondez avec n’importe quel 2xx dans les 5 secondes. En cas d’erreur réseau ou d’un 5xx, Mail Merge réessaie une fois, après 2 secondes ; un 4xx est pris comme votre verdict et n’est pas réessayé. Le même id de livraison est envoyé lors de la nouvelle tentative. Après 20 livraisons échouées d’affilée, le point de terminaison est désactivé et la ligne l’indique : corrigez le point de terminaison, puis supprimez-le et ajoutez-le à nouveau. Toute livraison réussie réinitialise le compteur.

Les événements sont livrés au moins une fois et dans aucun ordre garanti. Les ouvertures en particulier arrivent par rafales (chaque client de messagerie qui rend le pixel de suivi), donc rendez votre gestionnaire idempotent sur X-MailMerge-Delivery ou sur (event, campaignId, recipient).

Vérifiez toujours avant de faire confiance à une charge utile. Calculez le HMAC sur le corps de demande brut (les octets exacts, avant toute analyse JSON) et comparez-le en temps constant :

// Node.js (Express avec `express.raw({ type: "application/json" })`)
import { createHmac, timingSafeEqual } from "node:crypto"
export function verifyMailMergeSignature(rawBody, signatureHeader, secret) {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex")
const a = Buffer.from(expected)
const b = Buffer.from(signatureHeader ?? "")
return a.length === b.length && timingSafeEqual(a, b)
}
app.post("/mailmerge", (req, res) => {
if (!verifyMailMergeSignature(req.body, req.get("X-MailMerge-Signature"), process.env.MAILMERGE_WEBHOOK_SECRET)) {
return res.status(401).end()
}
const payload = JSON.parse(req.body)
// … traiter payload.event / payload.data
res.status(204).end()
})
# Python
import hashlib, hmac
def verify_mailmerge_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header or "")

Aucun code nécessaire : créez un Catch Hook (Zapier Webhooks by Zapier), un Custom webhook (Make) ou un nœud de déclenchement Webhook (n8n), collez l’URL qu’il vous donne en tant que point de terminaison, cochez les événements, et cliquez sur Envoyer un test pour que l’outil puisse échantillonner la charge utile. Les champs data deviennent les variables que vous mappez à l’étape suivante (ajouter une ligne à une feuille, mettre à jour un contact CRM, publier sur Slack). Ces outils ne vérifient pas les signatures par défaut ; l’URL qu’ils vous donnent est imprévisible, ce qui est la protection sur laquelle ils s’appuient.

  • Agents IA (MCP), si un assistant doit piloter Mail Merge pour vous au lieu d’un script.
  • Campagnes, pour comprendre ce que les statuts dans le point de terminaison des destinataires signifient.
  • Tarification, pour savoir ce que le plan Professionnel inclut.