Recevoir les emails entrants par webhook (IMAP vers JSON)

Mis à jour le

Smapiz garde une connexion IMAP ouverte sur chaque boîte. Quand un email arrive, il est analysé puis envoyé en POST à votre URL, en général quelques secondes après sa réception.

Créer l’endpoint

  1. Ouvrez Webhooks puis Ajouter un endpoint.
  2. Saisissez une URL HTTPS accessible publiquement.
  3. Cochez les événements voulus. Pour les emails entrants : message.received.
  4. Laissez Toutes les boîtes ou sélectionnez certaines boîtes.
  5. Enregistrez et copiez le secret (whsec_…) : il sert à vérifier la signature.

Le bouton Envoyer un test envoie un événement de test pour valider votre endpoint.

Les événements

  • message.received : un nouvel email est arrivé.
  • message.sent : un email a été accepté par le serveur SMTP.
  • message.failed : un email n’a pas pu être envoyé après plusieurs tentatives.
  • message.bounced : un retour d’erreur (bounce) a été reçu pour un email envoyé.
  • mailbox.error / mailbox.recovered : une boîte a perdu puis retrouvé sa connexion.

Ce que vous recevez

{
  "id": "evt_...",
  "object": "event",
  "type": "message.received",
  "created_at": "2026-10-12T08:30:00.000Z",
  "data": {
    "message": {
      "id": "msg_...",
      "mailbox_id": "mbx_...",
      "thread_id": "msg_...",
      "from": { "name": "Fournisseur", "address": "[email protected]" },
      "to": [{ "address": "[email protected]" }],
      "subject": "Facture F-2026-118",
      "text": "Veuillez trouver ci-joint…",
      "html": "<p>Veuillez trouver ci-joint…</p>",
      "attachments": [{ "index": 0, "filename": "F-2026-118.pdf", "url": "https://smapiz.com/v1/messages/msg_.../attachments/0" }],
      "is_auto_reply": false
    }
  }
}
  • Les pièces jointes se téléchargent via leur url, avec votre clé API.
  • is_auto_reply signale les réponses automatiques (absence, etc.), pour éviter de leur répondre.
  • Pour ne pas recevoir le texte et le HTML, désactivez Inclure le texte et le HTML dans les payloads et récupérez le message avec GET /v1/messages/{id}.

Vérifier la signature

Chaque requête porte un en-tête Smapiz-Signature: t=…,v1=…. v1 est un HMAC-SHA256 de "<t>.<corps brut>" avec votre secret. Refusez la requête si la signature ne correspond pas ou si t date de plus de 5 minutes.

import crypto from 'node:crypto';

app.post('/hooks/email', express.raw({ type: 'application/json' }), (req, res) => {
  const [t, v1] = req.header('smapiz-signature').split(',').map((p) => p.split('=')[1]);
  const expected = crypto.createHmac('sha256', process.env.SMAPIZ_WEBHOOK_SECRET)
    .update(`${t}.${req.body}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  if (!fresh || v1?.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) {
    return res.sendStatus(400);
  }
  const event = JSON.parse(req.body);
  res.sendStatus(200); // répondez vite, traitez ensuite
});

Calculez la signature sur le corps brut, avant tout parsing JSON.

Erreurs et nouvelles tentatives

  • Toute réponse 2xx est un succès. Sinon, Smapiz réessaie pendant environ 36 heures, à intervalles croissants.
  • Une réponse 410 ou des échecs répétés désactivent l’endpoint.
  • La liste Livraisons récentes montre chaque tentative ; le bouton Renvoyer renvoie une livraison.
  • Régénérer génère un nouveau secret ; l’ancien cesse de fonctionner immédiatement.

Sans serveur public, vous pouvez aussi lire les événements avec GET /v1/events.

Pour répondre à un email reçu, voir Répondre dans le même fil.

Guide suivantRépondre à un email par API dans le même fil