Aller au contenu
Support

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 à des systèmes externes.

  1. Vous configurez un webhook - Spécifiez une URL et les événements à écouter
  2. Un événement se produit - Par exemple, une sortie est livrée à un store
  3. LabelGrid envoie une requête POST - Votre serveur reçoit les données de l’événement
  4. Votre système les traite - Automatisez des workflows en fonction de l’événement

  1. Cliquez sur votre icône de profil en haut à droite
  2. Sélectionnez Webhooks dans le menu déroulant

  1. Cliquez sur Create Webhook
  2. Saisissez un Name pour identifier ce webhook
  3. Saisissez l’URL ou vous souhaitez recevoir les notifications
  4. Sélectionnez les Events qui doivent déclencher ce webhook
  5. Cliquez sur Create

Lorsque vous créez un webhook, vous recevez une clé secrète. Utilisez-la pour vérifier que les requêtes entrantes proviennent bien de LabelGrid :

  • Copiez le secret immédiatement : LabelGrid ne l’affiche qu’une seule fois et n’en conserve aucune copie lisible
  • Stockez le secret de manière sécurisée
  • Vérifiez la signature des requêtes entrantes
  • En cas de compromission ou de perte, renouvelez le secret (voir Renouveler le secret)

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énementDescription
delivery.completedDéclenché lorsqu’une sortie est livrée avec succès à un store
delivery.failedDéclenché lorsque la livraison à un store échoue
takedown.completedDéclenché lorsqu’une demande de retrait est terminée
release.review.status_changedDéclenché lorsque le statut de révision d’une sortie change
track.review.status_changedDéclenché lorsque le statut de révision d’une piste change
release.preflight.report_readyDéclenché lorsque le rapport Preflight QC d’une sortie en attente est prêt à être récupéré
stream_radar.flag_createdDéclenché lorsqu’un signalement Stream Radar est créé, ou qu’un signalement résolu rouvre sur une nouvelle détection
stream_radar.flag_resolvedDéclenché lorsqu’un signalement Stream Radar se résout parce que les détections ont cessé
release.distributedDéclenché lorsqu’une sortie est distribuée
release.deletedDéclenché lorsqu’une sortie est supprimée ; l’API renvoie ensuite 404 pour cette sortie
payment.statement_readyDéclenché lorsqu’un relevé de paiement est prêt à être consulté
transcode.completedDéclenché lorsque le transcodage audio d’une piste se termine avec succès
transcode.failedDéclenché lorsque le transcodage d’une piste échoue ou se termine de façon incomplète
distribution.outlet.status_changedDéclenché à 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 manière programmatique : GET /api/public/webhooks/event-types renvoie chaque événement accompagné d’un schéma data décrivant les clés et les types de son payload, afin que les consommateurs à schéma strict puissent élargir leur validation entrante à l’avance.


La liste des webhooks affiche :

ColonneDescription
NameLe nom que vous avez attribué au webhook
URLOu les notifications sont envoyées
EventsNombre d’événements configurés
StatusActive ou Inactive
Success / FailNombre de livraisons réussies et échouées
Last TriggeredDernière activation du webhook
  1. Cliquez sur l’action Edit sur la ligne du webhook
  2. Modifiez le nom, l’URL ou les événements
  3. Cliquez sur Save

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
  1. Cliquez sur l’action Delete sur la ligne du webhook
  2. Confirmez la suppression

Avant de dépendre d’un webhook en production, testez-le :

  1. Cliquez sur l’action Test sur votre webhook
  2. LabelGrid envoie un payload de test à votre URL
  3. Vérifiez que votre endpoint a bien reçu et traite correctement

Surveillez l’activité des webhooks et dépannez les problèmes :

  1. Cliquez sur l’action View Logs sur un webhook
  2. Consultez l’historique de toutes les livraisons du webhook

Chaque entrée de journal affiche :

ChampDescription
Event TypeL’événement qui a déclenché cette livraison
Response StatusCode de statut HTTP de votre serveur
DurationDurée de la requête
AttemptNuméro de la tentative de renvoi
TimestampDate et heure de la livraison

Lorsqu’un événement se produit, LabelGrid envoie une requête POST à votre URL avec un payload JSON :

