Documentation interactive · Portail développeurs · Spécification OpenAPI · EN · FR · DE · IT · PT · ES

API CRM Mailpro™ v3 : Référence

URL de base : https://api.mailpro.com/v3

L'API CRM Mailpro™ v3 vous permet de gérer par programmation les contacts, les listes, les tags, les champs personnalisés, les modèles d'e-mail et les campagnes — et d'envoyer aussi bien des e-mails marketing en masse que des e-mails transactionnels individuels, ainsi que des SMS.

Authentification

Tous les points de terminaison (sauf POST /token et les points de terminaison OAuth) acceptent trois méthodes d'authentification. Choisissez celle qui correspond à votre stack.

> Les méthodes héritées Bearer JWT et IdClient+ApiKey ne sont pas filtrées par scope — elles conservent > un accès complet à chaque point de terminaison qu'elles pouvaient déjà atteindre. Seuls les jetons d'accès > OAuth 2.0 sont soumis aux vérifications de scope par point de terminaison indiquées sur chaque > opération ci-dessous (un jeton dépourvu du scope reçoit 403 insufficient_scope).

Méthode 1 — OAuth 2.0 (recommandée pour les intégrations)

Mailpro exploite un seul serveur d'autorisation OAuth 2.0 pour toutes ses API, servi sur une surface unique indépendante de la version : https://api.mailpro.com/oauth/. Un seul serveur, un seul jeton — le même jeton d'accès fonctionne sur CRM v3, Email v2 et SMS. Les points de terminaison qu'un jeton peut appeler sont régis par les scopes du jeton, et non par l'URL de base de l'API que vous appelez. Il n'existe pas de point de terminaison OAuth par version (pas de /v3/oauth, /v2/oauth ni /sms/oauth).

Point de terminaisonURL
AuthorizeGET https://api.mailpro.com/oauth/authorize
Token / RefreshPOST https://api.mailpro.com/oauth/token
JWKS (vérifier les signatures)GET https://api.mailpro.com/oauth/.well-known/jwks
DiscoveryGET https://api.mailpro.com/oauth/.well-known/openid-configuration

Émetteur (le claim iss sur chaque jeton) : https://api.mailpro.com/oauth/.

Grants pris en charge

Durées de vie des jetons

JetonTTL
Jeton d'accès (JWT RS256)20 min
Refresh token (glissant, à usage unique)30 jours
Code d'autorisation60 secondes

Authorization Code + PKCE — étape par étape

   GET https://api.mailpro.com/oauth/authorize
     ?response_type=code
     &client_id=YOUR_CLIENT_ID
     &redirect_uri=https://yourapp.example.com/callback
     &scope=contacts:read contacts:write
     &state=RANDOM_CSRF_TOKEN
     &code_challenge=CODE_CHALLENGE
     &code_challenge_method=S256
   POST https://api.mailpro.com/oauth/token
   Content-Type: application/x-www-form-urlencoded

   grant_type=authorization_code&code=AUTH_CODE
   &redirect_uri=https://yourapp.example.com/callback
   &client_id=YOUR_CLIENT_ID&code_verifier=CODE_VERIFIER
   { "access_token": "eyJ…", "token_type": "Bearer",
     "expires_in": 1200, "refresh_token": "…" }

client_credentials

POST https://api.mailpro.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET&scope=contacts:read email:send

Le même jeton d'accès OAuth est aussi accepté par les API Email v2 (api.mailpro.com/v2) et SMS (api.mailpro.com/sms) — authentifiez-vous une seule fois, appelez n'importe quelle API. Catalogue complet des scopes : voir Scopes OAuth 2.0 ci-dessous.

Tester OAuth 2.0 en quelques minutes — démarrage rapide

Le moyen le plus rapide d'essayer OAuth est le grant client_credentials (serveur à serveur, sans navigateur, sans utilisateur). Vous avez besoin d'une paire client_id / client_secret (demandez-la à votre contact Mailpro, ou créez-en une dans Paramètres → Accès API). Remplacez les valeurs d'exemple ci-dessous — ne validez jamais un véritable secret dans le code source.

1. Obtenir un jeton d'accès

curl -X POST https://api.mailpro.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "scope=contacts:read"
{ "access_token": "eyJhbGciOiJSUzI1Ni…", "token_type": "Bearer",
  "expires_in": 1200 }

2. Appeler un point de terminaison de ressource avec le jeton

curl https://api.mailpro.com/v3/List \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1Ni…"

Le même jeton fonctionne aussi sur Email v2 (…/v2/…) et SMS (…/sms/…) — tant qu'il porte le scope requis par chaque point de terminaison. Un jeton dépourvu du scope requis est rejeté avec 403 insufficient_scope.

« Connect Mailpro » interactif (authorization_code + PKCE) — lorsque vous agissez pour le compte d'un *utilisateur* (Zapier/Make/n8n, applications partenaires) : redirigez l'utilisateur vers GET https://api.mailpro.com/oauth/authorize avec response_type=code, client_id, redirect_uri, scope, state, code_challenge et code_challenge_method=S256 ; l'utilisateur consent ; vous échangez le code retourné sur POST https://api.mailpro.com/oauth/token avec le code_verifier correspondant. Détail complet ci-dessus ; scopes dans Scopes OAuth 2.0 ci-dessous.

> Les jetons sont des JWT RS256 — les jetons d'accès vivent 20 min, les refresh > tokens 30 jours (glissants, à usage unique : chaque rafraîchissement fait tourner le jeton). > Vérifiez les signatures contre le JWKS situé à > https://api.mailpro.com/oauth/.well-known/jwks et validez le scope de > chaque requête contre la matrice de scopes ci-dessous.

Méthode 2 — Bearer JWT (héritée)

Authorization: Bearer <access_token>

Obtenez un jeton via POST /token (voir ci-dessous). Valide 30 jours par défaut ; utilisez grant_type=refresh_token pour le renouveler sans vous réauthentifier. Plus simple à mettre en place, mais lié à un unique identifiant de compte et impossible à cantonner ni à confier à un tiers — privilégiez OAuth 2.0 pour toute intégration installable.

Méthode 3 — IdClient + ApiKey (plus simple)

Envoyez votre identifiant client et votre clé API en tant qu'en-têtes HTTP (recommandé) ou en tant que paramètres de requête :

IdClient: 12345
ApiKey:   a1b2c3d4-e5f6-7890-abcd-ef1234567890

Mêmes identifiants que les API v2 / SMS — copiez-collez depuis Paramètres → Accès API. Aucune étape d'échange de jeton. La forme en en-tête est recommandée car les URL sont journalisées par IIS / Cloudflare / les proxys.

Point de terminaison de jeton (grant password)

POST /token
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=YOUR_USERNAME&password=YOUR_API_KEY

Point de terminaison de jeton (grant client_credentials)

POST /token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=YOUR_CLIENT_ID

> Le jeton émis par POST /v3/token est également valide sur l'API Email v2 > (api.mailpro.com/v2) et sur l'API SMS (api.mailpro.com/sms). Authentifiez-vous > une seule fois, appelez n'importe quelle API.

Scopes OAuth 2.0

Lorsque votre application demande un jeton d'accès OAuth, elle déclare un ensemble de scopes — des permissions qui définissent exactement ce que le jeton peut faire. L'utilisateur voit une description en langage clair de chaque scope demandé sur l'écran de consentement. Les scopes sont séparés par des espaces dans le paramètre scope (scope=contacts:read email:send). Ne demandez que ce dont vous avez besoin.

Les scopes suivent le format <resource>:<action> et sont hiérarchiquement indépendants — contacts:write n'implique pas contacts:read ; demandez les deux si nécessaire.

ScopeAutorise
contacts:readConsulter vos contacts, listes, tags, segments et champs personnalisés.
contacts:writeCréer, modifier et supprimer vos contacts, listes, tags et champs personnalisés.
email:sendEnvoyer des e-mails transactionnels et de campagne en votre nom.
email:readConsulter les statistiques de délivrabilité, ouvertures, clics et historique des rebonds.
email:templates:readConsulter vos modèles d'e-mail (objet, HTML, corps en texte brut).
email:templates:writeCréer, modifier et supprimer vos modèles d'e-mail.
sms:sendEnvoyer des messages SMS transactionnels et de campagne en votre nom.
sms:readConsulter le solde de crédits SMS et l'historique des messages.
sms:contacts:readConsulter votre répertoire SMS.
sms:contacts:writeCréer, modifier et supprimer des entrées dans votre répertoire SMS.
webhooks:manageS'abonner à, modifier et supprimer les points de terminaison webhook de votre compte.
account:readConsulter les crédits, les limites et le statut d'abonnement de votre compte.

Application des scopes par point de terminaison

