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
- Ouvrez Webhooks puis Ajouter un endpoint.
- Saisissez une URL HTTPS accessible publiquement.
- Cochez les événements voulus. Pour les emails entrants :
message.received. - Laissez Toutes les boîtes ou sélectionnez certaines boîtes.
- 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_replysignale 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
410ou 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.