{
"event": "delivery.completed",
"event_id": "5f0c8a52-3d1e-4b7a-9c2f-6e8d1a4b7c90",
"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 configuré (il correspond au header X-Webhook-Id).

event_id identifie l’événement lui-même, et non la tentative de livraison. Chaque renvoi d’une livraison porte le même event_id, tout comme chaque webhook auquel l’événement est envoyé. Il correspond au header X-Webhook-Event-Id. Les exemples de payload par événement ci-dessous l’omettent pour rester courts.


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 sérialisés dans le payload.

Déclenché 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"
}
}
ChampTypeDescription
distro_queue_idintegerID interne de la file pour cette tentative de livraison
release_idintegerLa sortie qui a été livrée
label_idintegerLe label propriétaire de la sortie, pour router l’événement sans requête supplémentaire
release_catstring | nullVotre référence de catalogue de sortie
outlet_idinteger | nullL’ID de l’outlet de destination
outlet_namestring | nullNom lisible de l’outlet (par exemple, "Spotify")
statusstringToujours "complete" pour cet événement

Déclenché une fois par outlet lorsqu’une livraison de sortie atteint un état d’échec 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."
}
}
ChampTypeDescription
statusstringL’un de error, fault, rejected, batch_exception
messagestring | nullRaison de l’échec depuis l’outlet ou le pipeline de distribution

Déclenché une fois par outlet lorsqu’une demande de retrait réussit. 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
}
}

Déclenché une fois par sortie lorsque la sortie passe à l’état de livraison distributed. Ne se déclenche 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"
}
}

Déclenché une seule fois lorsqu’une sortie est supprimée. Après cet événement, l’API renvoie 404 pour cette sortie : n’essayez donc pas de la récupérer à nouveau.

{
"event": "release.deleted",
"timestamp": "2026-05-18T10:00:00+00:00",
"webhook_id": "123",
"data": {
"release_id": 789,
"label_id": 321,
"barcode_number": "0123456789012",
"release_cat": "ABC123",
"release_title": "Summer EP"
}
}

Déclenché chaque fois qu’une sortie passe d’un état de révision à 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"
}
}
ChampTypeDescription
previous_statusstringStatut précédent. L’un de draft, to_review, approved, rejected, require_changes, audit, pending_customer_review
new_statusstringNouveau statut. Même ensemble de valeurs
review_issuesarray (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 présente

Déclenché chaque fois qu’une piste passe d’un état de révision à un autre, uniquement lorsque le statut change réellement.

{
"event": "track.review.status_changed",
"timestamp": "2026-05-18T10:00:00+00:00",
"webhook_id": "123",
"data": {
"track_id": 456,
"release_id": 789,
"label_id": 321,
"previous_status": "to_review",
"new_status": "require_changes"
}
}
ChampTypeDescription
track_idintegerLa piste dont le statut de révision a changé
previous_statusstringStatut précédent. Mêmes valeurs que pour release.review.status_changed
new_statusstringNouveau statut. Même ensemble de valeurs

Déclenché lorsque le rapport de qualité Preflight QC d’une sortie en mise en attente avant révision est prêt à être récupéré. Nécessite 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 }
}
}
ChampTypeDescription
release_idintegerLa sortie à laquelle appartient le rapport
label_idintegerLe label propriétaire de la sortie
release_catstring | nullVotre référence de catalogue de sortie
release_titlestring | nullLe titre de la sortie
generated_atstringQuand les vérifications se sont terminées (ISO 8601). Correspond au report.generated_at de l’endpoint du rapport de qualité
profileobjectLe profil de qualité selon lequel les décomptes ont été calculés : {name, version}
countsobjectUniquement des décomptes agrégés : {blocking, informational, requires_feedback}. Le décompte requires_feedback recoupe les deux autres

Déclenché lorsqu’un signalement Stream Radar est créé, soit un signalement entièrement nouveau, soit un signalement précédemment résolu qui rouvre sur une nouvelle détection. Nécessite 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
}
}
ChampTypeDescription
flag_idintegerL’identifiant stable du signalement ; correspond à id sur les endpoints Stream Radar
dspstringLa plateforme sur laquelle le motif a été observé (p. ex. SPOTIFY)
isrcstringL’ISRC de l’enregistrement concerne
release_idintegerLa sortie à laquelle appartient l’enregistrement
track_idinteger | nullLa piste précise, lorsque l’ISRC correspond sans ambiguïté à l’une de vos pistes
severitystringmedium ou high
statusstringactive pour cet événement
transitionstringpublished pour un nouveau signalement, reopened lorsqu’un signalement résolu est redevenu actif
first_detected_atstring | nullQuand le motif a été observé pour la première fois pour cette piste et cette plateforme (ISO 8601)
last_detected_atstring | nullLa détection la plus récente (ISO 8601)
estimated_affected_streamsinteger | nullUne estimation du nombre d’écoutes impliquées
published_atstringQuand le signalement vous a été remonté pour la première fois (ISO 8601)
resolved_atstring | nullnull tant que le signalement est actif