Les vérifications de scope sont actives et appliquées par point de terminaison pour les jetons émis par OAuth (l'authentification héritée en est exemptée). Chaque opération de cette référence indique son scope requis sous Authorization. Récapitulatif pour la surface CRM v3 :

Points de terminaisonScope requis
GET /Contact/{id}, GET /List, GET /List/{id}, GET /List/{id}/Contact, GET /List/{listId}/Unsubscribers, GET /Tag, GET /Tag/{id}, GET /Tag/{id}/Contact, GET /Segment, vérification d'appartenance à un segmentcontacts:read
POST /Contact, POST /Contact/Multiple, PUT/DELETE /Contact/{id}, ajout/retrait d'un tag ou d'une liste sur un contact, POST/PUT/DELETE /List, POST/PUT/DELETE /Tagcontacts:write

> Les points de terminaison de cette spécification qui ne sont pas listés ci-dessus (par exemple GET /Field, > les campagnes, l'envoi transactionnel, l'envoi SMS, les modèles de message, les informations de compte) > sont accessibles avec tout jeton valide aujourd'hui — ils ne sont pas encore filtrés par scope sur > la surface CRM v3. Les API Email v2 et SMS filtrent en plus leurs propres points de terminaison > d'envoi / modèles / contacts / compte (voir ces spécifications).

Un rejet de scope retourne 403 avec { "error": "insufficient_scope", "required_scope": "…" } (RFC 6750 §3.1).

Format des données

Pagination

Même règle sur les trois API Mailpro (Email v2, CRM v3, SMS) : 5 000 éléments par page, par défaut comme au maximum.

Paramètres inconnus : ils sont ignorés, jamais refusés. Quand une requête porte un paramètre que l'API ne reconnaît pas, la réponse contient X-Ignored-Parameters (les noms) et X-Documentation (un lien vers cette page), pour qu'une faute de frappe ne passe pas inaperçue.

Codes d'erreur métier

Les violations de règles métier retournent un HTTP 406 avec un corps JSON :

{ "Message": "Contact cannot be created. Email cannot be empty." }

Motifs 406 courants :

Codes de statut retournés

CodeSignification
400Requête mal formée (JSON invalide, message dépassant la limite de parts SMS)
401Identifiants manquants, invalides ou expirés
402Crédits insuffisants pour effectuer l'envoi
403Autorisé par vos identifiants, mais refusé — compte bloqué pour l'envoi de SMS
404L'objet référencé n'existe pas (contact, liste, tag, champ, campagne)
406Violation d'une règle métier de contact (voir la liste ci-dessus)
422Entrée rejetée par la validation, ou limite de compte atteinte

> Changement : certains de ces cas renvoyaient auparavant 404. Les crédits > insuffisants renvoient désormais 402, les erreurs de validation et les > limites de compte renvoient 422, et un compte bloqué pour le SMS renvoie > 403. 404 n'est plus utilisé que pour « cet objet n'existe pas », de > manière cohérente avec l'API SMS. Si votre intégration se base sur 404 pour > ces cas, mettez-la à jour avec les codes ci-dessus.

Format des numéros de téléphone

Les numéros de téléphone sont normalisés automatiquement. Vous pouvez les envoyer dans de nombreux formats — les espaces, tirets, points, barres obliques, parenthèses, tirets bas et espaces insécables sont supprimés avant validation. Tout autre caractère (lettres, apostrophes, =, ;, etc.) rend le numéro invalide.

ValideInvalide
+41794849980 — E.164 international0612345678 — format national (0 initial)
0041 79 484 99 80 — préfixe 00 + espaces41'794'849'80 — apostrophes (non supprimées)
+33 6-12-34-56-78 — + avec tiretstel=0041794849980 — caractères supplémentaires
41794849980 — chiffres bruts1234567 — trop court (< 8 chiffres)

Règles :

Spécificités du Contact v3 : le champ phone_number d'un Contact est actuellement limité à 12 chiffres après normalisation (contre 15 pour les points de terminaison SMS autonomes). Les numéros issus de pays comme l'Allemagne (13), le Brésil (13) ou l'Italie mobile (12–13) peuvent être rejetés sur /v3/Contact avec Length exceeded for Phone Number (12). Cette contrainte héritée pourra être assouplie dans une future version.

Limites

RessourceLimite
Tags par compte1 000
Listes par compte1 000
Champs personnalisés par compte50
Requêtes API mensuelles par compte50 000 (5× les crédits e-mail de l'abonnement)

Suivi des envois (e-mails transactionnels)

Chaque e-mail unitaire envoyé (POST /Send/Mail, l'API Email v2, le relais SMTP ou une automation) reçoit un identifiant. Il peut être suivi jusqu'à ce que le serveur du destinataire l'accepte ou le refuse. Les campagnes ne sont pas concernées : utilisez les statistiques.

statusSignificationFinal ?
queuedAccepté, en attente d'expédition.non
scheduledPlanifié pour plus tard (date_planned).non
sentRemis par nos serveurs, pas encore de réponse du serveur du destinataire.non
deliveredAccepté par le serveur du destinataire (diag_code = sa réponse SMTP).oui
bouncedRefusé. bounce_type : hard = adresse invalide ou refus définitif ; soft = refus après nouvelles tentatives (boîte pleine, serveur injoignable…).oui
not_foundIdentifiant inconnu ou qui n'appartient pas à votre compte.oui

Interroger sans boucler

Les statuts sont conservés 365 jours.

Webhooks

Mailpro™ peut notifier votre serveur en temps réel lorsque certains événements surviennent sur votre compte (création d'un contact, e-mail délivré, fin d'une campagne, etc.). À la manière de Stripe — votre URL reçoit un POST signé en HMAC-SHA256 dès que l'événement se déclenche.

Chaque événement envoyé à votre webhook compte pour 1 requête dans votre quota de requêtes API.

Fonctionnement

> ⏱ Délai d'activation — après avoir créé, mis à jour ou supprimé un webhook, le > changement met jusqu'à 10 min à se propager sur l'ensemble des serveurs de l'API > Mailpro. Pendant cette fenêtre, des événements peuvent ne pas encore correspondre à votre nouvel abonnement > (ou continuer à correspondre à un abonnement tout juste supprimé). C'est le temps nécessaire > pour rafraîchir le cache d'abonnements en mémoire sur chaque instance d'API.

Enveloppe de la charge utile

Tous les événements partagent une enveloppe commune :

{
  "id":         "evt_8f3a9b2c4d1e5f6789abcdef01234567",
  "type":       "contact.created",
  "created":    1748194800,
  "apiVersion": "v3",
  "account":    { "id": 12345, "name": "ACME Corp" },
  "data":       { "id": "...", "email": "[email protected]", "...": "..." }
}
ChampFormatDescription
idevt_ + 32 hexID d'événement unique — utilisez-le comme clé d'idempotence de votre côté.
type<domain>.<verb>Type d'événement canonique (par ex. email.delivered, contact.created).
createdSecondes Unix UTCInclus dans la signature HMAC.
apiVersion"v3"API Mailpro qui a publié l'événement.
account.idintVotre ID client Mailpro.
account.namestringLe nom de votre compte (pratique pour le débogage côté client).
dataobjectCharge utile de l'événement — la forme dépend du type (voir catalogue ci-dessous).

Catalogue des événements

ÉvénementDéclencheurForme de data
pingTest via POST /Webhook/{id}/test{ message }
contact.createdPOST /Contact{ id, email, firstName, lastName, createdAt }
contact.updatedPUT /Contact/{id}{ id, email, firstName, lastName, updatedAt, changes }
contact.deletedDELETE /Contact/{id}{ id, email, deletedAt }
list.contact_addedContact ajouté à une liste{ listId, listName, contactId, contactEmail, addedAt }
list.contact_removedContact retiré d'une liste{ listId, listName, contactId, contactEmail, removedAt }
tag.appliedTag appliqué à un contact{ tag, contactId, contactEmail, appliedAt }
tag.removedTag retiré{ tag, contactId, contactEmail, removedAt }
segment.matchedUn contact entre dans un segment{ segmentId, segmentName, contactId, contactEmail, matchedAt }
email.processedEnvoi accepté par le pipeline{ messageId, email, campaignId, processedAt }
email.deliveredUn email unitaire a été accepté par le serveur destinataire — API v2/v3, SMTP ou Automation (pas les campagnes). Émis depuis le flux de livraison PowerMTA.{ messageId, email, idSending, sendingType, diagCode, deliveredAt }
email.openedPixel de tracking déclenché{ messageId, email, campaignId, openedAt, ip, userAgent }
email.clickedClic sur un lien tracké{ messageId, email, campaignId, clickedAt, url, ip, userAgent }
email.bouncedRebond dur ou doux{ messageId, email, campaignId, bouncedAt, bounceType, reason }
email.spam_reportPlainte FBL{ messageId, email, campaignId, reportedAt }
email.unsubscribedClic sur le lien de désinscription{ messageId, email, campaignId, unsubscribedAt }
email.droppedRefusé avant envoi{ messageId, email, campaignId, droppedAt, reason }
campaign.startedDémarrage de la diffusion{ campaignId, name, totalRecipients, startedAt }
campaign.finishedTous les destinataires traités{ campaignId, name, totalSent, totalFailed, finishedAt }
import.startedDémarrage d'une tâche d'import{ importId, fileName, totalRows, startedAt }
import.progressÀ 25/50/75 %{ importId, fileName, processedRows, totalRows, progressPct }
import.completedImport OK{ importId, fileName, totalRows, addedCount, updatedCount, errorCount, completedAt }
import.failedErreur fatale pendant l'import{ importId, fileName, errorMessage, failedAt }

Abonnez-vous à tous les événements de cette API en passant ["*"] dans le tableau events.

Signature HMAC

Chaque POST porte un en-tête X-Mailpro-Signature :

X-Mailpro-Signature: t=1748194800,v1=7f9ac2b6e4d1c8a3...
X-Mailpro-Event-Id:  evt_8f3a9b2c4d1e5f6789abcdef01234567
X-Mailpro-Event-Type: contact.created
X-Mailpro-Attempt:   1

Pour vérifier :

Node.js
const crypto = require('crypto');

function verifyMailproSignature(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));
  if (Math.abs(Date.now() / 1000 - parseInt(parts.t)) > 300) return false;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(parts.t + '.' + rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(parts.v1, 'hex'),
    Buffer.from(expected, 'hex'));
}
PHP
function verifyMailproSignature(string $rawBody, string $header, string $secret): bool {
    parse_str(str_replace(',', '&', $header), $p);
    if (abs(time() - (int)$p['t']) > 300) return false;
    $expected = hash_hmac('sha256', $p['t'] . '.' . $rawBody, $secret);
    return hash_equals($expected, $p['v1']);
}
Python
import hmac, hashlib, time

def verify_mailpro_signature(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split('=') for p in header.split(','))
    t = int(parts['t'])
    if abs(time.time() - t) > 300:
        return False
    expected = hmac.new(
        secret.encode(),
        f"{t}.".encode() + raw_body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, parts['v1'])
C#
using System.Security.Cryptography;
using System.Text;

static bool VerifyMailproSignature(string rawBody, string header, string secret) {
    var parts = header.Split(',')
        .Select(p => p.Split('='))
        .ToDictionary(a => a[0], a => a[1]);
    var t = long.Parse(parts["t"]);
    if (Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t) > 300) return false;
    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
    var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes($"{t}.{rawBody}"));
    var expected = Convert.ToHexString(hash).ToLowerInvariant();
    return CryptographicOperations.FixedTimeEquals(
        Encoding.UTF8.GetBytes(expected),
        Encoding.UTF8.GetBytes(parts["v1"]));
}

Réessais et désactivation automatique

TentativeDélai avant la suivante
1 → 210 secondes
2 → 31 min
3 → 45 min
4 → 530 min
5 → 62 h
6 → 76 h
7abandonné (livraison marquée failed)

Après 10 échecs consécutifs sur le même webhook, il est automatiquement désactivé (isActive: false) et vous recevez un e-mail de notification. Réactivez-le avec PUT /Webhook/{id} une fois votre endpoint corrigé.

Succès = HTTP 2xx

