Connecteur Opper / Mahalo

Inklura fournit à Mahalo une API compatible avec les opérations transactionnelles d'Opper Mail : authentification, domaines, modèles, envoi et événements. Mahalo crée l'envoi ; Inklura le remet à son circuit d'envoi ; les retours réels du prestataire SMTP sont transmis à Mahalo au format Opper.

Cette page décrit le connecteur Inklura, son contrat HTTP et sa recette. Elle ne documente pas l'ensemble des fonctionnalités du service Opper Mail.

Note

État au 12 octobre 2026 : préproduction. Un envoi depuis l'interface Mahalo a affiché ENVOYÉ, puis DÉLIVRÉ après un retour réel de Postmark. Les événements d'ouverture, de clic, de rebond et de plainte sont raccordés et couverts par tests ; leur affichage dans Mahalo reste à valider sur des événements réels. Les environnements Mahalo production et recette ne sont pas encore provisionnés pour ce connecteur.

Configuration dans Mahalo

Demandez à Inklura les identifiants du compte pour l'éditeur, le site et l'environnement concernés. La clé est liée à un seul compte Inklura et un seul site ; elle ne donne pas accès aux modèles ou messages d'un autre site.

Paramètre Valeur à renseigner
Protocole du connecteur Opper Mail
URL de base en préproduction https://mahalo-mail.inklura.fr/v1/
Identifiant client / username Identifiant fourni par Inklura
Clé API / password Clé privée fournie séparément par Inklura
Expéditeur Adresse autorisée pour le site Inklura
Référence éditeur ref_editeur du même environnement Mahalo

Conservez le suffixe /v1/. Une clé de l'API compatible Brevo ou un jeton de connexion à la console Inklura ne remplace pas la clé de ce connecteur. Les secrets ne doivent pas apparaître dans une URL, un ticket public ou une capture d'écran.

Après avoir renseigné le compte, lancez le test de connexion Mahalo, vérifiez la liste des domaines et modèles, puis envoyez un e-mail à un contact de test contrôlé. Un test de connexion réussi ne valide pas, à lui seul, le suivi des statuts.

Circulation d'un envoi

sequenceDiagram
    participant M as Mahalo
    participant I as Connecteur Inklura
    participant P as Prestataire SMTP
    participant D as Serveur du destinataire
    M->>I: Token, puis transactional/send
    I->>P: E-mail et métadonnées de corrélation
    P-->>I: Acceptation de l'envoi
    I-->>M: HTTP 200 et messageId
    I->>M: Webhook request
    Note over M: ENVOYÉ
    P->>D: Remise de l'e-mail
    D-->>P: Acceptation ou échec
    P->>I: Retour réel de livraison ou de rebond
    I->>M: Webhook delivered ou bounce
    Note over M: DÉLIVRÉ observé sur livraison réelle

ENVOYÉ indique que le circuit d'envoi a accepté le message et que Mahalo a reçu l'événement request. DÉLIVRÉ indique que le serveur de messagerie du destinataire a accepté le message. Cela ne garantit ni son classement dans la boîte de réception, ni sa lecture. Une ouverture mesurée est un événement distinct.

Contrat HTTP

Les chemins ci-dessous sont relatifs à l'URL de base. Les requêtes et réponses utilisent JSON. Les opérations prises en charge renvoient HTTP 200 en cas de succès.

Méthode Chemin Réponse
POST /token { "token": "…" }
GET /transactional/domains Tableau de domaines autorisés
GET /transactional/templates Tableau des modèles actifs du site
POST /transactional/send { "messageId": "…" }
GET /newsletters/lists Tableau des listes du site, en lecture seule

Les modèles et listes exposent id, name, created_at et updated_at. Les dates sont au format ISO 8601. Les identifiants de modèle sont propres au site : récupérez-les sur cet endpoint, sans réutiliser ceux d'un autre compte.

Obtenir un token

Corps de POST /token :

{
  "username": "CLIENT_INKLURA",
  "password": "CLE_PRIVEE"
}

Le token expire au bout d'une heure. Sa révocation suit celle de la clé sous-jacente : une clé révoquée invalide immédiatement ses tokens. Passez le token dans X-Ownpage-Client-Token pour les autres opérations, et demandez-en un nouveau après expiration.

Exemple avec un fichier d'identifiants privé, dont le contenu correspond au JSON ci-dessus :

OPPER_BASE='https://mahalo-mail.inklura.fr/v1'
curl --fail-with-body --silent --show-error \
  -H 'Content-Type: application/json' \
  --data-binary @opper-credentials.json \
  "$OPPER_BASE/token"

Le point d'entrée dédié accepte également le GET /token avec corps JSON utilisé par le client Mahalo historique. Cette adaptation est limitée à l'opération token ; elle n'autorise pas les corps GET sur les autres opérations. Les réponses du listener dédié annoncent leur Content-Length, pour que le client historique reçoive le JSON sans marqueurs de transfert chunked.

Envoyer du contenu généré par Mahalo