Déclenché lorsqu’un signalement Stream Radar se résout parce que les détections ont cessé. Nécessite l’option Stream Radar. Mêmes champs que stream_radar.flag_created (sans transition), avec status réglé sur resolved et resolved_at renseigné.

{
"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"
}
}

Déclenché lorsqu’un relevé de paiement est généré et prêt à être consulté.

{
"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"
}
}
ChampTypeDescription
payment_request_idintegerID interne de la demande de paiement
invoice_numberstringRéférence de facture pour le relevé
periodstring | nullDate de fin de période (date ISO 8601, YYYY-MM-DD)
amountnumberMontant du relevé dans la devise currency
total_due_usdnumberTotal du relevé converti en USD
currencystringCode de devise ISO 4217 (par défaut USD)

Déclenché lorsque le transcodage audio d’une piste se termine. transcode.completed se déclenche en cas de succès ; transcode.failed se déclenche lorsque le transcodage échoue 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" }
]
}
}
ChampTypeDescription
release_idintegerLa sortie à laquelle appartient la piste
label_idintegerLe label propriétaire de la sortie
track_idintegerLa piste qui a été transcodée
transcoder_queue_idintegerID interne de la file de transcodage
statusstringStatut brut de la file : complete, error ou incomplete
status_messagestringCode de motif sûr et énuméré : transcode_complete, transcode_error ou transcode_incomplete
filesarrayDétail par fichier pour la piste : {asset_type_id, status} par fichier transcode

Déclenché à 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 à lui uniquement si vous voulez la progression complète 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"
}
}
ChampTypeDescription
distro_queue_idintegerID interne de la file pour cette livraison
release_idintegerLa sortie en cours de distribution
label_idintegerLe label propriétaire de la sortie
release_catstring | nullVotre référence de catalogue de sortie
outlet_idinteger | nullL’ID de l’outlet de destination
outlet_namestring | nullNom lisible de l’outlet
previous_statusstring | nullLe statut précédent ; null lorsque la ligne n’avait aucun statut précédent reconnu
statusstringLe nouveau statut

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.

Chaque requête POST de webhook inclut ces headers :

HeaderDescription
X-Webhook-SignatureHMAC-SHA256 du corps brut de la requête, en hexadécimal minuscule, sans préfixe d’algorithme
X-Webhook-TimestampCopie 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-EventIdentifiant d’événement (par exemple, delivery.completed)
X-Webhook-IdL’ID de la configuration du webhook qui reçoit la livraison (et non un ID propre à chaque livraison)
X-Webhook-Event-IdLa valeur event_id de l’événement, identique à chaque renvoi
User-AgentLabelGrid-Webhooks/1.0
Content-Typeapplication/json
  • Algorithme : HMAC-SHA256
  • Encodage : Hexadécimal minuscule
  • Préfixe : Aucun — la valeur est juste le digest hex, pas sha256=...
  • Contenu signé : 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.

  1. Lisez le corps brut de la requête avant tout parsing ou transformation JSON. Re-sérialiser le JSON parse peut produire des octets différents et casser la signature.
  2. Calculez HMAC-SHA256(corps_brut, votre_secret_webhook) et prenez le digest hexadécimal minuscule.
  3. Comparez avec X-Webhook-Signature en utilisant une comparaison à temps constant. Arrêtez-vous là si elle ne correspond pas.
  4. Ce n’est qu’à ce moment que vous parsez le corps, et vous rejetez la requête si sa propriété timestamp est 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.

$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);
const crypto = require('crypto');
// Express : capturer le corps brut AVANT tout middleware JSON
app.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);
});
import hmac, hashlib, json
from datetime import datetime, timezone
raw_body = request.get_data() # Flask : bytes, avant tout parsing JSON
signature = 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 header
if abs((datetime.now(timezone.utc) - delivery_time).total_seconds()) > 300:
return ('Livraison obsolete', 401)
return ('', 200) # traiter l'evenement puis acquitter
  • 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ôt timestamp dans le corps parsé — cette valeur, elle, est signée.
  • Re-sérialiser 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 à temps constant (==, ===). Susceptible aux attaques temporelles — utilisez toujours hash_equals (PHP), crypto.timingSafeEqual (Node), hmac.compare_digest (Python), ou l’équivalent dans votre langage.
  • S’attendre à un préfixe sha256=. La valeur du header est juste le digest hex sans préfixe.
  • 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-Id pour un identifiant de livraison. Il identifie la configuration du webhook, pas la livraison individuelle, et il n’est pas signé non plus.

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.