Nous considérons votre webhook comme réussi uniquement si vous retournez un statut compris dans 200–299. Tout 3xx/4xx/5xx ou un timeout (> 10 s) compte comme un échec et déclenche des réessais. Si votre endpoint est définitivement hors service, retournez explicitement 410 Gone — les réessais ont toujours lieu, mais le motif d'échec est plus clair dans votre journal de livraison.

Limites

LimiteValeur
Webhooks par compte20
Événements souscrits par webhook50
Taille maximale de la charge utile256 Ko
Timeout HTTP par tentative10 secondes
Conservation de l'historique de livraison30 jours

Sommaire

Authentication

Obtenir un jeton Bearer JWT pour authentifier toutes les autres requêtes API. Le point d’entrée de jeton accepte plusieurs grant types : password, refresh_token, client_credentials, ainsi que les intégrations tierces (zapier, automateio, microsoft-flow).

POST /token

Obtenir un jeton d’accès

Obtient un jeton Bearer JWT à partir des identifiants client. Transmettez l’access_token renvoyé sous la forme Authorization: Bearer <token> dans toutes les requêtes suivantes.

Grant types pris en charge
Grant typeCas d’usage
passwordIntégration standard — nom d’utilisateur + clé d’API
refresh_tokenRenouveler un jeton d’accès qui expire sans se ré-authentifier
client_credentialsServeur à serveur, avec l’identifiant client uniquement
zapier / automateio / microsoft-flowIntégrations de plateformes tierces
Durée de vie des jetons

Utilisez grant_type=refresh_token pour obtenir un nouveau jeton d’accès sans vous ré-authentifier — votre SDK devrait le faire automatiquement lorsque le jeton d’accès approche de son expiration (stratégie habituelle : rafraîchir lorsqu’il reste moins de 24 h).

Stocker les jetons en toute sécurité

Même avec une durée de vie de 30 jours, quiconque obtient un access_token peut se faire passer pour votre compte jusqu’à son expiration. Stockez les jetons dans un gestionnaire de secrets côté serveur (Vault, AWS Secrets Manager, Azure Key Vault, variables d’environnement sur un hôte durci). N’incorporez jamais un jeton dans :

Si un jeton est divulgué, révoquez-le depuis les paramètres de votre compte Mailpro et demandez-en un nouveau.

Corps de la requête (application/x-www-form-urlencoded)

NomTypeObligatoireDescription
grant_typestring: password, refresh_token, client_credentials, zapier, automateio, microsoft-flowouiGrant type d’authentification
usernamestringVotre nom d’utilisateur Mailpro (e-mail). Obligatoire pour le grant password.
passwordstringVotre clé d’API Mailpro (format GUID). Obligatoire pour le grant password.
refresh_tokenstringRefresh token précédent. Obligatoire pour le grant refresh_token.
client_idstringVotre identifiant client Mailpro (entier). Obligatoire pour le grant client_credentials.

Réponses

CodeDescription
200Jeton émis avec succès
400Identifiants invalides ou grant type non pris en charge

Exemple 200

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 31535999,
  "userName": "12345",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "application": null
}

Exemple 400

{
  "error": "invalid_grant",
  "error_description": "The username or password is incorrect."
}

Account

Récupérer le profil du compte, le solde de crédits et les détails de l’abonnement.

GET /Account/Me

Obtenir les détails du compte

Renvoie les informations de profil et les paramètres du compte Mailpro authentifié.

Réponses

CodeDescription
200Détails du compte renvoyés avec succès
401Jeton invalide ou expiré

GET /Account/Credits

Obtenir le solde de crédits

Renvoie le solde de crédits e-mail et SMS restant pour le compte.

Réponses

CodeDescription
200Solde de crédits renvoyé avec succès
401Jeton invalide ou expiré

Exemple 200

{
  "email_credits": 48500,
  "sms_credits": 1200
}

GET /Account/SubscriptionEndDate

Obtenir la date de fin d’abonnement

Renvoie la date d’expiration de l’abonnement Mailpro en cours.

Réponses

CodeDescription
200Date de fin d’abonnement renvoyée avec succès
401Jeton invalide ou expiré

GET /Account/Limits

Obtenir le quota d’API mensuel

Renvoie le quota mensuel de requêtes API pour le client authentifié.

Calcul du quota : la limite est calibrée à partir des crédits d’abonnement e-mail (typiquement subscription_credits × 5). Pour un forfait de 10 000 e-mails/mois, cela donne un budget de 50 000 requêtes mensuelles. La correspondance exacte est définie par la tâche de facturation lors de la souscription à l’abonnement et réinitialisée à la date anniversaire de l’abonnement (et non au 1er du mois calendaire).

Ce qui consomme des crédits :

Ce qui est GRATUIT (ne consomme pas de crédits) :

Réponses

CodeDescription
200Instantané du quota
401Jeton invalide ou expiré
404Aucun enregistrement de quota trouvé pour ce compte (compte nouvellement créé n’ayant jamais effectué d’appel API ; la ligne sera créée lors de la première requête authentifiée).

Contact

CRUD complet pour les contacts CRM. Les contacts stockent une adresse e-mail, un numéro de téléphone facultatif, les valeurs des champs personnalisés, et appartiennent à une ou plusieurs Listes. Ils peuvent également être étiquetés avec des Tags. Les identifiants de contact sont des UUID.

POST /Contact

Créer un contact

Crée un nouveau contact CRM avec champs personnalisés, affectations à des listes et tags facultatifs.

Obligatoire :

Les numéros de téléphone acceptent les formats +41…, 0041… ou 41… avec ou sans séparateurs (12 chiffres max sur Contact — voir Format des numéros de téléphone dans la description de l’API).

Les champs personnalisés sont identifiés par leur id (issu de GET /Field). Les valeurs sont validées par rapport au type du champ.

Scope OAuth : contacts:write

Corps de la requête (application/json)

NomTypeObligatoireDescription
emailstringouiAdresse e-mail du contact (obligatoire, doit être unique)
phone_numberstringNuméro de téléphone — accepte les formats +41…, 0041… ou 41… avec ou sans séparateurs. Doit commencer par un indicatif pays valide. 12 chiffres maximum sur Contact (voir Format des numéros de téléphone dans la description de l’API pour les règles complètes).
listsarray of ListRefouiListes auxquelles affecter ce contact. Au moins une liste est obligatoire.
tagsarray of TagRefTags à affecter à ce contact (facultatif)
custom_fieldsarray of FieldValueValeurs des champs personnalisés pour ce contact (facultatif)

Exemple

{
  "email": "[email protected]",
  "phone_number": "+41791234567",
  "lists": [
    {
      "id": 101
    }
  ],
  "tags": [
    {
      "id": 5
    }
  ],
  "custom_fields": [
    {
      "id": 1,
      "value": "Alice"
    },
    {
      "id": 2,
      "value": "Dupont"
    }
  ]
}

Réponses

CodeDescription
200Contact créé avec succès
400Format d’e-mail invalide
401Jeton invalide ou expiré
406Violation de règle métier (voir la description pour la liste complète)

Exemple 406

{
  "Message": "Contact cannot be created. A contact already exist with the same Email"
}

POST /Contact/Multiple

Importer des contacts (en masse)

Crée jusqu’à 1 000 contacts en une seule requête pour un import en masse efficace. La réponse inclut la liste des contacts créés avec succès et la liste des erreurs pour les contacts n’ayant pas pu être créés (ex. e-mail en doublon, données invalides).

Remarque : les listes et tags utilisés lors d’imports en masse ne doivent pas être liés à des workflows d’automatisation actifs. Si c’est le cas, l’import entier est rejeté avec un HTTP 406.

Scope OAuth : contacts:write

Corps de la requête (application/json)

Exemple

[
  {
    "email": "[email protected]",
    "lists": [
      {
        "id": 101
      }
    ],
    "custom_fields": [
      {
        "id": 1,
        "value": "Alice"
      }
    ]
  },
  {
    "email": "[email protected]",
    "lists": [
      {
        "id": 101
      }
    ],
    "custom_fields": [
      {
        "id": 1,
        "value": "Bob"
      }
    ]
  }
]

Réponses

CodeDescription
200Import en masse terminé (vérifiez le tableau errors pour les échecs partiels)
400Entrée invalide
401Jeton invalide ou expiré
406Violation de règle métier (ex. conflit d’automatisation, limite de liste atteinte)

Exemple 200

{
  "Added": [
    {
      "Email": "[email protected]",
      "Id": "550e8400-e29b-41d4-a716-446655440000"
    },
    {
      "Email": "[email protected]",
      "Id": "660e8400-e29b-41d4-a716-446655440001"
    }
  ],
  "Errors": []
}

GET /Contact/{id}

Obtenir un contact

Renvoie les détails d’un contact spécifique. Utilisez includeTags=true pour renvoyer également les tags affectés au contact. Utilisez includeLists=true pour renvoyer également les listes auxquelles le contact appartient.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiUUID du contact (issu de POST /Contact ou GET /List/{id}/Contact)
includeTagsquerybooleanDéfinir à true pour inclure les affectations de tags du contact dans la réponse
includeListsquerybooleanDéfinir à true pour inclure les appartenances aux listes du contact dans la réponse

Réponses

CodeDescription
200Contact renvoyé avec succès
401Jeton invalide ou expiré
404Contact introuvable

Exemple 200

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "[email protected]",
  "phone_number": "41791234567",
  "custom_fields": [
    {
      "id": 1,
      "value": "Alice"
    },
    {
      "id": 2,
      "value": "Dupont"
    }
  ],
  "tags": [
    {
      "id": 5
    }
  ],
  "lists": [
    {
      "id": 101
    }
  ]
}

PUT /Contact/{id}

Mettre à jour un contact

Met à jour l’e-mail, le numéro de téléphone, les champs personnalisés, les affectations aux listes et les tags d’un contact. Le corps de la requête remplace les données actuelles du contact — incluez toutes les listes et tous les tags auxquels vous souhaitez que le contact reste affecté.

Obligatoire dans le corps : email et au moins une entrée lists.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiUUID du contact

Corps de la requête (application/json)

NomTypeObligatoireDescription
emailstringouiAdresse e-mail du contact (obligatoire, doit être unique)
phone_numberstringNuméro de téléphone — accepte les formats +41…, 0041… ou 41… avec ou sans séparateurs. Doit commencer par un indicatif pays valide. 12 chiffres maximum sur Contact (voir Format des numéros de téléphone dans la description de l’API pour les règles complètes).
listsarray of ListRefouiListes auxquelles affecter ce contact. Au moins une liste est obligatoire.
tagsarray of TagRefTags à affecter à ce contact (facultatif)
custom_fieldsarray of FieldValueValeurs des champs personnalisés pour ce contact (facultatif)