curl --fail-with-body --silent --show-error \
  -H "X-Ownpage-Client-Token: $OPPER_TOKEN" \
  -H 'Content-Type: application/json' \
  --data-binary @opper-message.json \
  "$OPPER_BASE/transactional/send"

Exemple de opper-message.json — adresses et contenu fictifs, à remplacer pour une recette contrôlée :

{
  "sender": { "email": "envoi@example.com", "name": "Mon éditeur" },
  "to": [{ "email": "test@example.net", "name": "Contact de test" }],
  "subject": "Confirmation de votre demande",
  "htmlContent": "<p>Bonjour Jeanne, votre demande est confirmée.</p>",
  "textContent": "Bonjour Jeanne, votre demande est confirmée.",
  "tags": ["recette-mahalo"]
}

Réponse d'exemple :

{ "messageId": "0123456789abcdef01234567" }

Le messageId est une chaîne de 24 caractères hexadécimaux. Mahalo doit conserver cette valeur et la rapprocher de message-id dans les événements. L'identifiant du prestataire SMTP est distinct et ne remplace pas celui du connecteur.

Champs acceptés : subject, sender, to, cc, bcc, replyTo, headers, attachment, htmlContent, textContent, templateId, params et tags. Les champs optionnels à null transmis par Mahalo sont traités comme absents ; les champs inconnus sont refusés. Les destinataires utilisent des tableaux d'objets { "email": "…", "name": "…" } ; name est facultatif. attachment est un tableau d’objets : par exemple [{ "name": "document.pdf", "content": "CONTENU_BASE64" }], ou un objet avec une url autorisée à l’intérieur de ce tableau. Un objet de pièce jointe isolé est refusé.

L'expéditeur doit être celui configuré pour le site ou appartenir à un domaine authentifié de ce site. Les listes de suppression restent appliquées. La restriction temporaire aux seules adresses de test a été levée après la recette de livraison.

Utiliser un modèle Inklura

{
  "templateId": 12,
  "to": [{ "email": "test@example.net" }],
  "params": { "PRENOM": "Jeanne", "REFERENCE": "DEMO-123" },
  "tags": ["recette-mahalo"]
}

12 est un exemple : utilisez un identifiant retourné par /transactional/templates. Le modèle doit être actif et appartenir au site de la clé. Avec templateId, le contenu HTML/texte fourni en parallèle est ignoré au profit du modèle.

Les modèles Inklura utilisent notamment {{ params.PRENOM }}. Le langage de composants newsletter Opper n'est pas émulé. Les marqueurs Mahalo non résolus tels que #PRENOM# dans le sujet ou le contenu sont refusés avant l'envoi : corrigez le modèle ou le contexte de génération.

Événements transmis à Mahalo

Inklura configure une destination par clé du connecteur, avec la référence de l'éditeur correspondant. Ces URL sont des récepteurs de callbacks, pas des URL d'envoi :

Environnement Mahalo Destination des événements
Préproduction https://api-preprod.mahalo-app.io/aboweb/oppermail?ref_editeur=REF
Production, à provisionner https://api.mahalo-app.io/aboweb/oppermail?ref_editeur=REF
Recette, à provisionner https://api-recette.mahalo-app.io/aboweb/oppermail?ref_editeur=REF

REF doit venir de l'environnement cible. La préproduction actuellement validée utilise l'éditeur 2207 ; cette référence ne doit pas être copiée dans un futur environnement sans vérification.

Inklura transmet les événements par HTTP POST, avec Content-Type: application/json; charset=utf-8. Mahalo doit accepter le callback par un code 2xx. Les caractères Unicode peuvent être échappés en \uXXXX dans le JSON ; après décodage JSON, le sujet et les tags conservent leur texte original.

Événement Opper Origine dans ce connecteur Champs complémentaires
request Envoi accepté par le circuit Inklura Aucun champ supplémentaire obligatoire émis
delivered Retour de livraison du prestataire SMTP email
unique_opened / opened Première ouverture / ouverture suivante signalée par le prestataire email, user_agent s'il est disponible
click Clic signalé par le prestataire email, link, user_agent s'il est disponible
soft_bounce / hard_bounce Retour de rebond reconnu email, message s'il est disponible
spam Plainte signalée par le prestataire email, message s'il est disponible
error / blocked / invalid_email Type d'échec reconnu dans un retour du prestataire email, message s'il est disponible

Enveloppe d'exemple pour une livraison ; toutes les valeurs sont fictives :

{
  "event": "delivered",
  "date": "2026-10-12 14:51:10 UTC",
  "ts_epoch": 1791816670000,
  "message-id": "0123456789abcdef01234567",
  "subject": "Confirmation de votre demande",
  "tags": ["recette-mahalo"],
  "email": "test@example.net"
}

date est en UTC et ts_epoch en millisecondes, pas en secondes. Pour un clic, l'enveloppe ajoute par exemple "link": "https://example.com/confirmation". Pour un rebond, elle ajoute le diagnostic dans message. Ne déduisez pas une livraison du seul HTTP 200 de l'API d'envoi.