Utilisez event_id comme clé d’idempotence : il reste le même à chaque renvoi d’un événement. Enregistrez-le lorsque vous traitez un événement et ignorez toute livraison dont vous avez déjà enregistré l’event_id. Comme il fait partie du corps signé, une signature valide le garantit aussi.

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.


LimiteValeur
Timeout de requête10 secondes
Taille maximale du payload64 Ko
Maximum de webhooks par utilisateur10

Si votre endpoint ne répond pas dans les 10 secondes, la livraison est considérée comme un échec et renvoyée.

Si votre endpoint retourne un statut non-2xx ou expire, LabelGrid renvoie avec un backoff exponentiel :

TentativeAttente avant le renvoi
1 → 230 secondes
2 → 31 minute
3 → 42 minutes
4 → 54 minutes
5 → 68 minutes
6 → 716 minutes
7 → 832 minutes
8 → 964 minutes
9 → 10128 minutes

Chaque intervalle inclut 0 à 30 secondes de jitter. Après 10 tentatives (~4,5 heures de temps total écoulé), la livraison est journalisée comme définitivement échouée et n’est plus renvoyée.

Si l’endpoint d’un webhook échoue de manière 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’échecs est remis à zéro à 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 manière, 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’échec ayant déclenché la désactivation — par exemple un délai de connexion dépassé ou des erreurs HTTP répétées.

La réactivation se fait en autonomie : corrigez votre endpoint, puis réactivez le webhook depuis Webhooks dans le menu du compte (votre avatar, en haut à droite). Réactiver un webhook désactivé remet son compteur d’échecs à zéro. La liste des webhooks affiche le statut actif et le nombre d’échecs actuel de chaque webhook, ce qui vous permet de repérer un endpoint défaillant d’un coup d’oeil.

  • Retournez une réponse 2xx rapidement (en moins de 10 secondes)
  • Traitez les données de manière asynchrone après avoir acquitté
  • 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’échecs dans la liste des webhooks
  • Consultez les journaux de livraison lorsque vous enquêtez sur des événements manques

  • Envoyer des messages Slack lorsque les sorties sont en ligne
  • Emailer votre équipe en cas d’échec de livraison
  • Mettre à jour les tableaux de bord internes
  • Déclencher des campagnes marketing lorsque les sorties sont distribuées
  • Mettre à jour votre site web lorsque du nouveau contenu est disponible
  • Synchroniser le statut avec des outils de gestion de projet externes
  • Obtenir des alertes instantanées en cas d’échec de livraison
  • Suivre la progression de la distribution en temps réel
  • Surveiller les changements de statut de révision

  1. Vérifiez le statut - Le webhook est-il Active ?
  2. Vérifiez l’URL - L’endpoint est-il accessible depuis internet ?
  3. Vérifiez les événements - Les bons événements sont-ils sélectionnés ?
  4. Consultez les journaux - Des erreurs sont-elles enregistrées ?
  1. Vérifiez votre endpoint - Retourne-t-il 200 OK ?
  2. Vérifiez le temps de réponse - Répond-il dans le délai imparti ?
  3. Examinez les messages d’erreur - Qu’est-ce qui échoue ?
  4. Testez manuellement - Envoyez un webhook de test

Si votre secret webhook est compromis ou perdu, renouvelez-le. LabelGrid ne peut pas vous afficher à nouveau le secret actuel : le renouvellement est le seul moyen d’en obtenir un que vous puissiez copier.

  1. Ouvrez le menu du webhook (⋮) et cliquez sur Edit
  2. À côté de Webhook Secret, cliquez sur Rotate
  3. Cliquez sur Rotate secret pour confirmer
  4. Cliquez sur Copy dans l’encadré Copy it now et enregistrez le nouveau secret dans votre application
  5. Cliquez sur I’ve copied it

L’ancien secret cesse de fonctionner dès le renouvellement, et la vérification des signatures sur votre endpoint échoue tant que vous n’avez pas enregistré le nouveau. Mettez donc à jour votre endpoint dans la foulée. Le nouveau secret s’applique immédiatement : inutile de cliquer sur Save Changes.

LabelGrid n’affiche le nouveau secret qu’une seule fois. Si vous essayez de fermer la fenêtre avant d’avoir cliqué sur I’ve copied it, LabelGrid vous demande d’abord de confirmer, car la fermeture est votre dernière occasion de le copier. Si vous le perdez plus tard, renouvelez-le une nouvelle fois.


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 →