Réponses

CodeDescription
200Contact mis à jour avec succès
401Jeton invalide ou expiré
404Contact introuvable
422Erreur de validation (format d’e-mail, numéro de téléphone, incohérence de type de valeur de champ)

Exemple 200

{
  "Result": "Successful operation"
}

DELETE /Contact/{id}

Supprimer un contact

Supprime définitivement un contact du CRM.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiUUID du contact

Réponses

CodeDescription
200Contact supprimé avec succès
401Jeton invalide ou expiré
404Contact introuvable

GET /Contact/{id}/Activity

Activité d'un contact sur 90 jours

E-mails reçus, ouverts et cliqués, messagerie préférée et dernières campagnes du contact.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiGUID du contact

Réponses

CodeDescription
200Activité renvoyée
401Jeton invalide ou expiré
404Le contact demandé n'existe pas

Exemple 200

{
  "period_days": 90,
  "email_received": 12,
  "email_opened": 7,
  "email_clicked": 2,
  "favorite_email_client": "Gmail",
  "last_campaigns": [
    {
      "id": 5001,
      "name": "Spring Sale 2026",
      "date": "2026-10-01T09:00:00"
    }
  ]
}

PUT /Contact/{id}/Tag/{tagid}

Ajouter un tag à un contact

Affecte un tag à un contact. Si le tag est déjà affecté, l’opération est sans effet.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiUUID du contact
tagidpathinteger (int64)ouiIdentifiant du tag (issu de GET /Tag)

Réponses

CodeDescription
200Tag affecté avec succès
401Jeton invalide ou expiré
404Contact ou tag introuvable

DELETE /Contact/{id}/Tag/{tagid}

Retirer un tag d’un contact

Supprime l’affectation d’un tag à un contact.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiUUID du contact
tagidpathinteger (int64)ouiIdentifiant du tag

Réponses

CodeDescription
200Tag retiré avec succès
401Jeton invalide ou expiré
404Contact ou tag introuvable

PUT /Contact/{id}/List/{listid}

Ajouter un contact à une liste

Ajoute un contact à une liste spécifique. Renvoie HTTP 404 si le contact s’est précédemment désinscrit de cette liste.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiUUID du contact
listidpathinteger (int64)ouiIdentifiant de la liste (issu de GET /List)

Réponses

CodeDescription
200Contact ajouté à la liste avec succès
401Jeton invalide ou expiré
404Contact ou liste introuvable, ou contact désinscrit de cette liste

DELETE /Contact/{id}/List/{listid}

Retirer un contact d’une liste

Retire un contact d’une liste spécifique. Le contact lui-même n’est pas supprimé.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathstring (uuid)ouiUUID du contact
listidpathinteger (int64)ouiIdentifiant de la liste

Réponses

CodeDescription
200Contact retiré de la liste avec succès
401Jeton invalide ou expiré
404Contact ou liste introuvable

List

Gérer les listes de contacts. Les listes regroupent les contacts en vue des campagnes et de la segmentation. Maximum 1 000 listes par compte (même limite sur les trois API Mailpro et dans l'app). Maximum 1 000 000 de contacts par liste.

GET /List

Lister les listes de contacts

Renvoie toutes les listes de contacts du compte. Filtrez par nom ou par date de création. Triez par ordre alphabétique avec sortByName=true. Incluez le nombre total de contacts par liste avec includeTotalContacts=true.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
namequerystringFiltrer par nom de liste (correspondance partielle)
dateCreationFromquerystring (date-time)Filtrer par date de création (à partir de, ISO 8601)
dateCreationToquerystring (date-time)Filtrer par date de création (jusqu’à, ISO 8601)
numberOfRecordsqueryintegerÉléments par page — 5 000 par défaut et au maximum
pageNumberqueryintegerNuméro de page basé sur 1
sortByNamequerybooleanDéfinir à true pour trier alphabétiquement par nom
includeTotalContactsquerybooleanDéfinir à true pour inclure le décompte total_contacts dans chaque résultat

Réponses

CodeDescription
200Listes renvoyées avec succès
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 101,
    "name": "Newsletter subscribers",
    "total_contacts": 4521,
    "date_creation": "2025-01-15T10:30:00"
  }
]

POST /List

Créer une liste de contacts

Crée une nouvelle liste de contacts. Maximum 1 000 listes par compte.

Scope OAuth : contacts:write

Corps de la requête (application/json)

NomTypeObligatoireDescription
namestringouiNom d’affichage de la liste

Exemple

{
  "name": "Spring Campaign 2026"
}

Réponses

CodeDescription
200Liste créée avec succès
401Jeton invalide ou expiré
406Limite de listes (1 000) atteinte

Exemple 200

{
  "id": 102,
  "name": "Spring Campaign 2026",
  "date_creation": "2026-04-14T12:00:00"
}

GET /List/{id}

Obtenir une liste de contacts

Renvoie les détails d’une liste de contacts spécifique.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant de la liste

Réponses

CodeDescription
200Liste renvoyée avec succès
401Jeton invalide ou expiré
404Liste introuvable

PUT /List/{id}

Mettre à jour une liste de contacts

Renomme une liste de contacts existante.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant de la liste

Corps de la requête (application/json)

NomTypeObligatoireDescription
namestringouiNom d’affichage de la liste

Exemple

{
  "name": "Newsletter subscribers — Europe"
}

Réponses

CodeDescription
200Liste mise à jour avec succès
401Jeton invalide ou expiré
404Liste introuvable

DELETE /List/{id}

Supprimer une liste de contacts

Supprime définitivement une liste de contacts. Les contacts eux-mêmes ne sont pas supprimés — seule leur appartenance à cette liste est retirée. Les listes utilisées par des workflows d’automatisation actifs ne peuvent pas être supprimées.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant de la liste

Réponses

CodeDescription
200Liste supprimée avec succès
401Jeton invalide ou expiré
404Liste introuvable
406La liste est utilisée par un workflow d’automatisation actif

GET /List/{id}/Contact

Lister les contacts d’une liste

Renvoie les contacts appartenant à une liste spécifique. Filtrez par e-mail ou date d’ajout. Incluez les tags et appartenances aux listes via les indicateurs correspondants.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant de la liste
emailquerystringFiltrer par e-mail (correspondance partielle)
numberOfRecordsqueryintegerÉléments par page — 5 000 par défaut et au maximum
pageNumberqueryinteger
sortByEmailquerybooleanTrier alphabétiquement par e-mail
includeTagsquerybooleanInclure les affectations de tags dans les résultats
includeListsquerybooleanInclure les appartenances aux listes dans les résultats

Réponses

CodeDescription
200Contacts renvoyés avec succès
401Jeton invalide ou expiré
404Liste introuvable ou aucun contact ne correspond aux critères

GET /List/{listId}/Unsubscribers

Lister les désinscrits

Renvoie les contacts qui se sont désinscrits d’une liste spécifique.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
listIdpathinteger (int64)ouiIdentifiant de la liste

Réponses

CodeDescription
200Désinscrits renvoyés avec succès
401Jeton invalide ou expiré
404Liste introuvable

Tag

Gérer les tags pour étiqueter et segmenter les contacts. Les tags sont des étiquettes à plat (ex. « VIP », « Churned », « B2B »). Maximum 1 000 tags par compte.

GET /Tag

Lister les tags

Renvoie tous les tags du compte.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
namequerystringFiltrer par nom (correspondance partielle)
numberOfRecordsqueryinteger
pageNumberqueryinteger
sortByNamequeryboolean

Réponses

CodeDescription
200Tags renvoyés avec succès
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 5,
    "name": "VIP customers"
  },
  {
    "id": 6,
    "name": "Newsletter openers"
  }
]

POST /Tag

Créer un tag

Crée un nouveau tag. Maximum 1 000 tags par compte.

Scope OAuth : contacts:write

Corps de la requête (application/json)

NomTypeObligatoireDescription
namestringouiNom d’affichage du tag

Exemple

{
  "name": "VIP customers"
}

Réponses

CodeDescription
200Tag créé avec succès
401Jeton invalide ou expiré
406Limite de tags (1 000) atteinte

GET /Tag/{id}

Obtenir un tag

Renvoie un tag spécifique par son identifiant.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant du tag

Réponses

CodeDescription
200Tag renvoyé avec succès
401Jeton invalide ou expiré
404Tag introuvable

PUT /Tag/{id}

Mettre à jour un tag

Renomme un tag existant.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Corps de la requête (application/json)

NomTypeObligatoireDescription
namestringouiNom d’affichage du tag

Exemple

{
  "name": "VIP customers — updated"
}

Réponses

CodeDescription
200Tag mis à jour avec succès
401Jeton invalide ou expiré
404Tag introuvable

DELETE /Tag/{id}

Supprimer un tag

Supprime définitivement un tag. Le tag est retiré de tous les contacts. Les tags utilisés par des workflows d’automatisation actifs ne peuvent pas être supprimés.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Tag supprimé avec succès
401Jeton invalide ou expiré
404Tag introuvable
406Le tag est utilisé par un workflow d’automatisation actif

GET /Tag/{id}/Contact

Lister les contacts portant un tag

Renvoie les contacts auxquels un tag spécifique a été affecté.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant du tag
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Contacts renvoyés avec succès
401Jeton invalide ou expiré
404Tag introuvable

Field

Gérer les champs personnalisés des contacts. Les champs vous permettent de stocker des données supplémentaires sur chaque contact (ex. prénom, ville, niveau de fidélité). Maximum 50 champs par compte. Types de champs : text, number, date.

GET /Field

Lister les champs personnalisés

Renvoie tous les champs personnalisés de contact définis pour le compte. Utilisez les valeurs id renvoyées lors de la création ou de la mise à jour de contacts.

Paramètres

NomOùTypeObligatoireDescription
namequerystringFiltrer par nom de champ
idFieldTypequeryintegerFiltrer par identifiant de type de champ
numberOfRecordsqueryinteger
pageNumberqueryinteger
sortByNamequeryboolean

Réponses

CodeDescription
200Champs personnalisés renvoyés avec succès
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 1,
    "name": "first_name",
    "personalisation_key": "first_name",
    "field_type": "text"
  },
  {
    "id": 2,
    "name": "last_name",
    "personalisation_key": "last_name",
    "field_type": "text"
  }
]

