Webhooks

Un webhook envoie à votre serveur les événements de Sculdoc (fin d'un lot, publication d'une version…) par un appel HTTP signé ; cette page explique comment le créer, vérifier sa signature, le tester et suivre ses livraisons.

Deux façons d'être notifié

  • Abonnement de l'organisation : un webhook créé dans la page Webhooks reçoit les événements choisis, pour toute l'organisation.
  • Notification d'un job : un lot soumis avec un callbackUrl notifie cette adresse à sa fin. Ces appels sont signés avec le Secret des notifications de jobs de l'organisation.

Les webhooks sont gérés par les propriétaires et les administrateurs de l'organisation.

Page Webhooks : récepteurs, état, test et secret des notifications de jobs

Créer un webhook

  1. Ouvrez Webhooks, puis cliquez sur Nouveau webhook.
  2. Saisissez l'URL du récepteur : une adresse publique en https.
  3. Cochez les Événements à recevoir (au moins un).
  4. Facultatif : une Description ; laissez Actif coché pour recevoir les événements tout de suite.
  5. Cliquez sur Créer.

Le Secret de signature (whsec_…) s'affiche une seule fois : copiez-le dans la configuration de votre récepteur. En cas de perte, utilisez Nouveau secret.

Événement Envoyé quand
job.completed Un job asynchrone est terminé.
job.failed Un job asynchrone a échoué.
job.lost Un job n'a pas abouti dans les temps.
version.published Une version est publiée.
version.deprecated Une version est dépréciée.

Ce que reçoit votre serveur

Chaque livraison est un POST dont le corps JSON a la forme suivante :

{
	"id": "01JD…",
	"type": "version.published",
	"createdAt": "2026-10-14T09:30:00.000Z",
	"organizationId": "…",
	"data": { }
}

L'en-tête X-Sculdoc-Signature porte la signature : t=<horodatage en secondes>,v1=<signature hexadécimale>.

Vérifier la signature

La signature est un HMAC-SHA256, calculé avec le secret, sur la chaîne <t>.<corps brut>. Votre récepteur doit :

  1. vérifier la signature sur le corps brut, avant tout traitement du JSON, avec une comparaison en temps constant, et refuser un horodatage de plus de 5 minutes ;
  2. répondre vite par un statut 2xx, puis traiter l'événement de son côté ; toute autre réponse est rejouée avec un délai croissant pendant 24 heures ;
  3. dédoublonner sur id : un même événement peut arriver plusieurs fois.

Avec le client TypeScript :

import { SIGNATURE_HEADER, verifyWebhook } from '@supscale/sculdoc-client';

// rawBody: the request body as received, before JSON parsing
const event = await verifyWebhook(secret, req.headers[SIGNATURE_HEADER], rawBody);
if (await alreadySeen(event.id)) return; // a delivery can be replayed

Les clients Java, C# et Python fournissent la même vérification (Webhooks.verify, Webhooks.Verify, verify_webhook). Sans client, en Node :

import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(secret: string, header: string, rawBody: string): boolean {
	const parts = new Map(header.split(',').map((p) => p.split('=') as [string, string]));
	const t = Number(parts.get('t'));
	const v1 = parts.get('v1') ?? '';
	if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
	const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
	return expected.length === v1.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Tester un webhook

Cliquez sur Tester à côté du webhook : Sculdoc envoie un événement ping. Le message Le récepteur a répondu … donne le statut obtenu ; en cas d'échec, Le récepteur n'a pas accepté le test s'affiche avec le détail.

Gérer un webhook

Le menu d'un webhook propose :

  • Livraisons : le journal des envois ;
  • Modifier : URL, événements, description, état ;
  • Nouveau secret : les prochaines livraisons seront signées avec le nouveau secret ; mettez à jour votre récepteur ;
  • Désactiver / Activer : suspendre ou reprendre les envois ;
  • Supprimer : l'adresse ne reçoit plus d'événements et son journal de livraisons est supprimé.

Journal des livraisons et re-livraison

La page Livraisons d'un webhook liste chaque envoi : Date, Événement, Statut (En cours, Livrée, Échec), Réponse (code HTTP du récepteur) et Tentatives. Filtrez par Statut et par Événement.

Pour chaque livraison, vous pouvez consulter le Contenu envoyé et la Réponse du récepteur. Relivrer programme un nouvel envoi du même événement (par exemple après la correction de votre serveur) ; il apparaît marqué Re-livraison. Pensez au dédoublonnage sur id.

Secret des notifications de jobs

Sur la page Webhooks, sous la liste des récepteurs, la section Secret des notifications de jobs : ce secret signe les appels vers le callbackUrl des jobs asynchrones. Afficher le révèle ; Nouveau secret le remplace (les notifications déjà en file seront signées avec le nouveau secret). La vérification se fait exactement comme ci-dessus.