Webhooks sortants HMAC-SHA256

Vos événements produit, poussés vers vous

Déclarez un endpoint HTTPS et Pimelo y envoie un payload JSON signé à chaque changement produit — sans polling ni comparaison planifiée.

Seules les modifications unitaires déclenchent les webhooks

Les webhooks se déclenchent pour les modifications d'un produit à l'unité depuis l'application, l'API REST ou l'assistant IA. Les opérations en masse — imports CSV/XLSX, éditions groupées, endpoint batch NDJSON, exécutions de règles et synchronisations de connecteurs — ne déclenchent PAS de webhook pour le moment : un import de 50 000 lignes ne peut donc pas saturer votre endpoint.

Après une opération en masse, resynchronisez via l'API : listez les produits filtrés sur updated_at pour récupérer tout ce qui a changé.

Webhooks

Comment ça marche

Vous enregistrez un endpoint et choisissez les événements qui vous intéressent. Quand l'un d'eux survient, Pimelo envoie une requête HTTP POST contenant une enveloppe JSON décrivant ce qui s'est passé — y compris, pour les mises à jour, le diff exact des valeurs par canal et par locale.

Votre endpoint doit être joignable publiquement en HTTPS et répondre avec un statut 2xx. Toute autre réponse est considérée comme un échec et fait l'objet d'une nouvelle tentative.

Événements disponibles

Chaque abonnement écoute un ou plusieurs de ces types d'événements.

product.created
Un produit a été créé
product.updated
Les valeurs ou le statut d'un produit ont changé
product.deleted
Un produit a été supprimé
Payload

Format de la requête

Chaque livraison est un POST avec un corps JSON et quatre en-têtes Pimelo.

En-têtes

Header Description
Pimelo-Event-Id Identifiant unique de l'événement. Utilisez-le comme clé d'idempotence : les nouvelles tentatives et les rejeux manuels réutilisent la même valeur.
Pimelo-Event-Type Le type d'événement, par ex. product.updated. Identique au champ « type » du corps.
Pimelo-Delivery-Attempt Numéro de la tentative pour cette livraison, à partir de 1.
Pimelo-Signature Signature HMAC-SHA256 horodatée du corps de la requête. Voir « Vérifier la signature ».

Exemple : product.updated

{ "id": "evt_3KP7QW2ZR8XN4M", "type": "product.updated", "occurredAt": "2026-07-22T09:15:00+00:00", "organization": "K3M9XQ2P7RTZ8W", "actor": { "type": "user", "uid": "7WQ4MZ2XK9P3TR", "email": "[email protected]" }, "source": "app", "data": { "uid": "P8ZR3WQ7MK2X4N", "sku": "TSHIRT-BLUE-M", "status": "active", "changes": [ { "code": "description", "channelCode": "ecommerce", "localeCode": "fr_FR", "oldValue": "Ancien texte", "newValue": "Nouveau texte" } ] } }

Le tableau « changes » n'est présent que sur product.updated. Un channelCode ou localeCode à null signifie que l'attribut n'est pas scopé par canal ou par locale. Sur product.created et product.deleted, « data » ne contient que l'identité du produit.

Security

Vérifier la signature

Chaque requête est signée avec le secret affiché une seule fois à la création du webhook. Vérifiez-le systématiquement avant de faire confiance à un payload.

# The header carries the signing timestamp and the digest Pimelo-Signature: t=1753142400,v1=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

Extrayez t et v1 de l'en-tête, rejetez la livraison si t sort de votre fenêtre de tolérance (5 minutes est une bonne valeur par défaut), puis recalculez le HMAC-SHA256 sur la chaîne « {t}.{corpsBrut} » avec votre secret de signature et comparez-le à v1 en temps constant.

PHP

function verifyPimeloSignature( string $rawBody, string $header, string $secret, int $toleranceSeconds = 300 ): bool { // "t=1753142400,v1=9f86d081..." parse_str(str_replace(',', '&', $header), $parts); $timestamp = (int) ($parts['t'] ?? 0); $signature = (string) ($parts['v1'] ?? ''); // Reject stale deliveries (replay protection) if (abs(time() - $timestamp) > $toleranceSeconds) { return false; } $expected = hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret); return hash_equals($expected, $signature); }

Node.js

const crypto = require('crypto') function verifyPimeloSignature(rawBody, header, secret, tolerance = 300) { const parts = Object.fromEntries( header.split(',').map((p) => p.split('=')), ) const timestamp = Number(parts.t) const signature = parts.v1 || '' // Reject stale deliveries (replay protection) if (Math.abs(Date.now() / 1000 - timestamp) > tolerance) return false const expected = crypto .createHmac('sha256', secret) .update(timestamp + '.' + rawBody) .digest('hex') return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signature), ) }

Important : calculez la signature sur le corps BRUT de la requête, exactement tel que reçu. Parser le JSON puis le re-sérialiser change les octets et la signature ne correspondra jamais.

Delivery

Garanties de livraison

Ce à quoi vous attendre — et ce pour quoi concevoir votre endpoint.

Ce qui compte comme un succès

Toute réponse 2xx. Tout le reste — y compris les redirections 3xx — est un échec et fait l'objet d'une nouvelle tentative.

Nouvelles tentatives et backoff

Jusqu'à 12 tentatives avec backoff exponentiel et jitter : l'attente double à partir de 10 secondes et est plafonnée à une heure, soit une chaîne complète d'environ 3 h 25 après l'événement. Au-delà, la livraison est marquée en échec — et reste rejouable depuis l'historique des livraisons.

Livraison at-least-once

Une livraison peut arriver plusieurs fois. Dédupliquez sur Pimelo-Event-Id, qui reste stable entre les tentatives et les rejeux manuels.

L'ordre n'est pas garanti

Les événements peuvent arriver dans le désordre. Utilisez le champ « occurredAt » pour ignorer les payloads plus anciens que l'état que vous détenez déjà.

Désactivation automatique

Après 20 livraisons en échec consécutives, l'abonnement est désactivé automatiquement afin qu'un endpoint mort cesse de générer du trafic. Réactivez-le depuis la page de réglages.

Délai d'expiration

Les requêtes expirent au bout de 10 secondes. Accusez réception rapidement et traitez en asynchrone — faites le travail lourd après avoir répondu 2xx.

Setup

Configurer un webhook

Tout se passe dans l'application, dans Réglages → Système → Webhooks.

1

Allez dans Réglages → Système → Webhooks et cliquez sur « Créer un webhook ».

2

Saisissez un libellé et l'URL HTTPS de votre endpoint, puis choisissez les événements à recevoir.

3

Copiez le secret de signature affiché à la création — il n'est montré qu'une seule fois. Conservez-le avec vos autres secrets.

4

Utilisez « Tester » pour envoyer une livraison webhook.ping, puis consultez l'historique des livraisons pour inspecter les réponses et rejouer une livraison en échec.

Prêt à brancher Pimelo sur votre stack ?

Créez votre compte gratuitement et recevez vos premiers événements produit en quelques minutes.