POST /Field

Créer un champ personnalisé

Crée un nouveau champ personnalisé de contact. Maximum 50 champs par compte. Utilisez l’id renvoyé lors de l’affectation de valeurs aux contacts.

Corps de la requête (application/json)

NomTypeObligatoireDescription
namestringouiNom affiché du champ
id_field_typeintegerouiIdentifiant du type de champ (types disponibles via GET /Field/Types) : - 1 = texte - 2 = nombre entier - 3 = date et heure - 4 = oui / non - 12 = nombre décimal
personalize_keystringouiClé de variable du modèle, pour insérer le champ dans un message
sortintegerOrdre d'affichage (0 à 255). Obligatoire pour modifier un champ (PUT /Field/{id}).

Exemple

{
  "name": "First name",
  "id_field_type": 1,
  "personalize_key": "first_name"
}

Réponses

CodeDescription
200Champ créé avec succès
401Jeton invalide ou expiré
406Limite de champs (50) atteinte

GET /Field/Types

Lister les types de champs

Renvoie les identifiants de types de champs disponibles à utiliser lors de la création d’un champ personnalisé. Types courants : 1 = texte, 2 = nombre, 3 = date.

Réponses

CodeDescription
200Types de champs renvoyés avec succès
401Jeton invalide ou expiré

GET /Field/{id}

Obtenir un champ personnalisé

Renvoie la définition et les métadonnées d’un champ personnalisé spécifique.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant du champ

Réponses

CodeDescription
200Champ renvoyé avec succès
401Jeton invalide ou expiré
404Champ introuvable

PUT /Field/{id}

Mettre à jour un champ personnalisé

Met à jour le nom ou la clé de personnalisation d’un champ personnalisé.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Corps de la requête (application/json)

NomTypeObligatoireDescription
namestringouiNom affiché du champ
id_field_typeintegerouiIdentifiant du type de champ (types disponibles via GET /Field/Types) : - 1 = texte - 2 = nombre entier - 3 = date et heure - 4 = oui / non - 12 = nombre décimal
personalize_keystringouiClé de variable du modèle, pour insérer le champ dans un message
sortintegerOrdre d'affichage (0 à 255). Obligatoire pour modifier un champ (PUT /Field/{id}).

Réponses

CodeDescription
200Champ mis à jour avec succès
401Jeton invalide ou expiré
404Champ introuvable

DELETE /Field/{id}

Supprimer un champ personnalisé

Supprime définitivement un champ personnalisé et retire sa valeur de tous les contacts. Cette action est irréversible.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Champ supprimé avec succès
401Jeton invalide ou expiré
404Champ introuvable

Campaign

Consulter les statistiques de campagne et gérer les campagnes planifiées. Les campagnes peuvent être modifiées ou supprimées jusqu’à 5 minutes avant l’heure d’envoi planifiée.

GET /Campaign

Lister les campagnes

Renvoie une liste paginée des campagnes e-mail du compte.

Paramètres

NomOùTypeObligatoireDescription
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Campagnes renvoyées avec succès
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 8001,
    "title": "Spring Newsletter April 2026",
    "date_planned": "2026-04-20T09:00:01",
    "count_open": 1823,
    "count_sent": 4521,
    "count_click": 342,
    "count_badmail": 12,
    "count_unsubscription": 8,
    "count_clicking_users": 289,
    "count_complaints": 1,
    "spam_trap": 0,
    "deliverability_score": 98
  }
]

GET /Campaign/{id}

Obtenir une campagne

Renvoie la configuration et un résumé des statistiques d’une campagne spécifique.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Campagne renvoyée avec succès
401Jeton invalide ou expiré
404Campagne introuvable

PUT /Campaign/{id}

Mettre à jour une campagne

Met à jour le titre ou la date d’envoi d’une campagne planifiée. Les campagnes ne peuvent être modifiées que jusqu’à 5 minutes avant l’heure d’envoi planifiée.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Corps de la requête (application/json)

NomTypeObligatoireDescription
campaign_titlestringNom d’affichage de la campagne
date_plannedstring (date-time)Heure d’envoi planifiée (ISO 8601). Omettre pour un envoi immédiat.

Réponses

CodeDescription
200Campagne mise à jour avec succès
401Jeton invalide ou expiré
404Campagne introuvable

DELETE /Campaign/{id}

Supprimer une campagne

Annule et supprime définitivement une campagne par son identifiant.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Campagne supprimée avec succès
401Jeton invalide ou expiré
404Campagne introuvable

GET /Campaign/Scheduled

Lister mes campagnes planifiées

Renvoie les campagnes dont la date_planned est dans le futur et qui n’ont pas encore été expédiées. Triées par date_planned croissante.

Paramètres

NomOùTypeObligatoireDescription
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Liste des campagnes planifiées
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 5001,
    "id_client": 12345,
    "subject": "Spring Sale 2026",
    "date_planned": "2026-05-01T09:00:00",
    "title": "Spring Sale",
    "id_campaign": 7001,
    "id_list": 101,
    "id_segment": null,
    "number_email": 1250
  }
]

POST /Campaign/{id}/Cancel

Annuler une campagne planifiée

Annule une campagne planifiée dans le futur. Renvoie 409 Conflict si la campagne a déjà été expédiée ou n’existe pas.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Campagne annulée
401Jeton invalide ou expiré
409Déjà expédiée ou introuvable

Exemple 200

{
  "result": "ok",
  "cancelled": 5001
}

PATCH /Campaign/{id}/Reschedule

Replanifier une campagne planifiée

Met à jour la date d’envoi planifiée d’une campagne planifiée. La nouvelle date doit être dans le futur et dans les 90 jours.

Nom du champ du corps : l’API accepte date_planned (snake_case, principal) ainsi que les alias historiques PlanDate et scheduled_time. Fournissez l’un quelconque d’entre eux — le premier non null est utilisé.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Corps de la requête (application/json)

NomTypeObligatoireDescription
date_plannedstring (date-time)Nom de champ principal.
PlanDatestring (date-time)Alias historique accepté pour compatibilité ascendante.
scheduled_timestring (date-time)Alias historique accepté pour compatibilité ascendante.

Réponses

CodeDescription
200Campagne replanifiée
400Date manquante — fournissez l’un de date_planned / PlanDate / scheduled_time
401Jeton invalide ou expiré
409Déjà expédiée

Exemple 200

{
  "result": "ok",
  "id": 5001,
  "date_planned": "2026-12-31T14:30:00"
}

GET /Campaign/{id}/ByHour

Statistiques par heure

Renvoie la répartition horaire des ouvertures et des clics pour la campagne.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Statistiques horaires renvoyées avec succès
401Jeton invalide ou expiré

GET /Campaign/{id}/ByDay

Statistiques par jour

Renvoie la répartition quotidienne des ouvertures et des clics pour la campagne.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Statistiques quotidiennes renvoyées avec succès
401Jeton invalide ou expiré

GET /Campaign/{id}/Openings

Lister les ouvertures d’e-mail

Renvoie une liste paginée des contacts ayant ouvert l’e-mail de la campagne.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui
emailquerystringFiltrer par e-mail du destinataire
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Liste des ouvertures renvoyée avec succès
401Jeton invalide ou expiré

GET /Campaign/{id}/Clicks

Lister les clics sur les liens

Renvoie une liste paginée des contacts ayant cliqué sur un lien dans la campagne.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui
emailquerystring
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Liste des clics renvoyée avec succès
401Jeton invalide ou expiré

GET /Campaign/{id}/HardBounces

Lister les hard bounces

Renvoie les adresses e-mail ayant fait l’objet d’un hard bounce lors de cette campagne.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui
emailquerystring
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Liste des hard bounces renvoyée avec succès
401Jeton invalide ou expiré

Lister les liens suivis

Renvoie les données de performance des clics pour chaque lien suivi dans la campagne.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui
linkquerystringFiltrer par URL du lien (correspondance partielle)
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Statistiques de liens renvoyées avec succès
401Jeton invalide ou expiré

GET /Campaign/{id}/OS

Statistiques par OS / appareil

Renvoie la répartition des ouvertures et des clics par système d’exploitation et type d’appareil.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Statistiques par OS renvoyées avec succès
401Jeton invalide ou expiré

GET /Campaign/{id}/EmailClients

Statistiques par client de messagerie

Renvoie la répartition des ouvertures par client de messagerie (Gmail, Outlook, Apple Mail…).

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Statistiques par client de messagerie renvoyées avec succès
401Jeton invalide ou expiré

GET /Campaign/{id}/Countries

Statistiques par pays

Renvoie la répartition géographique des ouvertures et des clics.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Statistiques par pays renvoyées avec succès
401Jeton invalide ou expiré

Send

Envoyer des campagnes e-mail en masse (vers des listes de contacts) et des e-mails transactionnels individuels. Les campagnes peuvent être planifiées ou envoyées immédiatement.

POST /Send/Mail

Envoyer un e-mail transactionnel

Envoie un e-mail transactionnel ponctuel à un destinataire unique.

Destinataire : fournissez email (adresse en ligne) OU id_contact (contact CRM) — pas les deux. Utiliser id_contact permet la personnalisation automatique avec les valeurs des champs personnalisés du contact.

Contenu : fournissez body_html (HTML en ligne) OU id_message (modèle enregistré) — pas les deux. Si les deux sont fournis, id_message est prioritaire.

Obligatoire : id_sender_email, subject, et l’un de (email ou id_contact), ainsi que l’un de (body_html ou id_message).

Corps de la requête (application/json)