Fiabilité et corrélation

L'événement request attend environ trois secondes après l'acceptation pour laisser Mahalo enregistrer le journal. Chaque transmission tente jusqu'à quatre requêtes avec délai progressif en cas d'échec. Une coupure du processus peut interrompre ces tentatives de request : ce chemin n'est pas encore une outbox persistante.

Pour les retours Postmark, Inklura vérifie l'authentification du callback, la clé autorisée, le stream SMTP configuré, le message enregistré et son destinataire exact. Les messages étrangers du stream partagé et les fixtures de vérification sont ignorés. L'état natif et l'événement sont enregistrés avant la transmission à Mahalo. Un échec de traitement ou de transmission renvoie 503 à Postmark pour permettre une nouvelle tentative ; un événement déjà transmis est acquitté sans recompter les événements natifs.

Mahalo doit tolérer les doublons : une coupure entre sa réponse et l'enregistrement de l'acquittement côté Inklura peut provoquer une retransmission. La réception des événements peut aussi être décalée ; ne supposez pas un ordre strict d'arrivée.

Le suivi des ouvertures et liens est activé par message Opper. Les paramètres globaux du stream partagé ne sont pas modifiés. Une ouverture dépend du chargement des images et peut provenir d'un proxy ; elle ne constitue pas une preuve certaine de lecture humaine. Les réponses automatiques et types de rebond inconnus ne sont pas transformés en échecs de livraison.

Recette et état de validation

La recette du 12 octobre 2026 a été effectuée depuis l'interface Mahalo préproduction, avec un destinataire de test contrôlé. Le journal a affiché ENVOYÉ à 16:51:09 Europe/Paris, puis DÉLIVRÉ à 16:51:10, après acceptation par le serveur de messagerie du destinataire et réception du callback Postmark.

Vérification État
Connexion Mahalo et réponse token exploitable Vérifié
Envoi depuis Mahalo et statut ENVOYÉ Vérifié de bout en bout
Livraison réelle et statut DÉLIVRÉ Vérifié de bout en bout
Préservation des accents et du sujet Unicode Vérifiée sur un nouvel envoi
Ouvertures, clics, rebonds et plaintes Webhooks configurés ; correspondances et reprises testées ; recette réelle Mahalo à compléter
Suite de tests du connecteur et régressions mail 157 tests réussis
Production et recette À provisionner lorsqu'elles seront disponibles

Pour une nouvelle recette, envoyez à un contact contrôlé depuis Mahalo, conservez le messageId, puis rapprochez le journal Mahalo et les callbacks. Un appel direct de l'API Inklura n'établit pas qu'un journal Mahalo a été créé. Testez ensuite une ouverture et un clic sur un lien de test ; utilisez une procédure contrôlée du prestataire pour les rebonds, sans provoquer de plainte sur un e-mail réel.

Erreurs et dépannage

Résultat ou symptôme Vérification à effectuer
400 JSON, champs autorisés, contenu requis, identifiant de modèle, marqueurs Mahalo non résolus
401 Identifiant client, clé, header token, expiration ou révocation
403 Expéditeur autorisé, domaine authentifié ou restriction de recette encore active sur un autre compte
404 URL de base correcte ou modèle actif dans le bon site
413 Corps HTTP supérieur à 1 Mio, pièces jointes base64 incluses
429 Limite du listener : 120 requêtes par minute ; tenir compte de Retry-After
501 Opération non implémentée par ce connecteur
502 Le circuit d'envoi n'a pas accepté le message ; conserver l'identifiant éventuellement retourné pour le diagnostic
500 Erreur interne à diagnostiquer avec Inklura
HTTP 200, journal encore EN_COURS Vérifier le callback request, le ref_editeur, son environnement et le même message-id
ENVOYÉ sans DÉLIVRÉ Vérifier le retour réel du prestataire et sa corrélation ; ne pas fabriquer de statut
Token reçu mais aucune suite d'appel Mahalo Vérifier le décodage HTTP et la réponse JSON, pas seulement son code 200

En cas de résultat incertain ou de timeout d'envoi, vérifiez le journal et le circuit natif avant de réexpédier : aucune garantie générale d'envoi « exactement une fois » n'est annoncée par ce connecteur. Pour un incident, fournissez à Inklura l'environnement, la référence éditeur, l'heure avec fuseau, le messageId et les codes HTTP, sans clé ni token.

Périmètre de compatibilité

Cette intégration couvre les opérations du tableau HTTP et les événements listés ci-dessus. Les écritures newsletter, le remplacement de listes, la programmation d'envois, messageVersions, l'événement unsubscribed, le miroir de message mirror_link et les workflows généraux d'abonnement/réabonnement ne font pas partie du contrat actuellement validé. Les autres endpoints authentifiés renvoient 501 ; un champ d'envoi inconnu renvoie 400.

Références du protocole : envoi transactionnel Opper Mail, événements Opper Mail, retour de livraison Postmark. Pour l'autre protocole disponible chez Inklura, voir API compatible Brevo.