Aller au contenu principal
Cette page vous a-t-elle été utile ?

API Webhook

Ceci est la référence technique du récepteur de webhook entrant de PrimeCal — le point de terminaison qu'un système externe appelle pour déclencher une règle d'automatisation webhook.incoming. Pour une présentation côté produit, voir Webhooks dans le Guide utilisateur.

Les requêtes doivent être signées HMAC — il n'existe pas de mode non signé

Chaque appel à ce point de terminaison est vérifié avec une signature HMAC-SHA256. Il n'y a aucun moyen de désactiver cela par règle, et une requête non signée est catégoriquement rejetée. Prévoyez la signature dès le départ ; un simple POST curl -d '{...}' échouera.

Point de terminaison​

POST https://api.primecal.eu/api/automation/webhook/{token}
GET https://api.primecal.eu/api/automation/webhook/{token}

{token} est unique par règle (webhookToken), disponible dans l'onglet Webhook de la règle dans l'application, et régénérable depuis là.

  • POST — envoyez votre charge utile sous forme de corps JSON (Content-Type: application/json).
  • GET — pour les appelants qui ne peuvent pas envoyer de corps POST (boutons IoT, liens déclenchés par navigateur). Les paramètres de chaîne de requête deviennent alors la charge utile.

Les deux variantes nécessitent la même signature.

Obtenir votre secret de signature​

Chaque règle possède un webhookSecret, généré automatiquement à la création de la règle. L'application web ne l'affiche pas actuellement — le seul moyen de le récupérer ou de le faire tourner est ce point de terminaison :

POST /api/automation/rules/{id}/webhook/rotate-secret

Authentifié en tant que propriétaire de la règle (authentification JWT normale, pas le jeton webhook). Réponse :

{ "webhookSecret": "<nouveau secret hex de 128 caractères>", "graceUntil": "2026-09-26T12:00:00.000Z" }

Appeler ceci fait tourner le secret — l'ancien secret continue de fonctionner jusqu'à graceUntil (1 heure par défaut), puis s'arrête. Il n'existe pas d'appel en lecture seule « afficher le secret actuel » ; si vous avez perdu le secret, la rotation est le seul moyen de récupération.

Signer une requête​

  1. Horodatage — l'heure Unix actuelle en secondes, sous forme de chaîne.
  2. Charge utile signée — "{timestamp}.{rawRequestBody}" (les octets exacts que vous envoyez, pas une version reséréialisée — pour les requêtes GET, utilisez une chaîne vide à la place du corps).
  3. Signature — HMAC-SHA256(webhookSecret, chargeUtileSignée), encodée en hexadécimal.

Envoyez les deux en en-têtes :

En-têteValeur
X-PrimeCal-TimestampL'horodatage Unix (secondes) utilisé ci-dessus
X-PrimeCal-SignatureLa signature hexadécimale, préfixée facultativement par sha256=

(X-Webhook-Signature/X-Webhook-Timestamp et X-Hub-Signature-256 sont également acceptés, pour la compatibilité avec les conventions courantes d'émetteurs de webhooks.)

Exemple (Node.js)​

const crypto = require('crypto');

const secret = 'the webhookSecret from rotate-secret';
const body = JSON.stringify({ event: 'order.completed', data: { order_id: '12345' } });
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${body}`)
.digest('hex');

await fetch('https://api.primecal.eu/api/automation/webhook/YOUR_TOKEN', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-PrimeCal-Timestamp': timestamp,
'X-PrimeCal-Signature': signature,
},
body,
});

Exemple (curl, précalculé)​

SECRET="the webhookSecret from rotate-secret"
BODY='{"event":"order.completed","data":{"order_id":"12345"}}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')

curl -X POST "https://api.primecal.eu/api/automation/webhook/YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "X-PrimeCal-Timestamp: $TS" \
-H "X-PrimeCal-Signature: $SIG" \
-d "$BODY"

Tolérance d'horodatage et protection contre le rejeu​

  • L'horodatage doit être à moins de 5 minutes de l'horloge du serveur (WEBHOOK_TIMESTAMP_TOLERANCE_SECONDS, 300 par défaut). En dehors de cette fenêtre, la requête est rejetée — cela signifie aussi que vous ne pouvez pas rejouer une ancienne requête interceptée après la fermeture de la fenêtre.
  • Chaque combinaison (token, signature, timestamp) ne peut être utilisée qu'une seule fois. Une nouvelle tentative identique octet pour octet de la même requête signée est rejetée comme rejeu.

Faire tourner sans interruption​

rotate-secret donne à vos nouvelles requêtes un nouveau secret tandis que l'ancien continue d'être vérifié jusqu'à graceUntil (1 heure par défaut). Mettez à jour le secret stocké dans votre système externe dans cette fenêtre ; il n'y a aucun moyen de la prolonger après coup — faites tourner à nouveau si vous avez besoin de plus de temps.

Limites de débit​

Les appels webhook sont limités en débit par règle : 60 requêtes par fenêtre de 60 secondes par défaut (AUTOMATION_WEBHOOK_MAX_PER_WINDOW / AUTOMATION_WEBHOOK_WINDOW_MS), indépendamment des limites de débit générales de l'API décrites dans Limites de débit de l'API. Le dépassement renvoie une erreur indiquant le délai de nouvelle tentative.

Optionnel : restreindre par IP source​

Une règle peut être configurée avec une liste blanche d'IP (triggerConfig) afin que seules les requêtes provenant d'IP source spécifiques soient acceptées, en plus de la vérification de signature. Cela se configure via l'API Automatisation, non exposé actuellement dans l'interface du constructeur de règles.

Réponses​

StatutSignification
200{ "success": true, "ruleId": <id>, "message": "Webhook processed successfully" }
400Format de signature malformé, ou la règle n'est pas une règle webhook.incoming, ou la règle est désactivée
401Signature manquante/invalide, horodatage hors tolérance, ou requête rejouée
403La règle n'a aucun webhookSecret (ne devrait pas se produire pour une règle créée normalement)
404Le jeton ne correspond à aucune règle
429Limite de débit dépassée

Un 200 signifie que la requête a été acceptée et évaluée — pas que les conditions de la règle correspondaient. Consultez le journal d'audit de la règle (API Automatisation) pour voir si l'action s'est réellement exécutée.