Webhooks
Recevez des notifications HTTP signées lorsque les liens, campagnes et publications changent dans votre espace de travail.
Les webhooks Styrar envoient des notifications HTTP signées lorsque des ressources de votre espace de travail changent. Utilisez-les pour synchroniser liens et clics avec un CRM, déclencher des automatisations dans votre stack, ou diffuser des événements de funnel vers un entrepôt de données.
Ceci remplace l'API de webhooks limitée aux liens, désormais retirée (/v1/link-webhooks). Les nouvelles intégrations doivent utiliser uniquement /v1/webhooks/*.
Mettre en place un webhook
Suivez ces étapes pour passer de zéro à un point de terminaison vérifié et prêt pour la production.
1. Préparez votre URL de réception
Votre serveur a besoin d'une URL HTTPS publique qui accepte des requêtes POST avec un corps JSON. En production, les URL de callback doivent utiliser HTTPS.
Votre gestionnaire doit :
- Lire le corps brut de la requête sous forme de chaîne ou de buffer (ne pas analyser le JSON avant de vérifier la signature).
- Lire les en-têtes
Styrar-Signature,Styrar-Event-IdetStyrar-Event-Type. - Vérifier la signature (voir la section Vérifier les signatures ci-dessous).
- Retourner un code 2xx rapidement une fois l'événement accepté. Mettez le traitement lourd en file d'attente de manière asynchrone.
Exemple de chemin : https://votre-app.com/webhooks/styrar
Styrar ne peut pas livrer vers des adresses privées ou loopback comme localhost.
2. Obtenez un accès à l'API (pour une configuration programmatique)
Si vous créez des points de terminaison via l'API plutôt que via le tableau de bord, vous avez besoin d'un jeton Bearer avec :
| Portée | Accès |
|---|---|
webhooks:read | Lister les points de terminaison, les livraisons et les types d'événements |
webhooks:write | Créer, mettre à jour, supprimer, tester, faire tourner le secret, relancer les livraisons |
Créez une clé API dans Paramètres → Clés API avec webhooks:read et webhooks:write, ou utilisez un jeton d'accès OAuth d'une application connectée avec les mêmes portées.
Pour les espaces de travail d'entreprise, transmettez companyId lors des requêtes de liste et de création.
3. Créez un point de terminaison dans le tableau de bord
- Connectez-vous et ouvrez Paramètres → Webhooks (
/settings/webhooks). - Sous Points de terminaison, saisissez votre URL de point de terminaison (le callback HTTPS public).
- Ajoutez éventuellement une Description (par exemple « Synchronisation CRM de production »).
- Sélectionnez les Événements souhaités (au moins un est requis). Choix courants :
link.clickedpour le suivi des clicslink.created/link.updated/link.deletedpour le cycle de vie des lienspost.publishedetcampaign.createdpour les événements de funnel
- Cliquez sur Ajouter un point de terminaison.
Après la création, Styrar affiche votre secret de signature (whsec_live_… ou whsec_test_…). Copiez-le immédiatement et stockez-le dans votre gestionnaire de secrets. Il n'est affiché qu'une seule fois. Si vous le perdez, utilisez Faire tourner le secret sur le point de terminaison et mettez à jour votre serveur.
4. Créez un point de terminaison via l'API
Authorization: Bearer sty_live_your_api_key
Content-Type: application/json
{
"companyId": "cmxyz_company",
"url": "https://your-app.com/webhooks/styrar",
"description": "Production CRM sync",
"eventTypes": [
"link.clicked",
"link.created"
]
}{
"id": "wh_ep_abc123",
"url": "https://your-app.com/webhooks/styrar",
"description": "Production CRM sync",
"enabled": true,
"eventTypes": [
"link.clicked",
"link.created"
],
"secretPrefix": "whsec_l",
"companyId": "cmxyz_company",
"userId": null,
"disabledAt": null,
"createdAt": "2026-06-22T12:00:00.000Z",
"updatedAt": "2026-06-22T12:00:00.000Z",
"secret": "whsec_live_abc123onlyShownOnce"
}Stockez secret immédiatement. Il n'est pas renvoyé lors des requêtes GET ultérieures. Un tableau eventTypes vide vous abonne à tous les types d'événements ; le tableau de bord exige au moins un événement explicite.
5. Envoyez un événement de test
Confirmez que votre serveur est accessible avant de vous fier au trafic réel.
Tableau de bord : Sur la ligne du point de terminaison, cliquez sur Envoyer un test. Styrar livre un événement webhook.test. Vous devriez voir une notification de succès avec le code de statut HTTP.
API :
Authorization: Bearer sty_live_your_api_key{
"ok": true,
"statusCode": 200
}Lorsque le test réussit, votre serveur devrait avoir reçu un événement webhook.test (voir Recevoir un événement sur votre serveur ci-dessous).
Consultez Livraisons récentes dans le tableau de bord (ou GET /v1/webhooks/deliveries) si le test échoue. Problèmes courants :
| Problème | Que vérifier |
|---|---|
| Connexion refusée / délai dépassé | L'URL est en HTTPS public, le pare-feu autorise Styrar, le tunnel est actif |
| HTTP 4xx/5xx depuis votre application | Le gestionnaire renvoie 2xx après vérification ; journalisez le corps brut et les en-têtes |
| La vérification de signature échoue | Utilisez le corps brut, le bon secret, une comparaison en temps constant |
| Point de terminaison désactivé | Réactivez dans le tableau de bord ou corrigez ce qui a causé le HTTP 410 |
6. Vérifiez et traitez les livraisons
Pour chaque POST vers votre URL :
- Analysez
Styrar-Signaturepour en extraire l'horodatagetet le condensév1. - Rejetez si
test plus ancien que votre tolérance (5 minutes recommandées). - Calculez le HMAC-SHA256 de
"{t}.{raw_body}"avec le secret de votre point de terminaison. - Comparez avec
v1en utilisant une vérification en temps constant. - N'analysez le JSON qu'après réussite de la vérification.
- Dédupliquez sur
Styrar-Event-Id(livraison au moins une fois).
Voir la section Vérifier les signatures ci-dessous pour un exemple en Node.js.
7. Passez en production
- Gardez le point de terminaison Activé dans le tableau de bord.
- Abonnez-vous uniquement aux événements dont vous avez besoin (réduit le bruit et le coût).
- Surveillez les Livraisons récentes pour détecter les échecs et utilisez Relancer au besoin.
- Faites tourner le secret s'il a pu être divulgué (Faire tourner le secret dans le tableau de bord ou
POST …/rotate-secret).
Démarrage rapide
- Obtenez un accès à l'API avec les portées
webhooks:readetwebhooks:write(clé API ou OAuth). - Exposez un récepteur HTTPS public et créez un point de terminaison dans Paramètres → Webhooks ou via
POST /v1/webhooks/endpoints. - Copiez le secret de signature lorsqu'il est affiché et stockez-le en sécurité.
- Envoyez un événement de test et confirmez que votre serveur vérifie
Styrar-Signatureet renvoie 2xx. - Traitez les événements réels avec déduplication sur
Styrar-Event-Id.
Authentification
La gestion des webhooks nécessite un jeton Bearer avec les portées listées à l'étape 2 ci-dessus. Les clés API avec les portées correspondantes fonctionnent de la même manière que les jetons d'accès OAuth.
Types d'événements
Appelez GET /v1/webhooks/event-types pour obtenir le catalogue en temps réel de votre environnement. Abonnez-vous à des types spécifiques par point de terminaison, ou transmettez un tableau eventTypes vide pour recevoir tous les événements.
webhook.test n'est envoyé que lorsque vous cliquez sur Envoyer un test ; il n'est pas émis par l'activité normale de l'espace de travail.
Enveloppe d'événement
Chaque livraison utilise la même structure de premier niveau. Les champs spécifiques à l'événement se trouvent sous data.object :
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant unique de l'événement. Même valeur que l'en-tête Styrar-Event-Id. |
type | string | Nom de l'événement (par exemple link.clicked). |
api_version | string | Version du schéma de charge utile (2026-06-22). |
created_at | string | Horodatage ISO 8601 de la création de l'événement. |
workspace.type | string | company ou personal. |
workspace.company_id | string | null | Identifiant d'entreprise lorsque workspace.type est company. |
data.object | object | Charge utile de l'événement (documentée par événement ci-dessous). |
Exemple complet de livraison (enveloppe + charge utile link.created) :
{
"id": "evt_outbox_abc123",
"type": "link.created",
"api_version": "2026-06-22",
"created_at": "2026-06-22T12:00:00.000Z",
"workspace": {
"type": "company",
"company_id": "cmxyz_company"
},
"data": {
"object": {
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"original_url": "https://example.com/sale",
"is_active": true,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": null,
"created_at": "2026-06-22T12:00:00.000Z"
}
}
}
Pour les espaces personnels, workspace.type vaut personal et workspace.company_id vaut null. La charge utile peut inclure company_id: null sur les objets de lien.
Résumé des événements
| Événement | Quand il se déclenche | Volume typique |
|---|---|---|
link.created | Un lien court est créé (POST /v1/links, création en masse ou upsert en masse) | Faible |
link.updated | Un lien court est mis à jour (PATCH /v1/links/:id, mise à jour en masse ou upsert en masse) | Faible |
link.deleted | Un lien court est supprimé de façon logicielle (DELETE /v1/links/:id ou suppression en masse) | Faible |
link.clicked | Un clic suivi est enregistré (asynchrone, après la redirection via le worker de clics) | Élevé |
link.experiment.completed | Une expérience A/B sur un lien est terminée et un gagnant est sélectionné | Faible |
campaign.created | Une campagne est créée (POST /v1/campaigns) | Faible |
post.published | Une publication sociale est publiée avec succès sur toutes les cibles de plateforme | Faible |
webhook.test | Vous exécutez Envoyer un test sur un point de terminaison | Sur demande |
link.created
Se déclenche lorsqu'un nouveau lien court est enregistré dans votre espace de travail.
Usages courants : Synchroniser les nouveaux liens vers un CRM, déclencher des automatisations de bienvenue, ou indexer les liens dans un moteur de recherche externe.
Champs de data.object :
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant du lien |
short_code | string | Code court public |
title | string | null | Titre du lien |
original_url | string | null | URL de destination |
is_active | boolean | Si le lien est actif |
company_id | string | null | Entreprise propriétaire (espace entreprise) |
campaign_id | string | null | Campagne liée, si applicable |
link_group_id | string | null | Identifiant du dossier/groupe, si applicable |
created_at | string | Heure de création ISO 8601 |
{
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"original_url": "https://example.com/sale",
"is_active": true,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": null,
"created_at": "2026-06-22T12:00:00.000Z"
}
link.updated
Se déclenche lorsqu'un lien court existant est modifié (destination, titre, tags, dossier, paramètres UTM, etc.).
Usages courants : Garder les systèmes externes synchronisés lorsqu'un lien change sans le recréer.
Champs de data.object : Identiques à link.created (voir ci-dessus).
{
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale (updated)",
"original_url": "https://example.com/sale-v2",
"is_active": true,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": "lgrp_promos",
"created_at": "2026-06-22T12:00:00.000Z"
}
link.deleted
Se déclenche lorsqu'un lien court est supprimé de façon logicielle (isActive mis à false). Le lien arrête de résoudre publiquement mais reste dans l'historique de votre espace de travail.
Usages courants : Retirer les liens des catalogues externes ou suspendre les automatisations liées à ce code court.
Champs de data.object : Même structure que link.created, avec is_active toujours à false.
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant du lien |
short_code | string | Code court au moment de la suppression |
title | string | null | Titre du lien |
original_url | string | null | URL de destination |
is_active | boolean | false après suppression logicielle |
company_id | string | null | Entreprise propriétaire |
campaign_id | string | null | Campagne liée, si applicable |
link_group_id | string | null | Identifiant du dossier/groupe, si applicable |
created_at | string | Heure de création originale |
{
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"original_url": "https://example.com/sale",
"is_active": false,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": null,
"created_at": "2026-06-22T12:00:00.000Z"
}
link.clicked
Se déclenche après qu'un clic visiteur a été enregistré. Livré de manière asynchrone (pas sur le chemin de redirection), attendez-vous donc à un léger délai en cas de forte charge.
Usages courants : Analytics de clics en temps réel, routage géographique dans votre stack, flux d'activité CRM, ou ingestion en entrepôt de données.
Confidentialité : Les charges utiles incluent des dimensions de géolocalisation et d'appareil, pas d'adresses IP brutes.
Champs de data.object :
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant du lien |
link_id | string | Identique à id |
short_code | string | Code court qui a été cliqué |
title | string | null | Titre du lien |
country | string | null | Code pays ISO (recherche géo) |
city | string | null | Ville issue de la recherche géo |
device | string | null | Classe d'appareil (par exemple mobile, desktop) |
browser | string | null | Nom du navigateur |
os | string | null | Système d'exploitation |
platform | string | null | Indice de plateforme issu de l'analyse du user agent |
referrer | string | null | URL de provenance lorsque disponible |
routing_rule_id | string | null | Règle de routage géo/appareil correspondante, si applicable |
experiment_variant_id | string | null | Identifiant de variante A/B lorsque le clic a traversé une expérience |
clicked_at | string | Heure de clic ISO 8601 |
{
"id": "clink_abc123",
"link_id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"country": "NL",
"city": "Amsterdam",
"device": "mobile",
"browser": "Chrome",
"os": "iOS",
"platform": null,
"referrer": "https://instagram.com/",
"routing_rule_id": null,
"experiment_variant_id": null,
"clicked_at": "2026-06-22T12:00:00.000Z"
}
link.experiment.completed
Se déclenche lorsqu'un test A/B sur un lien court est marqué comme terminé et qu'une variante gagnante est sélectionnée.
Usages courants : Journaliser les résultats d'expériences, mettre à jour des tableaux de bord, ou déclencher des campagnes de suivi en fonction du gagnant.
Champs de data.object :
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant de l'expérience |
link_id | string | Identifiant du lien parent |
short_code | string | null | Code court du lien parent |
status | string | completed |
assignment_mode | string | null | Mode de répartition du trafic (par exemple pondéré) |
winning_variant_id | string | null | Identifiant de la variante gagnante |
ended_at | string | null | Heure de fin ISO 8601 |
variants | array | Résultats par variante (voir ci-dessous) |
Chaque élément de variants :
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant de la variante |
label | string | Libellé lisible |
weight | number | Poids de trafic utilisé dans le test |
destination_url | string | URL vers laquelle cette variante envoyait le trafic |
clicks | number | Total des clics enregistrés pour cette variante |
{
"id": "lexp_abc123",
"link_id": "clink_abc123",
"short_code": "summer",
"status": "completed",
"assignment_mode": "weighted",
"winning_variant_id": "lvar_b",
"ended_at": "2026-06-22T14:00:00.000Z",
"variants": [
{
"id": "lvar_a",
"label": "Control",
"weight": 50,
"destination_url": "https://example.com/a",
"clicks": 120
},
{
"id": "lvar_b",
"label": "Variant B",
"weight": 50,
"destination_url": "https://example.com/b",
"clicks": 184
}
]
}
campaign.created
Se déclenche lorsqu'une nouvelle campagne est créée dans votre espace de travail.
Usages courants : Provisionner des dossiers de campagne dans des outils externes, démarrer des workflows d'attribution, ou notifier des chargés de compte.
Champs de data.object :
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant de la campagne |
name | string | Nom de la campagne |
description | string | null | Description de la campagne |
company_id | string | null | Entreprise propriétaire |
user_id | string | null | Utilisateur créateur (campagnes personnelles) |
brand_id | string | null | Portée de marque lorsque définie |
created_at | string | Heure de création ISO 8601 |
{
"id": "ccamp_abc123",
"name": "Summer launch",
"description": "Q2 product push",
"company_id": "cmxyz_company",
"user_id": null,
"brand_id": "cbrand_abc",
"created_at": "2026-06-22T12:00:00.000Z"
}
post.published
Se déclenche lorsqu'une publication planifiée ou immédiate est publiée avec succès sur toutes les cibles de plateforme configurées.
Usages courants : Notifier les systèmes en aval que le contenu est en ligne, clore la boucle des automatisations de campagne, ou synchroniser l'état de publication vers un entrepôt de données.
Remarque : N'est émis que lorsque chaque cible réussit. Les échecs partiels n'émettent pas cet événement aujourd'hui.
Champs de data.object :
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant de la publication |
post_id | string | Identique à id |
status | string | PUBLISHED |
company_id | string | null | Entreprise propriétaire |
user_id | string | null | Utilisateur propriétaire (espace personnel) |
brand_id | string | null | Portée de marque lorsque définie |
campaign_id | string | null | Campagne liée lorsque définie |
published_at | string | Heure de publication ISO 8601 |
platform_count | number | Nombre de cibles de plateforme sur la publication |
{
"id": "cpost_abc123",
"post_id": "cpost_abc123",
"status": "PUBLISHED",
"company_id": "cmxyz_company",
"user_id": null,
"brand_id": "cbrand_abc",
"campaign_id": "ccamp_abc123",
"published_at": "2026-06-22T12:00:00.000Z",
"platform_count": 3
}
webhook.test
Ping synthétique envoyé uniquement lorsque vous cliquez sur Envoyer un test dans le tableau de bord ou que vous appelez POST /v1/webhooks/endpoints/:id/test.
Usages courants : Valider votre URL de réception, le TLS, la vérification de signature et la gestion des réponses avant de passer en production.
Champs de data.object :
| Champ | Type | Description |
|---|---|---|
endpoint_id | string | Point de terminaison qui a reçu le test |
message | string | Message fixe : Styrar webhook test ping |
{
"endpoint_id": "wh_ep_abc123",
"message": "Styrar webhook test ping"
}
Exemples d'API
Lister les points de terminaison
Authorization: Bearer sty_live_your_api_key[
{
"id": "wh_ep_abc123",
"url": "https://your-app.com/webhooks/styrar",
"description": "Production CRM sync",
"enabled": true,
"eventTypes": ["link.clicked", "link.created"],
"secretPrefix": "whsec_l",
"companyId": "cmxyz_company",
"userId": null,
"disabledAt": null,
"createdAt": "2026-06-22T12:00:00.000Z",
"updatedAt": "2026-06-22T12:00:00.000Z"
}
]Recevoir un événement sur votre serveur
Lorsqu'un événement abonné se déclenche, Styrar envoie un POST à l'URL de votre point de terminaison. Voici la charge utile que reçoit votre gestionnaire :
Content-Type: application/json
Styrar-Event-Id: evt_outbox_abc123
Styrar-Event-Type: link.clicked
Styrar-Signature: t=1719052800,v1=8f4b2c1a9e0d3f7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3
User-Agent: Styrar-Webhooks/1.0
{
"id": "evt_outbox_abc123",
"type": "link.clicked",
"api_version": "2026-06-22",
"created_at": "2026-06-22T12:00:00.000Z",
"workspace": {
"type": "company",
"company_id": "cmxyz_company"
},
"data": {
"object": {
"id": "clink_abc123",
"link_id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"country": "NL",
"city": "Amsterdam",
"device": "mobile",
"browser": "Chrome",
"os": "iOS",
"referrer": "https://instagram.com/",
"routing_rule_id": null,
"experiment_variant_id": null,
"clicked_at": "2026-06-22T12:00:00.000Z"
}
}
}{
"received": true
}Le corps de votre réponse peut être vide. Renvoyez n'importe quel statut 2xx après avoir vérifié la signature et accepté l'événement. Styrar relance en cas de réponse non-2xx.
Charge utile du ping de test
Une action Envoyer un test livre webhook.test avec une charge utile plus petite :
Content-Type: application/json
Styrar-Event-Id: evt_test_abc123
Styrar-Event-Type: webhook.test
Styrar-Signature: t=1719052800,v1=...
{
"id": "evt_test_abc123",
"type": "webhook.test",
"api_version": "2026-06-22",
"created_at": "2026-06-22T12:00:00.000Z",
"workspace": {
"type": "company",
"company_id": "cmxyz_company"
},
"data": {
"object": {
"endpoint_id": "wh_ep_abc123",
"message": "Styrar webhook test ping"
}
}
}Lister les livraisons récentes
Authorization: Bearer sty_live_your_api_key[
{
"id": "wh_del_abc123",
"endpointId": "wh_ep_abc123",
"outboxEventId": "wh_out_abc123",
"eventType": "link.clicked",
"status": "delivered",
"attemptCount": 1,
"lastStatusCode": 200,
"lastError": null,
"durationMs": 142,
"nextAttemptAt": null,
"deliveredAt": "2026-06-22T12:00:01.000Z",
"createdAt": "2026-06-22T12:00:00.500Z"
}
]Gérer les points de terminaison
GET /v1/webhooks/endpoints?companyId={id}
POST /v1/webhooks/endpoints
GET /v1/webhooks/endpoints/:id
PATCH /v1/webhooks/endpoints/:id
DELETE /v1/webhooks/endpoints/:id
POST /v1/webhooks/endpoints/:id/test
POST /v1/webhooks/endpoints/:id/rotate-secret
| Champ | Description |
|---|---|
url | URL de callback HTTPS |
description | Libellé optionnel |
eventTypes | Tableau des types d'événements abonnés ; vide signifie tous les événements |
enabled | true par défaut |
Le secret de signature (whsec_live_… / whsec_test_…) est renvoyé exactement une fois à la création et lors de rotate-secret. Vous pouvez enregistrer jusqu'à 25 points de terminaison par portée d'espace de travail.
Livraisons
GET /v1/webhooks/deliveries?endpointId={id}
GET /v1/webhooks/deliveries/:id
POST /v1/webhooks/deliveries/:id/retry
Chaque ligne de livraison suit status, attemptCount, nextAttemptAt, lastStatusCode, lastError et deliveredAt. Examinez les échecs dans le tableau de bord sous Paramètres → Webhooks ou relancez via l'API.
Format de livraison
Chaque événement réel est un POST HTTP vers votre URL de callback. Les en-têtes et le corps sont présentés dans Recevoir un événement sur votre serveur ci-dessus.
| En-tête | Description |
|---|---|
Styrar-Event-Id | Identifiant unique de l'événement (utilisez-le pour la déduplication) |
Styrar-Event-Type | par exemple link.clicked |
Styrar-Signature | t={unix_ts},v1={hmac_sha256_hex} |
User-Agent | Styrar-Webhooks/1.0 |
Champs de l'enveloppe :
| Champ | Description |
|---|---|
id | Identifiant de l'événement (correspond à Styrar-Event-Id) |
type | Chaîne de type d'événement |
api_version | Version du schéma de charge utile |
created_at | Horodatage ISO 8601 |
workspace | Portée company ou personal |
data.object | Charge utile spécifique à l'événement |
Les charges utiles de clics incluent des dimensions de géolocalisation et d'appareil, pas d'adresses IP brutes.
Vérifier les signatures
La signature suit un schéma de type Stripe. Elle signe "{timestamp}.{raw_body}" avec HMAC-SHA256 en utilisant le secret de votre point de terminaison.
- Analysez
Styrar-Signaturepour en extrairet(horodatage unix) etv1(condensé hexadécimal). - Rejetez si
test hors de votre tolérance (nous recommandons 5 minutes). - Calculez le condensé attendu et comparez-le avec
v1en utilisant une vérification en temps constant.
import crypto from 'node:crypto'
function verifyStyrarWebhook(secret, signatureHeader, rawBody, toleranceSeconds = 300) {
const parts = Object.fromEntries(
signatureHeader.split(',').map((part) => part.trim().split('=')),
)
const timestamp = Number(parts.t)
const receivedDigest = parts.v1 || ''
if (!Number.isFinite(timestamp)) return false
if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false
const expectedDigest = crypto
.createHmac('sha256', secret)
.update(\`${timestamp}.${rawBody}\`)
.digest('hex')
try {
return crypto.timingSafeEqual(
Buffer.from(expectedDigest, 'utf8'),
Buffer.from(receivedDigest, 'utf8'),
)
} catch {
return false
}
}
Vérifiez toujours par rapport au corps brut de la requête avant d'analyser le JSON.
Fiabilité
- Les livraisons sont au moins une fois. Dédupliquez en utilisant
Styrar-Event-Idou l'idde l'enveloppe. - Les livraisons en échec sont relancées avec un backoff exponentiel jusqu'au succès ou au nombre maximal de tentatives.
- Si votre serveur renvoie HTTP 410, Styrar désactive automatiquement le point de terminaison.
- Répondez avec un code 2xx dès que vous avez accepté l'événement ; traitez le travail lourd de manière asynchrone.
Limites
- HTTPS requis en production pour les URL de callback.
- 25 points de terminaison par portée d'espace de travail personnel ou entreprise.
- Les secrets de signature ne sont affichés qu'une fois à la création et lors de la rotation ; stockez-les dans votre gestionnaire de secrets.
Liens utiles
- Pixel de conversion — suivez les conversions sur des pages de destination que vous ne contrôlez pas
- Liens courts et QR dans le centre d'aide
- Clés API et applications connectées