NomTypeObligatoireDescription
id_sender_emailintegerIdentifiant de l’adresse e-mail expéditrice (issu de GET /SenderEmail). Obligatoire.
emailstringAdresse email du destinataire (en ligne). Fournissez ceci OU id_contact. Si les deux sont fournis, id_contact prévaut. La partie locale (avant le @) accepte les lettres, les chiffres et . _ - + — y compris le sous-adressage RFC 5322 (user+tag@domain, ex. Gmail, Fastmail, Proton). Les autres caractères spéciaux autorisés par la RFC 5322 (ex. ! # $ % & ' * / = ? ^ { | } ~) et les parties locales entre guillemets ne sont pas acceptés.
id_contactstring (uuid)Identifiant du contact CRM destinataire. Fournissez ceci OU email. Utiliser id_contact permet la personnalisation avec les valeurs des champs personnalisés du contact.
subjectstringObjet de l’e-mail (255 caractères max). Obligatoire.
body_htmlstringContenu HTML en ligne. Fournissez ceci OU id_message. Si les deux sont fournis, id_message est prioritaire.
id_messageintegerIdentifiant d’un modèle de message enregistré (issu de GET /Message). Fournissez ceci OU body_html.
reply_tostringAdresse de réponse (par défaut, l’adresse de l’expéditeur)
fieldsarray of FieldValueChamps de personnalisation personnalisés (utilisés uniquement avec un email en ligne, pas avec id_contact)
date_plannedstring (date-time)Planifier l’envoi à une date ultérieure. Omettre pour un envoi immédiat.
attachmentsarray of EmailAttachmentPièces jointes optionnelles (max 5). Chaque élément est un objet avec un filename et un content encodé en Base64. Limites : 10 Mo par fichier et 15 Mo au total, mesurés après décodage Base64. Types acceptés : PDF, Word, Excel, PowerPoint, images (JPG, PNG, GIF, WebP), ZIP, CSV, TXT — les fichiers exécutables et scripts sont refusés. Facturation : l'envoi garde son crédit habituel, plus 1 crédit par 512 Ko de pièces jointes au-delà des 512 premiers Ko (les pièces jointes ≤ 512 Ko n'ajoutent rien).
keep_in_my_filesbooleanfalse (par défaut) : les pièces jointes ne servent qu'à cet envoi — elles sont stockées hors de votre compte, ne comptent pas dans votre quota de stockage et sont supprimées automatiquement après 35 jours. true : les pièces jointes sont aussi conservées dans les fichiers de votre compte (dossier Secure/Files/Sending/api) et comptent dans votre quota de stockage.

Exemple

{
  "id_sender_email": 201,
  "email": "[email protected]",
  "subject": "Your order #12345 has shipped",
  "body_html": "<p>Hello {{first_name}}, your order is on its way!</p>",
  "reply_to": "[email protected]",
  "fields": [
    {
      "id": 1,
      "value": "Alice"
    }
  ],
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content": "JVBERi0xLjQKJVBERi0xLjQK..."
    }
  ]
}

Réponses

CodeDescription
200E-mail envoyé ou planifié avec succès
400Format d’e-mail invalide ou champ obligatoire manquant
401Jeton invalide ou expiré
404Expéditeur, message ou contact introuvable ; ou destinataire désinscrit
422Erreur de validation (objet trop long, corps et message tous les deux vides, etc.)

Exemple 200

{
  "message": "Successful operation",
  "id_single_send": 8001
}

Exemple 404

{
  "Message": "Not enough credit available"
}

GET /Send/{id}/Status

Obtenir le statut de livraison d'un e-mail transactionnel

Renvoie le statut de livraison actuel d'un e-mail transactionnel envoyé via POST /Send/Mail. Transmettez l'id_single_send renvoyé par cet appel.

Valeurs possibles : delivered (accepté par le serveur du destinataire, voir diag_code), bounced (refusé — bounce_type: hard adresse invalide ou refus définitif, soft refus après nouvelles tentatives), sent (remis au serveur de messagerie, pas encore de réponse), scheduled (pas encore envoyé, date_planned dans le futur) et queued (en attente d'expédition). delivered et bounced sont finaux : arrêtez d'interroger. Chaque e-mail a un statut final au plus tard 48 heures après l'envoi ; interrogez toutes les 15 minutes au plus (chaque appel compte dans votre quota API) ou utilisez les webhooks email.delivered / email.bounced. Seul le client qui a envoyé l'e-mail peut lire son statut — tout autre id renvoie 404.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiL'id_single_send renvoyé par POST /Send/Mail.

Réponses

CodeDescription
200Statut de livraison actuel
401Jeton invalide ou expiré
404Aucun envoi transactionnel trouvé avec cet id pour ce client

Exemple 200

{
  "id_single_send": 8001,
  "email": "[email protected]",
  "status": "delivered",
  "date_planned": "2026-04-15T14:30:00",
  "status_date": "2026-04-15T14:30:07",
  "diag_code": "2.0.0 (success)",
  "bounce_type": null
}

POST /Send/Campaign

Envoyer une campagne e-mail

Envoie une campagne e-mail en masse à une ou plusieurs listes de contacts.

Obligatoire :

Segment : filtrez facultativement les destinataires par un segment enregistré (id_segment). Le segment filtre les contacts au sein des listes spécifiées.

Planification : définissez date_planned à une date/heure ISO 8601 future. Les campagnes peuvent être modifiées ou annulées jusqu’à 5 minutes avant l’heure planifiée.

Corps de la requête (application/json)

NomTypeObligatoireDescription
id_messageintegerouiIdentifiant du modèle de message à utiliser (issu de GET /Message)
id_sender_emailintegerouiIdentifiant de l’adresse expéditrice (issu de GET /SenderEmail)
id_email_reply_tointegerIdentifiant de l’adresse expéditrice de réponse (issu de GET /SenderEmail). Doit être l’une des adresses expéditrices de votre compte, sinon la requête est refusée. Par défaut : id_sender_email.
listsarray of ListRefouiListes de contacts cibles (au moins une est obligatoire)
id_segmentintegerFiltrer les destinataires par un segment enregistré (facultatif)
campaign_titlestringouiNom d’affichage de cette campagne (150 caractères max)
date_plannedstring (date-time)Heure d’envoi planifiée (ISO 8601). Omettre pour un envoi immédiat.
id_automationintegerLier cet envoi à un workflow d’automatisation (facultatif)

Exemple

{
  "id_message": 501,
  "id_sender_email": 201,
  "lists": [
    {
      "id": 101
    }
  ],
  "campaign_title": "Spring Newsletter April 2026",
  "date_planned": "2026-04-20T09:00:00"
}

Réponses

CodeDescription
200Campagne planifiée ou envoyée avec succès
401Jeton invalide ou expiré
402Crédits insuffisants
404Message, expéditeur, liste ou segment introuvable ; ou crédits insuffisants
422Titre de campagne vide ou trop long (150 caractères max)

Exemple 200

{
  "Message": "Successful operation. Campaigns can be edited or deleted until 5 minutes prior to send.",
  "IdCampaign": 8001
}

GET /Send

Lister les envois planifiés

Renvoie la liste des campagnes e-mail en attente d’envoi (planifiées, pas encore traitées).

Paramètres

NomOùTypeObligatoireDescription
subjectMessagequerystringFiltrer par objet (correspondance partielle)
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Envois en attente renvoyés avec succès
401Jeton invalide ou expiré

DELETE /Send/{id}

Annuler un envoi planifié

Annule et supprime un envoi d’e-mail planifié qui n’a pas encore été traité. Ne peut pas annuler des envois en cours de traitement.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant d’envoi (issu de GET /Send)

Réponses

CodeDescription
200Envoi planifié annulé avec succès
401Jeton invalide ou expiré
404Envoi planifié introuvable

GET /Send/Mail/Scheduled

Lister les e-mails unitaires programmés

Renvoie les e-mails unitaires envoyés avec POST /Send/Mail et une date future, pas encore partis. Les campagnes sont listées par GET /Campaign/Scheduled.

Scope OAuth : email:send

Réponses

CodeDescription
200E-mails programmés renvoyés
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id_single_send": 880123,
    "email": "[email protected]",
    "subject": "Your invoice",
    "date_planned": "2026-12-01T09:00:00"
  }
]

POST /Send/Mail/{id}/Cancel

Annuler un e-mail unitaire programmé

Annule l'e-mail tant qu'il n'est pas parti.

Scope OAuth : email:send

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiid_single_send renvoyé par POST /Send/Mail

Réponses

CodeDescription
200E-mail annulé
401Jeton invalide ou expiré
409Envoi introuvable, ou déjà parti

Exemple 200

{
  "result": "ok",
  "cancelled": 880123
}

PATCH /Send/Mail/{id}/Reschedule

Reprogrammer un e-mail unitaire programmé

Change la date d'envoi. La nouvelle date doit être future et à moins de 90 jours. POST est aussi accepté.

Scope OAuth : email:send

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiid_single_send renvoyé par POST /Send/Mail

Corps de la requête (application/json)

NomTypeObligatoireDescription
date_plannedstring (date-time)ouiNouvelle date d'envoi (ISO 8601)

Réponses

CodeDescription
200E-mail reprogrammé
400Date manquante
401Jeton invalide ou expiré
409Envoi introuvable, déjà parti, ou date hors limites

Exemple 200

{
  "result": "ok",
  "id": 880123,
  "date_planned": "2026-12-15T09:00:00"
}

Sender Addresses

Gérer les adresses e-mail expéditrices validées. Seules les adresses vérifiées peuvent être utilisées comme From.

GET /SenderEmail

Lister les adresses expéditrices

Renvoie les adresses e-mail expéditrices validées configurées pour le compte.

Paramètres

NomOùTypeObligatoireDescription
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Adresses expéditrices renvoyées avec succès
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 201,
    "email": "[email protected]",
    "sender_name": "Your Company Newsletter",
    "is_validated": true
  }
]

POST /SenderEmail

Ajouter une adresse d'expéditeur

Ajoute l'adresse avec les mêmes contrôles que l'application et lui envoie un e-mail de validation. Elle est utilisable une fois le lien de cet e-mail cliqué. Un compte peut avoir jusqu'à 25 expéditeurs, validés ou en attente.

Scope OAuth : email:templates:write

Corps de la requête (application/json)

NomTypeObligatoireDescription
emailstringouiAdresse de l'expéditeur
sender_namestringouiNom affiché aux destinataires

Réponses

CodeDescription
200Adresse ajoutée. domain_has_mx vaut false quand le domaine n'a pas d'enregistrement MX.
400email ou sender_name manquant
401Jeton invalide ou expiré
422Adresse refusée : invalide, déjà parmi les expéditeurs du compte, domaine de messagerie public, nom interdit, ou limite de 25 atteinte. Le message donne la raison.
503Indisponible pour le moment, réessayez

Exemple 200

{
  "result": "ok",
  "confirmation_sent": true,
  "domain_has_mx": true
}

POST /SenderEmail/{id}/ResendValidation

Renvoyer l'e-mail de validation

Pour une adresse encore en attente de validation.

Scope OAuth : email:templates:write

Paramètres

NomOùTypeObligatoireDescription
idpathintegerouiid_sender_email de GET /SenderEmail

Réponses

CodeDescription
200E-mail renvoyé
401Jeton invalide ou expiré
404Expéditeur introuvable
409Cet expéditeur est déjà validé
503Indisponible pour le moment, réessayez

