Webhooks
Les webhooks vous permettent de recevoir des notifications en temps réel lorsque des événements se produisent dans votre compte LabelGrid. Utilisez les webhooks pour automatiser des workflows et vous intégrer a des systèmes externes.
Pour les développeurs : Vous pouvez également gérer les webhooks de maniere programmatique via l’API. Consultez la documentation de l’API LabelGrid pour les endpoints et exemples.
Comment fonctionnent les webhooks
Section intitulée « Comment fonctionnent les webhooks »- Vous configurez un webhook - Spécifiez une URL et les événements a écouter
- Un événement se produit - Par exemple, une sortie est livrée a un store
- LabelGrid envoie une requête POST - Votre serveur reçoit les données de l’événement
- Votre système les traite - Automatisez des workflows en fonction de l’événement
Accéder aux webhooks
Section intitulée « Accéder aux webhooks »- Cliquez sur votre icône de profil en haut a droite
- Sélectionnez Webhooks dans le menu déroulant
Créer un webhook
Section intitulée « Créer un webhook »- Cliquez sur Create Webhook
- Saisissez un Name pour identifier ce webhook
- Saisissez l’URL ou vous souhaitez recevoir les notifications
- Sélectionnez les Events qui doivent déclencher ce webhook
- Cliquez sur Create
Secret du webhook
Section intitulée « Secret du webhook »Lorsque vous créez un webhook, vous recevez une clé secrete. Utilisez-la pour vérifier que les requêtes entrantes proviennent bien de LabelGrid :
- Stockez le secret de maniere sécurisée
- Vérifiez la signature des requêtes entrantes
- En cas de compromission, régénérez le secret
Événements disponibles
Section intitulée « Événements disponibles »Configurez votre webhook pour écouter ces événements. L’identifiant d’événement est la valeur que vous verrez dans la propriété event du payload et dans le header X-Webhook-Event :
| Identifiant d’événement | Description |
|---|---|
delivery.completed | Declenche lorsqu’une sortie est livrée avec succès a un store |
delivery.failed | Declenche lorsque la livraison a un store echoue |
takedown.completed | Declenche lorsqu’une demande de retrait est terminée |
release.review.status_changed | Declenche lorsque le statut de révision d’une sortie change |
release.preflight.report_ready | Declenche lorsque le rapport Preflight QC d’une sortie en attente est prêt a être récupère |
stream_radar.flag_created | Declenche lorsqu’un signalement Stream Radar est cree, ou qu’un signalement résolu rouvre sur une nouvelle détection |
stream_radar.flag_resolved | Declenche lorsqu’un signalement Stream Radar se résout parce que les détections ont cesse |
release.distributed | Declenche lorsqu’une sortie est distribuée |
payment.statement_ready | Declenche lorsqu’un releve de paiement est prêt a être consulte |
transcode.completed | Declenche lorsque le transcodage audio d’une piste se termine avec succès |
transcode.failed | Declenche lorsque le transcodage d’une piste echoue ou se termine de façon incomplète |
distribution.outlet.status_changed | Declenche a chaque transition de statut de distribution par outlet |
Vous pouvez sélectionner plusieurs événements pour un seul webhook, ou créer des webhooks séparés pour différents types d’événements.
Vous pouvez aussi lire cette liste de maniere programmatique : GET /api/public/webhooks/event-types renvoie chaque événement accompagne d’un schema data décrivant les clés et les types de son payload, afin que les consommateurs a schema strict puissent élargir leur validation entrante a l’avance.
Gérer les webhooks
Section intitulée « Gérer les webhooks »Consulter vos webhooks
Section intitulée « Consulter vos webhooks »La liste des webhooks affiche :
| Colonne | Description |
|---|---|
| Name | Le nom que vous avez attribue au webhook |
| URL | Ou les notifications sont envoyées |
| Events | Nombre d’événements configures |
| Status | Active ou Inactive |
| Success / Fail | Nombre de livraisons réussies et échouées |
| Last Triggered | Dernière activation du webhook |
Modifier un webhook
Section intitulée « Modifier un webhook »- Cliquez sur l’action Edit sur la ligne du webhook
- Modifiez le nom, l’URL ou les événements
- Cliquez sur Save
Activer / Désactiver
Section intitulée « Activer / Désactiver »Basculez le statut actif d’un webhook sans le supprimer :
- Active - Le webhook recevra les notifications
- Inactive - Le webhook est en pause, aucune notification envoyée
Supprimer un webhook
Section intitulée « Supprimer un webhook »- Cliquez sur l’action Delete sur la ligne du webhook
- Confirmez la suppression
Tester les webhooks
Section intitulée « Tester les webhooks »Avant de dépendre d’un webhook en production, testez-le :
- Cliquez sur l’action Test sur votre webhook
- LabelGrid envoie un payload de test a votre URL
- Vérifiez que votre endpoint a bien reçu et traite correctement
Consulter les journaux des webhooks
Section intitulée « Consulter les journaux des webhooks »Surveillez l’activité des webhooks et dépannez les problèmes :
- Cliquez sur l’action View Logs sur un webhook
- Consultez l’historique de toutes les livraisons du webhook
Details des journaux
Section intitulée « Details des journaux »Chaque entrée de journal affiche :
| Champ | Description |
|---|---|
| Event Type | L’événement qui a declenche cette livraison |
| Response Status | Code de statut HTTP de votre serveur |
| Duration | Durée de la requête |
| Attempt | Numéro de la tentative de renvoi |
| Timestamp | Date et heure de la livraison |
Format du payload webhook
Section intitulée « Format du payload webhook »Lorsqu’un événement se produit, LabelGrid envoie une requête POST a votre URL avec un payload JSON :
{ "event": "delivery.completed", "timestamp": "2026-05-05T10:00:00+00:00", "webhook_id": "123", "data": { // Donnees specifiques a l'evenement }}Le champ timestamp utilise le format ISO 8601. webhook_id est l’ID de votre webhook configure (il correspond au header X-Webhook-Id).
Payloads des événements
Section intitulée « Payloads des événements »La structure de l’objet data dépend du type d’event. Tous les types de champs ci-dessous sont des types JSON tels que serialises dans le payload.
delivery.completed
Section intitulée « delivery.completed »Declenche une fois par outlet lorsqu’une livraison de sortie atteint un état de succès terminal.
{ "event": "delivery.completed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "complete" }}| Champ | Type | Description |
|---|---|---|
distro_queue_id | integer | ID interne de la file pour cette tentative de livraison |
release_id | integer | La sortie qui a été livrée |
label_id | integer | Le label propriétaire de la sortie, pour router l’événement sans requête supplémentaire |
release_cat | string | null | Votre référence de catalogue de sortie |
outlet_id | integer | null | L’ID de l’outlet de destination |
outlet_name | string | null | Nom lisible de l’outlet (par exemple, "Spotify") |
status | string | Toujours "complete" pour cet événement |
delivery.failed
Section intitulée « delivery.failed »Declenche une fois par outlet lorsqu’une livraison de sortie atteint un état d’echec terminal. Même payload que delivery.completed plus un champ message.
{ "event": "delivery.failed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "error", "message": "Outlet rejected the delivery: missing ISRC." }}| Champ | Type | Description |
|---|---|---|
status | string | L’un de error, fault, rejected, batch_exception |
message | string | null | Raison de l’echec depuis l’outlet ou le pipeline de distribution |
takedown.completed
Section intitulée « takedown.completed »Declenche une fois par outlet lorsqu’une demande de retrait reussit. Même forme que delivery.completed plus un indicateur takedown: true.
{ "event": "takedown.completed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "complete", "takedown": true }}release.distributed
Section intitulée « release.distributed »Declenche une fois par sortie lorsque la sortie passe a l’état de livraison distributed. Ne se declenche que sur la transition vers distributed, pas sur les enregistrements suivants pendant que la sortie est déjà distribuée.
{ "event": "release.distributed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "release_cat": "ABC123", "release_title": "Summer EP", "delivery_status": "distributed" }}release.review.status_changed
Section intitulée « release.review.status_changed »Declenche chaque fois qu’une sortie passe d’un état de révision a un autre.
{ "event": "release.review.status_changed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "release_cat": "ABC123", "release_title": "Summer EP", "previous_status": "to_review", "new_status": "approved" }}| Champ | Type | Description |
|---|---|---|
previous_status | string | Statut précédent. L’un de draft, to_review, approved, rejected, require_changes, audit |
new_status | string | Nouveau statut. Même ensemble de valeurs |
review_issues | array (optionnel) | Présent uniquement sur les transitions vers require_changes et rejected : les problèmes qui demandent votre attention. La clé est omise sur toute autre transition, ne considérez donc pas qu’elle est toujours presente |
release.preflight.report_ready
Section intitulée « release.preflight.report_ready »Declenche lorsque le rapport de qualité Preflight QC d’une sortie en mise en attente avant révision est prêt a être récupère. Necessite l’option Preflight QC sur votre compte.
{ "event": "release.preflight.report_ready", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "release_cat": "ABC123", "release_title": "Summer EP", "generated_at": "2026-07-07T09:58:12+00:00", "profile": { "name": "quality_report", "version": 2 }, "counts": { "blocking": 1, "informational": 2, "requires_feedback": 1 } }}| Champ | Type | Description |
|---|---|---|
release_id | integer | La sortie a laquelle appartient le rapport |
label_id | integer | Le label propriétaire de la sortie |
release_cat | string | null | Votre référence de catalogue de sortie |
release_title | string | null | Le titre de la sortie |
generated_at | string | Quand les vérifications se sont terminées (ISO 8601). Correspond au report.generated_at de l’endpoint du rapport de qualité |
profile | object | Le profil de qualité selon lequel les decomptes ont été calcules : {name, version} |
counts | object | Uniquement des decomptes agreges : {blocking, informational, requires_feedback}. Le decompte requires_feedback recoupe les deux autres |
stream_radar.flag_created
Section intitulée « stream_radar.flag_created »Declenche lorsqu’un signalement Stream Radar est cree, soit un signalement entièrement nouveau, soit un signalement précédemment résolu qui rouvre sur une nouvelle détection. Necessite l’option Stream Radar sur votre compte. Le champ transition distingue les deux cas : published pour un nouveau signalement, reopened pour un signalement redevenu actif.
{ "event": "stream_radar.flag_created", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "flag_id": 4501, "dsp": "spotify", "isrc": "USRC12345678", "release_id": 789, "track_id": 654, "severity": "high", "status": "active", "transition": "published", "first_detected_at": "2026-07-06T00:00:00+00:00", "last_detected_at": "2026-07-07T00:00:00+00:00", "estimated_affected_streams": 12500, "published_at": "2026-07-07T09:58:12+00:00", "resolved_at": null }}| Champ | Type | Description |
|---|---|---|
flag_id | integer | L’identifiant stable du signalement ; correspond a id sur les endpoints Stream Radar |
dsp | string | La plateforme sur laquelle le motif a été observe (p. ex. spotify) |
isrc | string | L’ISRC de l’enregistrement concerne |
release_id | integer | La sortie a laquelle appartient l’enregistrement |
track_id | integer | null | La piste precise, lorsque l’ISRC correspond sans ambiguïté a l’une de vos pistes |
severity | string | low, medium ou high |
status | string | active pour cet événement |
transition | string | published pour un nouveau signalement, reopened lorsqu’un signalement résolu est redevenu actif |
first_detected_at | string | null | Quand le motif a été observe pour la première fois pour cette piste et cette plateforme (ISO 8601) |
last_detected_at | string | null | La détection la plus récente (ISO 8601) |
estimated_affected_streams | integer | null | Une estimation du nombre d’écoutes impliquées |
published_at | string | Quand le signalement vous a été remonte pour la première fois (ISO 8601) |
resolved_at | string | null | null tant que le signalement est actif |
stream_radar.flag_resolved
Section intitulée « stream_radar.flag_resolved »Declenche lorsqu’un signalement Stream Radar se résout parce que les détections ont cesse. Necessite l’option Stream Radar. Mêmes champs que stream_radar.flag_created (sans transition), avec status regle sur resolved et resolved_at renseigne.
{ "event": "stream_radar.flag_resolved", "timestamp": "2026-07-14T10:00:00+00:00", "webhook_id": "123", "data": { "flag_id": 4501, "dsp": "spotify", "isrc": "USRC12345678", "release_id": 789, "track_id": 654, "severity": "high", "status": "resolved", "first_detected_at": "2026-07-06T00:00:00+00:00", "last_detected_at": "2026-07-12T00:00:00+00:00", "estimated_affected_streams": 18700, "published_at": "2026-07-07T09:58:12+00:00", "resolved_at": "2026-07-14T09:55:03+00:00" }}payment.statement_ready
Section intitulée « payment.statement_ready »Declenche lorsqu’un releve de paiement est genere et prêt a être consulte.
{ "event": "payment.statement_ready", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "payment_request_id": 1024, "invoice_number": "INV-2026-001", "period": "2026-04-30", "amount": 1234.56, "total_due_usd": 1234.56, "currency": "USD" }}| Champ | Type | Description |
|---|---|---|
payment_request_id | integer | ID interne de la demande de paiement |
invoice_number | string | Référence de facture pour le releve |
period | string | null | Date de fin de période (date ISO 8601, YYYY-MM-DD) |
amount | number | Montant du releve dans la devise currency |
total_due_usd | number | Total du releve converti en USD |
currency | string | Code de devise ISO 4217 (par défaut USD) |
transcode.completed et transcode.failed
Section intitulée « transcode.completed et transcode.failed »Declenche lorsque le transcodage audio d’une piste se termine. transcode.completed se declenche en cas de succès ; transcode.failed se declenche lorsque le transcodage echoue ou se termine de façon incomplète. Les deux partagent la même forme de payload.
{ "event": "transcode.completed", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "track_id": 654, "transcoder_queue_id": 987, "status": "complete", "status_message": "transcode_complete", "files": [ { "asset_type_id": 2, "status": "complete" } ] }}| Champ | Type | Description |
|---|---|---|
release_id | integer | La sortie a laquelle appartient la piste |
label_id | integer | Le label propriétaire de la sortie |
track_id | integer | La piste qui a été transcodée |
transcoder_queue_id | integer | ID interne de la file de transcodage |
status | string | Statut brut de la file : complete, error ou incomplete |
status_message | string | Code de motif sur et énumère : transcode_complete, transcode_error ou transcode_incomplete |
files | array | Detail par fichier pour la piste : {asset_type_id, status} par fichier transcode |
distribution.outlet.status_changed
Section intitulée « distribution.outlet.status_changed »Declenche a chaque transition de statut de distribution par outlet (par exemple scheduled → transcoding → batched → complete), pas seulement les transitions terminales couvertes par delivery.completed, delivery.failed et takedown.completed. Cet événement est bavard par nature : abonnez-vous a lui uniquement si vous voulez la progression complete par outlet.
{ "event": "distribution.outlet.status_changed", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "previous_status": "transcoding", "status": "batched" }}| Champ | Type | Description |
|---|---|---|
distro_queue_id | integer | ID interne de la file pour cette livraison |
release_id | integer | La sortie en cours de distribution |
label_id | integer | Le label propriétaire de la sortie |
release_cat | string | null | Votre référence de catalogue de sortie |
outlet_id | integer | null | L’ID de l’outlet de destination |
outlet_name | string | null | Nom lisible de l’outlet |
previous_status | string | null | Le statut précédent ; null lorsque la ligne n’avait aucun statut précédent reconnu |
status | string | Le nouveau statut |
Vérification des signatures webhook
Section intitulée « Vérification des signatures webhook »Chaque livraison de webhook est signée afin que vous puissiez vérifier qu’elle provient bien de LabelGrid. Vérifiez toujours la signature avant de traiter l’événement.
Headers de la requête
Section intitulée « Headers de la requête »Chaque requête POST de webhook inclut ces headers :
| Header | Description |
|---|---|
X-Webhook-Signature | HMAC-SHA256 du corps brut de la requête, en hexadécimal minuscule, sans prefixe d’algorithme |
X-Webhook-Timestamp | Copie de commodité de la propriété timestamp du corps. Non couverte par la signature — ne l’utilisez jamais pour décider si une livraison est récente. |
X-Webhook-Event | Identifiant d’événement (par exemple, delivery.completed) |
X-Webhook-Id | L’ID de la configuration du webhook qui reçoit la livraison (et non un ID propre à chaque livraison) |
User-Agent | LabelGrid-Webhooks/1.0 |
Content-Type | application/json |
Algorithme
Section intitulée « Algorithme »- Algorithme : HMAC-SHA256
- Encodage : Hexadécimal minuscule
- Prefixe : Aucun — la valeur est juste le digest hex, pas
sha256=... - Contenu signe : Le corps JSON brut complet de la requête — et rien d’autre. Aucun header n’est signé.
Le corps porte sa propre propriété timestamp : cette valeur est donc protégée par la signature. Le header X-Webhook-Timestamp n’en est qu’une copie, envoyée par commodité, et un attaquant qui intercepte une livraison peut modifier le header à volonté sans invalider la signature. Les contrôles de fraîcheur doivent donc lire timestamp dans le corps parsé, jamais dans le header.
Recette de vérification
Section intitulée « Recette de vérification »- Lisez le corps brut de la requête avant tout parsing ou transformation JSON. Re-serialiser le JSON parse peut produire des octets différents et casser la signature.
- Calculez
HMAC-SHA256(corps_brut, votre_secret_webhook)et prenez le digest hexadécimal minuscule. - Comparez avec
X-Webhook-Signatureen utilisant une comparaison a temps constant. Arrêtez-vous là si elle ne correspond pas. - Ce n’est qu’à ce moment que vous parsez le corps, et vous rejetez la requête si sa propriété
timestampest plus ancienne que votre fenêtre de tolérance de rejeu — nous suggérons 5 minutes. Comme cette valeur est signée, un attaquant ne peut pas la rafraîchir pour faire passer une livraison interceptée pour récente.
Chaque renvoi est signé à nouveau avec un nouveau timestamp : une fenêtre de 5 minutes ne rejette donc jamais un renvoi légitime, aussi tard qu’il arrive dans le calendrier de backoff.
Exemple PHP
Section intitulée « Exemple PHP »$rawBody = file_get_contents('php://input');$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $rawBody, $webhookSecret);
if (! hash_equals($expected, $signature)) { http_response_code(401); exit('Signature invalide');}
// Ne parsez qu'une fois les octets authentifiés.$payload = json_decode($rawBody, true);
// La fraîcheur vient de l'horodatage SIGNÉ dans le corps,// jamais du header X-Webhook-Timestamp.if (! isset($payload['timestamp']) || abs(time() - strtotime($payload['timestamp'])) > 300) { http_response_code(401); exit('Livraison obsolete');}
// ... traiter l'événement (voir « Gérer les livraisons répétées » ci-dessous)http_response_code(200);Exemple Node.js
Section intitulée « Exemple Node.js »const crypto = require('crypto');
// Express : capturer le corps brut AVANT tout middleware JSONapp.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const rawBody = req.body; // Buffer const signature = req.header('X-Webhook-Signature') || '';
const expected = crypto .createHmac('sha256', webhookSecret) .update(rawBody) .digest('hex');
const sigBuf = Buffer.from(signature, 'hex'); const expBuf = Buffer.from(expected, 'hex');
if (sigBuf.length !== expBuf.length || !crypto.timingSafeEqual(sigBuf, expBuf)) { return res.status(401).send('Signature invalide'); }
// Ne parsez qu'une fois les octets authentifiés. const payload = JSON.parse(rawBody.toString('utf8'));
// La fraîcheur vient de l'horodatage SIGNÉ dans le corps, // jamais du header X-Webhook-Timestamp. const sentAt = new Date(payload.timestamp).getTime();
if (Number.isNaN(sentAt) || Math.abs(Date.now() - sentAt) > 5 * 60 * 1000) { return res.status(401).send('Livraison obsolete'); }
// ... traiter l'événement (voir « Gérer les livraisons répétées » ci-dessous) res.sendStatus(200);});Exemple Python
Section intitulée « Exemple Python »import hmac, hashlib, jsonfrom datetime import datetime, timezone
raw_body = request.get_data() # Flask : bytes, avant tout parsing JSONsignature = request.headers.get('X-Webhook-Signature', '')
expected = hmac.new( webhook_secret.encode('utf-8'), raw_body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, signature): return ('Signature invalide', 401)
payload = json.loads(raw_body) # parser seulement une fois les octets authentifiés
delivery_time = datetime.fromisoformat(payload['timestamp']) # la valeur SIGNÉE, jamais le headerif abs((datetime.now(timezone.utc) - delivery_time).total_seconds()) > 300: return ('Livraison obsolete', 401)
return ('', 200) # traiter l'evenement puis acquitterPieges courants
Section intitulée « Pieges courants »- Contrôler la fraîcheur avec le header
X-Webhook-Timestamp. Le header n’est pas signé. Quiconque intercepte une livraison peut rejouer indéfiniment le même corps et la même signature avec une valeur de header récente et passer ainsi un contrôle fondé sur le header. Lisez plutôttimestampdans le corps parsé — cette valeur, elle, est signée. - Re-serialiser le corps avant de le hacher. Les frameworks qui parsent automatiquement le JSON (Express
express.json(), le corps de requête par défaut de Laravel) perdent les octets originaux. Capturez d’abord le corps brut. - Utiliser une comparaison qui n’est pas a temps constant (
==,===). Susceptible aux attaques temporelles — utilisez toujourshash_equals(PHP),crypto.timingSafeEqual(Node),hmac.compare_digest(Python), ou l’equivalent dans votre langage. - S’attendre a un prefixe
sha256=. La valeur du header est juste le digest hex sans prefixe. - Omettre le contrôle de fraîcheur. Sans lui, une livraison interceptée peut être rejouée indéfiniment contre votre endpoint.
- Prendre
X-Webhook-Idpour un identifiant de livraison. Il identifie la configuration du webhook, pas la livraison individuelle, et il n’est pas signé non plus.
Gérer les livraisons répétées
Section intitulée « Gérer les livraisons répétées »La livraison des webhooks se fait au moins une fois : une livraison que votre endpoint a bel et bien traitée peut arriver de nouveau si votre réponse 2xx s’est perdue ou est arrivée après le timeout de 10 secondes et que LabelGrid la renvoie. Vérifier la signature prouve qu’une requête est authentique — cela ne prouve pas que vous ne l’avez pas déjà traitée.
Les livraisons ne portent pas d’identifiant unique par livraison : construisez donc votre propre clé d’idempotence à partir du payload signé. Le type d’événement plus les identifiants présents dans data suffisent généralement — par exemple delivery.completed plus distro_queue_id, ou transcode.completed plus track_id. Enregistrez la clé lorsque vous traitez un événement et ignorez tout ce que vous avez déjà enregistré.
N’utilisez pas la signature ni le timestamp comme clé. Chaque tentative est signée à nouveau au moment de l’envoi : le renvoi d’un événement que vous avez déjà traité arrive donc avec un timestamp différent et une signature différente — la clé doit venir des identifiants propres à l’événement.
Combinez cela avec le contrôle de fraîcheur ci-dessus : la fraîcheur borne la durée pendant laquelle une livraison interceptée reste rejouable, et l’idempotence rend une répétition inoffensive, qu’elle vienne d’un renvoi ou d’un attaquant à l’intérieur de la fenêtre.
Limites et fiabilité
Section intitulée « Limites et fiabilité »Limites de requête
Section intitulée « Limites de requête »| Limite | Valeur |
|---|---|
| Timeout de requête | 10 secondes |
| Taille maximale du payload | 64 Ko |
| Maximum de webhooks par utilisateur | 10 |
Si votre endpoint ne répond pas dans les 10 secondes, la livraison est considérée comme un échec et renvoyée.
Calendrier de renvoi
Section intitulée « Calendrier de renvoi »Si votre endpoint retourne un statut non-2xx ou expire, LabelGrid renvoie avec un backoff exponentiel :
| Tentative | Attente avant le renvoi |
|---|---|
| 1 → 2 | 30 secondes |
| 2 → 3 | 1 minute |
| 3 → 4 | 2 minutes |
| 4 → 5 | 4 minutes |
| 5 → 6 | 8 minutes |
| 6 → 7 | 16 minutes |
| 7 → 8 | 32 minutes |
| 8 → 9 | 64 minutes |
| 9 → 10 | 128 minutes |
Chaque intervalle inclut 0 a 30 secondes de jitter. Après 10 tentatives (~4,5 heures de temps total ecoule), la livraison est journalisee comme définitivement échouée et n’est plus renvoyée.
Desactivation automatique
Section intitulée « Desactivation automatique »Si l’endpoint d’un webhook echoue de maniere répétée — des livraisons échouées consécutives sans aucune livraison réussie entre elles —, LabelGrid désactivé automatiquement le webhook pour cesser de réessayer un endpoint qui ne peut manifestement pas recevoir d’événements. Le compteur d’echecs est remis a zéro a chaque livraison réussie, de sorte qu’un incident ponctuel ne désactivé jamais un webhook ; seul un échec continu et ininterrompu le fait.
Lorsqu’un webhook est désactivé de cette maniere, son propriétaire reçoit un email. L’email indique le nom du webhook et l’URL de son endpoint, ainsi que le type d’echec ayant declenche la desactivation — par exemple un délai de connexion depasse ou des erreurs HTTP répétées.
La réactivation se fait en autonomie : corrigez votre endpoint, puis réactivez le webhook depuis Profil → Webhooks. Réactiver un webhook désactivé remet son compteur d’echecs a zéro. La liste des webhooks affiche le statut actif et le nombre d’echecs actuel de chaque webhook, ce qui vous permet de repérer un endpoint défaillant d’un coup d’oeil.
Bonnes pratiques pour la fiabilité
Section intitulée « Bonnes pratiques pour la fiabilité »- Retournez une réponse 2xx rapidement (en moins de 10 secondes)
- Traitez les données de maniere asynchrone après avoir acquitte
- Vérifiez la signature de chaque requête (voir Vérification des signatures webhook)
- Rendez votre gestionnaire idempotent — la livraison se fait au moins une fois (voir Gérer les livraisons répétées)
- Surveillez votre compteur d’echecs dans la liste des webhooks
- Consultez les journaux de livraison lorsque vous enquêtez sur des événements manques
Cas d’utilisation
Section intitulée « Cas d’utilisation »Notifications automatisées
Section intitulée « Notifications automatisées »- Envoyer des messages Slack lorsque les sorties sont en ligne
- Emailer votre équipe en cas d’echec de livraison
- Mettre a jour les tableaux de bord internes
Automatisation de workflow
Section intitulée « Automatisation de workflow »- Déclencher des campagnes marketing lorsque les sorties sont distribuées
- Mettre a jour votre site web lorsque du nouveau contenu est disponible
- Synchroniser le statut avec des outils de gestion de projet externes
Surveillance et alertes
Section intitulée « Surveillance et alertes »- Obtenir des alertes instantanées en cas d’echec de livraison
- Suivre la progression de la distribution en temps réel
- Surveiller les changements de statut de révision
Dépannage
Section intitulée « Dépannage »Le webhook ne reçoit pas d’événements
Section intitulée « Le webhook ne reçoit pas d’événements »- Vérifiez le statut - Le webhook est-il Active ?
- Vérifiez l’URL - L’endpoint est-il accessible depuis internet ?
- Vérifiez les événements - Les bons événements sont-ils sélectionnés ?
- Consultez les journaux - Des erreurs sont-elles enregistrées ?
Nombre d’echecs élevé
Section intitulée « Nombre d’echecs élevé »- Vérifiez votre endpoint - Retourne-t-il 200 OK ?
- Vérifiez le temps de réponse - Repond-il dans le délai imparti ?
- Examinez les messages d’erreur - Qu’est-ce qui echoue ?
- Testez manuellement - Envoyez un webhook de test
Régénérer le secret
Section intitulée « Régénérer le secret »Si votre secret webhook est compromis :
- Cliquez sur Regenerate Secret dans les paramètres du webhook
- Mettez a jour votre application avec le nouveau secret
- L’ancien secret cesse immédiatement de fonctionner
Besoin d’aide ?
Section intitulée « Besoin d’aide ? »Si vous avez des questions sur les webhooks, contactez notre équipe support.
Vous n’utilisez pas encore LabelGrid ?
Tout ce que vous venez de lire est disponible sur notre plateforme.
Découvrez ce que LabelGrid peut faire →