Exemple 200

{
  "result": "ok",
  "confirmation_sent": true
}

GET /SenderEmail/{id}/Authentication

Contrôler le domaine d'un expéditeur (SPF, DKIM, DMARC, MX)

Contrôle le domaine en direct dans le DNS et renvoie les enregistrements à publier. Lecture seule. Le DKIM s'active dans l'application : dkim_settings_url ouvre le bon écran.

Scope OAuth : email:templates:read

Paramètres

NomOùTypeObligatoireDescription
idpathintegerouiid_sender_email de GET /SenderEmail

Réponses

CodeDescription
200État du domaine. spf.recommended_record est construit à partir de votre enregistrement actuel : publiez-le seulement si spf.change_needed vaut true.
401Jeton invalide ou expiré
404Expéditeur introuvable
503Indisponible pour le moment, réessayez

Exemple 200

{
  "domain": "example.com",
  "spf": {
    "valid": true,
    "record": "v=spf1 include:spf.mailpro.com -all",
    "recommended_record": "v=spf1 include:spf.mailpro.com -all",
    "change_needed": false
  },
  "dkim": {
    "valid": true,
    "records": [
      {
        "host": "key._domainkey.example.com",
        "value": "v=DKIM1;k=rsa;p=MIIBIjANBgkq...",
        "validated": true
      }
    ]
  },
  "dmarc": {
    "valid": true,
    "record": "v=DMARC1; p=quarantine"
  },
  "mx": {
    "valid": true,
    "record": "mail.example.com"
  },
  "dkim_settings_url": "https://app.mailpro.com/dkim/list?d=example.com"
}

History

Parcourir l’historique des envois d’e-mails et de SMS.

GET /History/Email

Lister l’historique des envois d’e-mails

Renvoie l’historique des envois d’e-mails passés pour le compte.

Paramètres

NomOùTypeObligatoireDescription
subjectMessagequerystringFiltrer par objet (correspondance partielle)
idCampaignqueryintegerFiltrer par identifiant de campagne
includeBodyHTMLquerybooleanInclure le corps HTML complet dans la réponse (plus lent)
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Historique des e-mails renvoyé avec succès
401Jeton invalide ou expiré

GET /History/SMS

Lister l’historique des envois de SMS

Renvoie l’historique des envois de SMS passés pour le compte.

Paramètres

NomOùTypeObligatoireDescription
dateSendquerystring (date-time)Filtrer à partir de cette date (ISO 8601)
dateSendEndquerystring (date-time)Filtrer jusqu’à cette date (ISO 8601)
phoneNumberquerystringFiltrer par téléphone du destinataire (partiel)
typequeryintegerFiltre par type de SMS
statusCodequeryintegerFiltre par code de statut DLR
sortByStatusqueryboolean
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Historique des SMS renvoyé avec succès
401Jeton invalide ou expiré

Segment

Gérer les segments dynamiques — des règles de filtrage enregistrées qui sélectionnent automatiquement les contacts en fonction des valeurs de champs, du comportement ou de l’appartenance aux listes.

GET /Segment

Lister les segments

Renvoie tous les segments dynamiques enregistrés pour le compte.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Segments renvoyés avec succès
401Jeton invalide ou expiré

GET /Segment/{id}/Contact

Lister les contacts d'un segment

Avec id_list, renvoie seulement les contacts de cette liste qui entrent dans le segment : ceux que toucherait une campagne liste + segment. Le total est dans l'en-tête X-Total-Count.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiID du segment
id_listqueryinteger (int64)Limiter à cette liste (facultatif)
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Contacts renvoyés
401Jeton invalide ou expiré
404Segment ou liste introuvable

GET /Segment/{id}/Count

Compter les contacts d'un segment

Le nombre seul, pour connaître la taille d'un envoi à l'avance. Avec id_list, compte seulement les contacts de cette liste qui entrent dans le segment.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiID du segment
id_listqueryinteger (int64)Limiter à cette liste (facultatif)

Réponses

CodeDescription
200Nombre de contacts
401Jeton invalide ou expiré
404Segment ou liste introuvable

Exemple 200

{
  "total": 1250
}

GET /Segment/{id}/contact/{contactId}/check

Vérifier si un contact correspond à un segment

Vérifie si un contact spécifique (par GUID) correspond actuellement aux règles d’un segment donné. Utile pour déclencher de la logique d’automatisation à la demande.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiID du segment
contactIdpathstring (uuid)ouiGUID du contact

Réponses

CodeDescription
200Renvoie le résultat de la correspondance
401Jeton invalide ou expiré
404Segment ou contact introuvable

SMS

Envoyer des SMS à des contacts individuels ou à des listes de contacts entières. Utilise le champ phone_number de chaque contact.

POST /Sms/SingleSMS

Envoyer un SMS unique

Envoie un SMS unique vers un numéro de téléphone directement. Utilisez-le pour les messages transactionnels (OTP, confirmations de commande, alertes). Le numéro de téléphone accepte les formats +41…, 0041… ou 41… avec ou sans séparateurs — voir Format des numéros de téléphone dans la description de l’API pour les entrées acceptées / rejetées.

Corps de la requête (application/json)

NomTypeObligatoireDescription
phone_numberstringouiNuméro de téléphone du destinataire — accepte les formats +41…, 0041… ou 41… avec ou sans séparateurs. Voir Format des numéros de téléphone dans la description de l’API.
messagestringouiTexte du SMS (160 caractères max en encodage standard)
date_plannedstring (date-time)Planifier l’envoi. Omettre pour un envoi immédiat.

Exemple

{
  "phone_number": "+41791234567",
  "message": "Your verification code is 9473. Valid for 10 minutes."
}

Réponses

CodeDescription
200SMS envoyé ou planifié avec succès
401Jeton invalide ou expiré
422Format de numéro de téléphone invalide

POST /Sms/Campaign

Envoyer une campagne SMS

Envoie un message SMS au champ phone_number de tous les contacts d’une ou plusieurs listes. Les contacts sans numéro de téléphone sont ignorés.

Corps de la requête (application/json)

NomTypeObligatoireDescription
listsarray of ListRefouiListes de contacts cibles (utilise le champ phone_number de chaque contact)
messagestringouiTexte du SMS
date_plannedstring (date-time)Planifier l’envoi. Omettre pour un envoi immédiat.

Exemple

{
  "lists": [
    {
      "id": 101
    }
  ],
  "message": "Flash sale today — 20% off. Shop at mailpro.com",
  "date_planned": "2026-04-20T10:00:00"
}

Réponses

CodeDescription
200Campagne SMS envoyée ou planifiée avec succès
401Jeton invalide ou expiré

GET /Sms

Lister l’historique des SMS

Renvoie l’historique des envois de SMS (à la fois unitaires et par campagne) pour le compte.

Paramètres

NomOùTypeObligatoireDescription
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Historique des SMS renvoyé avec succès
401Jeton invalide ou expiré

DELETE /Sms/{id}

Annuler un SMS planifié

Annule un envoi de SMS planifié en attente.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiIdentifiant de l’envoi SMS

Réponses

CodeDescription
200SMS planifié annulé avec succès
401Jeton invalide ou expiré
404Envoi SMS introuvable

GET /Sms/Scheduled

Lister les envois de SMS planifiés

Renvoie les envois de SMS avec une date_planned future (pas encore expédiés), triés par date croissante.

Paramètres

NomOùTypeObligatoireDescription
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Envois de SMS planifiés renvoyés avec succès
401Jeton invalide ou expiré

POST /Sms/{id}/Cancel

Annuler un SMS planifié

Annule un envoi de SMS planifié uniquement s’il n’a pas encore été expédié.

Paramètres

NomOùTypeObligatoireDescription
idpathintegerouiIdentifiant de l’envoi SMS

Réponses

CodeDescription
200SMS planifié annulé avec succès
401Jeton invalide ou expiré
409Envoi SMS introuvable, non détenu par le client, ou déjà expédié

PATCH /Sms/{id}/Reschedule

Replanifier un SMS planifié

Met à jour la date d’envoi planifiée d’un SMS planifié. La nouvelle date doit être dans le futur et dans les 90 jours. Échoue si le SMS a déjà été expédié.

Nom du champ du corps : l’API accepte date_planned (snake_case, principal) ainsi que les alias historiques PlanDate et scheduled_time. Fournissez l’un quelconque d’entre eux.

Paramètres

NomOùTypeObligatoireDescription
idpathintegerouiIdentifiant de l’envoi SMS

Corps de la requête (application/json)

NomTypeObligatoireDescription
date_plannedstring (date-time)Nom de champ principal.
PlanDatestring (date-time)Alias historique accepté pour compatibilité ascendante.
scheduled_timestring (date-time)Alias historique accepté pour compatibilité ascendante.

Réponses

CodeDescription
200SMS planifié replanifié avec succès
400Date manquante — fournissez l’un de date_planned / PlanDate / scheduled_time
401Jeton invalide ou expiré
409Replanification échouée (introuvable, déjà expédié ou date hors plage)

Folders

Organiser les modèles de messages dans des dossiers.

GET /FolderList

Lister les dossiers de listes

Renvoie les dossiers utilisés pour organiser les listes de contacts.

Paramètres

NomOùTypeObligatoireDescription
namequerystringFiltrer par nom de dossier (partiel)
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Dossiers de listes renvoyés avec succès
401Jeton invalide ou expiré

GET /FolderList/{id}

Obtenir un dossier de listes unique

Renvoie les détails d’un dossier de listes par son identifiant.

Paramètres

NomOùTypeObligatoireDescription
idpathintegerouiIdentifiant du dossier

Réponses

CodeDescription
200Dossier renvoyé avec succès
401Jeton invalide ou expiré
404Dossier introuvable

GET /FolderMessage

Lister les dossiers de messages

Renvoie les dossiers utilisés pour organiser les modèles de messages e-mail.

Paramètres

NomOùTypeObligatoireDescription
namequerystringFiltrer par nom de dossier
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Dossiers de messages renvoyés avec succès
401Jeton invalide ou expiré

Import

Téléverser un fichier CSV ou XLSX pour importer des contacts dans une liste en masse. Le fichier est mis en file d’attente pour un traitement asynchrone — suivez la complétion via l’import_job_id renvoyé ou via le callback facultatif webhook_url.

POST /Import/Upload

Téléverser un fichier de contacts (CSV / XLSX) pour import en masse

Téléversez un fichier CSV ou XLSX pour importer des contacts dans une liste. Le fichier est stocké et mis en file d’attente pour un traitement asynchrone — le endpoint renvoie immédiatement un import_job_id.

Type de requête : multipart/form-data

Champs de formulaire obligatoires :

Facultatif :

Format de fichier :

Corps de la requête (multipart/form-data)

NomTypeObligatoireDescription
id_listinteger (int64)ouiIdentifiant de la liste de destination
filestring (binary)ouiFichier CSV ou XLSX (UTF-8, 50 Mo max)
json_match_fieldsstringouiCorrespondance JSON entre les colonnes du fichier et les champs du contact
webhook_urlstring (uri)URL de callback invoquée à la fin du traitement

Réponses

CodeDescription
200Fichier accepté et mis en file d’attente
400Aucun fichier téléversé, id_list manquant, ou json_match_fields absent / invalide
401Jeton invalide ou expiré
500Erreur serveur ou de stockage

Exemple 200

{
  "result": "OK",
  "import_job_id": 14,
  "internal_name": "230575-20260420142615-contacts.csv"
}

Webhooks

Abonner votre serveur aux notifications d’événements en temps réel. Mailpro envoie en POST un payload JSON signé HMAC à votre URL dès qu’un événement souscrit se produit. Voir la section « Webhooks » de l’introduction pour le catalogue complet des événements, l’enveloppe du payload, des extraits de vérification de signature et la politique de relance.

GET /Webhook

Lister les webhooks

Renvoie tous les webhooks configurés sur le compte authentifié.

Réponses

CodeDescription
200Tableau de webhooks
401Jeton invalide ou expiré

POST /Webhook

Créer un webhook

Crée une nouvelle souscription webhook. La réponse contient un secret qui est affiché une seule fois — stockez-le immédiatement, côté serveur. Utilisez-le pour vérifier la signature HMAC de chaque payload entrant.

Limites : 20 webhooks max par compte, 50 événements max par webhook.

Corps de la requête (application/json)

NomTypeObligatoireDescription
urlstring (uri)ouiEndpoint HTTPS (HTTP refusé en production)
eventsarray of stringouiListe des types d’événements à souscrire (voir le catalogue ci-dessus). Utilisez ["*"] pour souscrire à tous les événements de cette API.
descriptionstringDescription libre pour votre référence

Exemple

{
  "url": "https://example.com/hooks/mailpro",
  "events": [
    "email.delivered",
    "email.bounced",
    "contact.created"
  ],
  "description": "Intégration Slack"
}

Réponses

CodeDescription
201Webhook créé — secret n’est renvoyé qu’ici
400URL invalide, liste d’événements invalide, ou limite dépassée
401Jeton invalide ou expiré

Exemple 201

{
  "id": 42,
  "url": "https://example.com/hooks/mailpro",
  "events": [
    "email.delivered",
    "email.bounced",
    "contact.created"
  ],
  "description": "Intégration Slack",
  "isActive": true,
  "consecutiveFailures": 0,
  "autoDisabledAt": null,
  "autoDisabledReason": null,
  "createdAt": "2026-05-25T10:00:00Z",
  "updatedAt": "2026-05-25T10:00:00Z",
  "secret": "whsec_AbcD1234EfgH5678IjkL9012MnoP3456QrsT"
}

GET /Webhook/{id}

Obtenir un webhook

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Le webhook
404Webhook introuvable

PUT /Webhook/{id}

Mettre à jour un webhook

Mise à jour partielle — seuls les champs envoyés sont modifiés.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Corps de la requête (application/json)

NomTypeObligatoireDescription
urlstring (uri)
eventsarray of string
descriptionstring
isActivebooleanMettre à true pour réactiver un webhook désactivé automatiquement, une fois votre endpoint corrigé.

Réponses

CodeDescription
200Webhook mis à jour
400Payload invalide
404Webhook introuvable

DELETE /Webhook/{id}

Supprimer un webhook

Supprime définitivement le webhook et tout son historique de livraisons.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
204Supprimé
404Webhook introuvable

POST /Webhook/{id}/test

Envoyer un événement de test

Met en file d’attente un événement ping immédiat (ou n’importe quel autre type d’événement via le champ eventType du corps) vers votre endpoint. Utile pour vérifier l’accessibilité et la vérification de signature avant de s’appuyer sur des événements réels.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Corps de la requête (application/json)

NomTypeObligatoireDescription
eventTypestringRemplacer le type d’événement (doit être souscrit par ce webhook). ping fonctionne toujours.

Exemple

{
  "eventType": "ping"
}

Réponses

CodeDescription
202Événement mis en file d’attente pour expédition
404Webhook introuvable

Exemple 202

{
  "deliveryId": 1234,
  "eventId": "evt_8f3a9b2c4d1e5f6789abcdef01234567",
  "eventType": "ping"
}

POST /Webhook/{id}/rotate-secret

Faire tourner le secret HMAC

Génère un nouveau secret HMAC et invalide immédiatement l’ancien. Le nouveau secret est renvoyé une seule fois dans la réponse — stockez-le. Toute livraison à partir de ce moment sera signée avec le nouveau secret.

Utilisez ceci si vous suspectez que votre secret a été compromis.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui

Réponses

CodeDescription
200Nouveau secret (visible une seule fois)
404Webhook introuvable

Exemple 200

{
  "secret": "whsec_XyzA9876BcdE5432FghI1098JklM7654NopQ"
}

GET /Webhook/{id}/deliveries

Lister les tentatives de livraison

Renvoie l’historique des tentatives d’expédition pour ce webhook (rétention de 30 jours). Utile pour le débogage — quels événements ont été envoyés, codes de statut reçus, nombres de tentatives, messages d’erreur.

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui
limitqueryinteger
cursorqueryinteger (int64)Curseur de pagination (= dernier identifiant de livraison vu). Renvoie les livraisons avec id < cursor.

Réponses

CodeDescription
200Tableau des tentatives de livraison (les plus récentes en premier)
404Webhook introuvable

POST /Webhook/{id}/deliveries/{deliveryId}/replay

Rejouer une livraison

Met en file d’attente une nouvelle tentative de livraison avec le même payload que l’original. Utile pour redéclencher une livraison ayant échoué après avoir corrigé votre endpoint. Une NOUVELLE ligne Webhook_Delivery est créée (l’original est conservé pour audit). Le rejeu suit la politique de relance standard (10 s → 1 min → 5 min → 30 min → 2 h → 6 h → 24 h, puis abandon).

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)oui
deliveryIdpathinteger (int64)oui

Réponses

CodeDescription
202Rejeu mis en file d’attente
404Webhook ou livraison introuvable

Suppression

Bounces et désinscrits du compte : lister, ajouter, retirer.

GET /Suppression/Bounces

Lister les bounces du compte

Les plus récents d'abord. Le total est dans l'en-tête X-Total-Count.

Scope OAuth : email:read

Paramètres

NomOùTypeObligatoireDescription
typequerystring: hard, softhard ou soft
sourcequerystringOrigine du bounce : list, contact, api ou smtp
emailquerystringAdresse exacte
dateFromquerystring (date-time)À partir de cette date
dateToquerystring (date-time)Jusqu'à cette date
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Bounces renvoyés
400type doit valoir hard ou soft
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 5521,
    "source": "contact",
    "type": "hard",
    "email": "[email protected]",
    "date": "2026-10-12T08:30:00",
    "diag_code": "550 5.1.1 User unknown",
    "id_list": 101
  }
]

DELETE /Suppression/Bounces/{id}

Retirer un bounce

source et type sont obligatoires, tels que renvoyés par GET /Suppression/Bounces : un id seul n'est pas unique.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiid du bounce
sourcequerystringouilist, contact, api ou smtp
typequerystring: hard, softouihard ou soft

Réponses

CodeDescription
200Bounce retiré
400source ou type manquant
401Jeton invalide ou expiré
404Bounce introuvable

Exemple 200

{
  "result": "ok",
  "id": 5521,
  "restored": false
}

POST /Suppression/Bounces/{id}/Restore

Remettre en liste un contact en hard bounce

Uniquement pour un hard bounce de source contact.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiid du bounce

Réponses

CodeDescription
200Contact remis en liste
401Jeton invalide ou expiré
404Hard bounce de contact introuvable, ou adresse plus active

Exemple 200

{
  "result": "ok",
  "id": 5521,
  "restored": true
}

GET /Suppression/Unsubscribers

Lister les désinscrits du compte

Les plus récents d'abord. Le total est dans l'en-tête X-Total-Count.

Scope OAuth : contacts:read

Paramètres

NomOùTypeObligatoireDescription
sourcequerystringOrigine de la désinscription : contact, list, smtp, api ou api3
emailquerystringAdresse exacte
dateFromquerystring (date-time)À partir de cette date
dateToquerystring (date-time)Jusqu'à cette date
numberOfRecordsqueryinteger
pageNumberqueryinteger

Réponses

CodeDescription
200Désinscrits renvoyés
401Jeton invalide ou expiré

Exemple 200

[
  {
    "id": 9012,
    "source": "api3",
    "email": "[email protected]",
    "date": "2026-10-20T16:05:00",
    "list_name": null,
    "comment": "Asked by phone"
  }
]

POST /Suppression/Unsubscribers

Ajouter un désinscrit

Sans id_list, l'adresse est désinscrite pour tout le compte. Avec, de cette liste de désinscription seulement.

Scope OAuth : contacts:write

Corps de la requête (application/json)

NomTypeObligatoireDescription
emailstringouiAdresse à désinscrire
commentstringCommentaire libre
id_listinteger (int64)Liste de désinscription du compte (facultatif)

Réponses

CodeDescription
200C'est fait. already_unsubscribed vaut true quand l'adresse l'était déjà.
400Une adresse valide est obligatoire
401Jeton invalide ou expiré
404id_list n'est pas une liste de désinscription de ce compte

Exemple 200

{
  "result": "ok",
  "already_unsubscribed": false
}

DELETE /Suppression/Unsubscribers/{id}

Retirer un désinscrit

source est obligatoire, tel que renvoyé par GET /Suppression/Unsubscribers : un id seul n'est pas unique.

Scope OAuth : contacts:write

Paramètres

NomOùTypeObligatoireDescription
idpathinteger (int64)ouiid du désinscrit
sourcequerystringouicontact, list, smtp, api ou api3

Réponses

CodeDescription
200Désinscrit retiré
400source est obligatoire
401Jeton invalide ou expiré
404Désinscrit introuvable

Exemple 200

{
  "result": "ok",
  "removed": 9012
}