Kadens logoKadens logoKadens
  • Découvrir
  • Prix
ConnexionCommencer
Kadens logoKadens logoKadens

Enseignement

  1. Premiers pas
  2. Académie
  3. Certificats
  4. Apprentissage
  5. Cours

Argent

  1. Abonnements
  2. Finances
  3. Billets

Agenda

  1. Événements
  2. Travail

Personnes

  1. Communauté
  2. E-mailing
  3. Formulaires
  4. Candidatures
  5. Communautés

Plateforme

  1. Mon site
  2. Découvrir
  3. Compte

Développeurs

  1. Vue d'ensemble
  2. Clés API et autorisations
  3. Widgets pour site web
  4. Webhooks
  5. Assistants IA (MCP)
  6. API REST
Vous ne trouvez pas ce que vous cherchez ?Recherchez à nouveau··Parlez-nous
Kadens logoKadens logoKadens

Là où les danseurs se connectent, apprennent et grandissent

Produit

  • Découvrir
  • Cours
  • Événements
  • Communautés
  • Mentorat

Pour les entreprises

  • Kadens pour enseigner
  • Kadens pour les événements
  • Kadens pour les formulaires
  • Kadens pour les certificats
  • Crée ton site
  • Tarifs
  • Réserve une démo en direct

Ressources

  • Centre d'aide
  • Nouveautés
  • Développeurs
  • Support

Entreprise

  • Contact
  • Instagram
  • Politique de confidentialité
  • Conditions d'utilisation
  • Politique des cookies
Centre d'aideContact
Parcourir la documentation · Webhooks

Enseignement

  1. Premiers pas
  2. Académie
  3. Certificats
  4. Apprentissage
  5. Cours

Argent

  1. Abonnements
  2. Finances
  3. Billets

Agenda

  1. Événements
  2. Travail

Personnes

  1. Communauté
  2. E-mailing
  3. Formulaires
  4. Candidatures
  5. Communautés

Plateforme

  1. Mon site
  2. Découvrir
  3. Compte

Développeurs

  1. Vue d'ensemble
  2. Clés API et autorisations
  3. Widgets pour site web
  4. Webhooks
  5. Assistants IA (MCP)
  6. API REST
  1. Centre d'aide
  2. Développeurs
  3. Webhooks pour les développeurs

Webhooks pour les développeurs

Kadens envoie une requête HTTPS à votre point de terminaison chaque fois que quelque chose se passe dans votre compte. Chaque requête est signée, renvoyée jusqu'à sa réussite et listée dans votre journal des envois.

·9 min
Sur cette page
  1. Ce qu'est un webhook
  2. Démarrage rapide
  3. Tester sans serveur
  4. Corps de la requête
  5. Vérifier les signatures
  6. Gérer les événements en toute sécurité
  7. Nouvelles tentatives et limites
  8. Données personnelles
  9. Gérer les endpoints
  10. Catalogue des événements
  11. Dépannage
  12. Et maintenant ?

Ce qu'est un webhook

Un webhook est un message que Kadens envoie à une adresse web que vous choisissez chaque fois qu'un événement se produit sur votre compte : une commande est payée, un billet est émis, quelqu'un se présente à l'entrée. Votre système le reçoit et fait le reste, par exemple ajouter l'acheteur à votre liste de diffusion ou mettre à jour une feuille de calcul.

Ce dont vous avez besoin

  • Une adresse HTTPS publique qui accepte les requêtes POST. Pas encore de serveur ? Le récepteur de test vous en donne une en un clic.
  • L'accès à Intégrations dans votre tableau de bord Kadens.

Vous utilisez Zapier, Make, n8n ou votre propre code ? Ils peuvent créer et supprimer des endpoints pour vous avec une clé API, via l'API REST.

En savoir plus sur les REST hooks

Démarrage rapide

  1. 1

    Ajouter un endpoint

    Ouvrez Webhooks dans votre tableau de bord, choisissez Ajouter un endpoint, collez votre adresse HTTPS et sélectionnez les événements qu'il doit recevoir. Copiez le secret de signature : il n'est affiché qu'une seule fois.
  2. 2

    Envoyer un événement de test

    Sur la page de l'endpoint, choisissez Envoyer un événement de test. Kadens envoie un événement d'exemple, signé comme un vrai, avec livemode à false et chaque id marqué comme id de test.
  3. 3

    Vérifier la signature

    Avant de faire confiance au corps de la requête, vérifiez sa signature sur votre serveur avec le secret de signature. Copiez le code pour votre langage depuis Vérifier les signatures.
  4. 4

    Répondre avec un statut 2xx

    Répondez avec n'importe quel statut 2xx dès que l'événement est enregistré. Toute autre réponse, ou l'absence de réponse, compte comme un échec et la livraison est retentée.
Configurez-le maintenant
Connectez-vous et ouvrez Webhooks pour ajouter votre premier endpoint.
Ouvrir Webhooks

Tester sans serveur

Kadens peut héberger un récepteur de test pour vous. Choisissez Essayer avec un récepteur de test sur la page Webhooks : Kadens crée une adresse de test privée, connecte un endpoint qui reçoit chaque événement et lui envoie un événement de test. Chaque requête apparaît sur la page de cet endpoint en quelques secondes, avec ses en-têtes, son corps et si la signature correspondait.

Le récepteur de test conserve les 50 dernières requêtes pendant 7 jours, et les premiers 64 Ko de chaque corps.

Observez l'arrivée d'un webhook signé
Connectez-vous, ouvrez Webhooks et choisissez Essayer avec un récepteur de test.
Ouvrir Webhooks

Corps de la requête

Chaque événement arrive dans la même enveloppe JSON, version 2026-10-01. L'événement lui-même se trouve dans data.

ChampTypeDescription
idstringId unique de l'événement, commençant par evt_. La même valeur arrive dans l'en-tête webhook-id et reste identique à chaque nouvelle tentative, renvoi et relecture.
typestringLe type d'événement, par exemple order.paid. Le catalogue d'événements les liste tous.
versionstringLa version de contrat que suit la charge utile. Aujourd'hui, c'est 2026-10-01.
occurred_atstringLe moment où c'est arrivé, sous forme de date et heure ISO 8601.
account{ id, name }Le compte Kadens auquel appartient l'événement : son id et son nom.
subject.typestringLe type d'enregistrement concerné par l'événement, par exemple order, booking ou subscription.
subject.idstringL'id de cet enregistrement. Chaque événement concernant le même enregistrement porte le même id.
subject.sequenceinteger | nullUn nombre qui augmente à chaque modification du même enregistrement, pour savoir quel événement est le plus récent. null quand l'enregistrement n'a pas d'ordre de modifications.
correlation_idstring | nullRelie les événements issus de la même action, quand il y en a une. Sinon null.
livemodebooleantrue pour une activité réelle. false pour les événements de test, dont les id sont aussi marqués comme id de test.
dataobjectL'événement lui-même. Ses champs dépendent du type : ouvrez un exemple dans le catalogue d'événements.
Un corps de requête complet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
{
  "id": "evt_2f8a1c7e9b3d4e5fa6c7d8e9f0a1b2c3",
  "type": "order.paid",
  "version": "2026-10-01",
  "occurred_at": "2026-10-01T10:00:00Z",
  "account": {
    "id": "ent_1a0f",
    "name": "Barcelona Salsa Studio"
  },
  "subject": {
    "type": "order",
    "id": "ord_91ac04",
    "sequence": 2
  },
  "correlation_id": null,
  "livemode": true,
  "data": {
    "order": {
      "id": "ord_91ac04",
      "status": "paid",
      "created_at": "2026-10-01T09:58:02Z",
      "paid_at": "2026-10-01T10:00:00Z",
      "event": {
        "id": "evt_7f3c2a",
        "name": "Salsa Congress Barcelona 2026"
      },
      "totals": {
        "gross": {
          "amount": 12000,
          "currency": "EUR"
        },
        "fees": {
          "amount": 600,
          "currency": "EUR"
        },
        "net": {
          "amount": 11400,
          "currency": "EUR"
        },
        "tax": {
          "amount": 2083,
          "currency": "EUR"
        }
      },
      "buyer": {
        "entity_id": "ent_5b21",
        "name": "Lucia Martin",
        "email": "lucia@example.com"
      },
      "lines": [
        {
          "ticket_type_id": "tt_full_pass",
          "name": "Full pass",
          "quantity": 1,
          "unit_price": {
            "amount": 12000,
            "currency": "EUR"
          }
        }
      ]
    }
  }
}

Vérifier les signatures

Les requêtes suivent la spécification Standard Webhooks : les bibliothèques officielles les vérifient sans code propre à Kadens. Vérifiez toujours le corps brut.

En-têteDescription
webhook-idUnique par événement. Utilisez-le pour ignorer une requête déjà traitée.
webhook-timestampSecondes Unix de la signature de la requête. Refusez les requêtes de plus de 300 secondes.
webhook-signatureUne ou plusieurs signatures v1 séparées par des espaces. Pendant 24 heures après le renouvellement d'un secret, l'ancien et le nouveau signent tous les deux.
Gardez le secret de signature privé
Chaque endpoint a son propre secret de signature, commençant par whsec_. Stockez-le dans une variable d'environnement, jamais dans votre code ni dans un dépôt.
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// npm install standardwebhooks
import { Webhook } from 'standardwebhooks';

const wh = new Webhook(process.env.KADENS_WEBHOOK_SECRET);

// Use the RAW request body, exactly as received (not re-serialized JSON).
app.post('/webhooks/kadens', express.raw({ type: 'application/json' }), (req, res) => {
    try {
        const event = wh.verify(req.body.toString('utf8'), req.headers);
        // event.type, event.data
        res.sendStatus(200);
    } catch {
        res.sendStatus(400);
    }
});

Gérer les événements en toute sécurité

Le même événement peut arriver deux fois, en retard ou dans le désordre. Trois habitudes rendent votre récepteur sûr.

Traiter chaque événement une seule fois

Stockez le webhook-id de chaque événement que vous traitez. Si le même arrive à nouveau après une nouvelle tentative, un renvoi ou une relecture, répondez 2xx et ignorez-le.

Mettre les événements en ordre

Une nouvelle tentative peut faire arriver un événement plus ancien après un plus récent. Quand subject.sequence est défini, conservez le plus élevé que vous avez traité pour chaque subject.id et ignorez tout ce qui est inférieur.

Répondez d'abord, travaillez ensuite

Répondez 2xx dès que l'événement est enregistré en toute sécurité, puis effectuez le travail long en arrière-plan. Une réponse qui prend plus de 10 secondes compte comme un échec et est retentée.

Nouvelles tentatives et limites

Répondez avec un statut 2xx pour confirmer un envoi. Tout autre statut, ou l'absence de réponse, compte comme un échec.

Un envoi en échec est renvoyé 10 fois de plus avec des délais croissants, sur environ 3 jours. Vous pouvez aussi le renvoyer ou rejouer une période depuis votre tableau de bord.

Si votre endpoint répond 410 Gone, il est désactivé immédiatement et ne reçoit plus rien jusqu'à ce que vous le réactiviez.

Un point de terminaison en échec pendant 5 jours sans un seul succès est désactivé, et vous êtes prévenu.

Les événements et les envois sont conservés 30 jours.

Chaque compte peut avoir jusqu'à 10 points de terminaison à lui. Ceux que créent Zapier, Make ou n8n ne comptent pas dans cette limite et ont leur propre plafond de 50.

Quand chaque nouvelle tentative a lieu

Nouvelle tentativeQuand
Nouvelle tentative 130 secondes après la tentative précédente
Nouvelle tentative 22 minutes après la tentative précédente
Nouvelle tentative 310 minutes après la tentative précédente
Nouvelle tentative 430 minutes après la tentative précédente
Nouvelle tentative 51 heure après la tentative précédente
Nouvelle tentative 63 heures après la tentative précédente
Nouvelle tentative 76 heures après la tentative précédente
Nouvelle tentative 812 heures après la tentative précédente
Nouvelle tentative 924 heures après la tentative précédente
Nouvelle tentative 1024 heures après la tentative précédente

Données personnelles

Les noms et adresses e-mail des acheteurs, détenteurs de billets et participants sont des données personnelles. Par défaut, Kadens retire ces champs des données avant l'envoi, de sorte que l'endpoint reçoit l'événement sans eux.

Pour les recevoir, modifiez l'endpoint et activez Inclure les données personnelles. Une fois que les données quittent Kadens, les protéger de votre côté est de votre responsabilité.

Gérer les endpoints

ActionDescription
Renouveler le secretCrée un nouveau secret de signature. L'ancien continue de signer pendant 24 heures, pour que vous puissiez mettre à jour votre serveur sans manquer un événement.
RenvoyerRenvoie chaque événement d'une plage de dates que l'endpoint a manqué ou n'a pas reçu, jusqu'à 30 jours en arrière.
RenvoyerRenvoie une livraison, depuis le journal de livraisons de l'endpoint.
Envoyer un événement de testEnvoie un exemple de n'importe quel type d'événement à cet endpoint uniquement, marqué comme test.
Désactiver / ActiverArrête les livraisons jusqu'à ce que vous réactiviez l'endpoint. Après l'avoir réactivé, rejouez la plage qu'il a manquée.

Un endpoint qui échoue pendant 5 jours sans un seul succès est désactivé automatiquement, et vous êtes notifié.

Catalogue des événements

Abonnez un point de terminaison aux événements dont il a besoin. Chacun montre les données qu'il transporte.

Commandes

order.paid

Une commande a été payée.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{
  "order": {
    "id": "ord_91ac04",
    "status": "paid",
    "created_at": "2026-10-01T09:58:02Z",
    "paid_at": "2026-10-01T10:00:00Z",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    },
    "totals": {
      "gross": {
        "amount": 12000,
        "currency": "EUR"
      },
      "fees": {
        "amount": 600,
        "currency": "EUR"
      },
      "net": {
        "amount": 11400,
        "currency": "EUR"
      },
      "tax": {
        "amount": 2083,
        "currency": "EUR"
      }
    },
    "buyer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "lines": [
      {
        "ticket_type_id": "tt_full_pass",
        "name": "Full pass",
        "quantity": 1,
        "unit_price": {
          "amount": 12000,
          "currency": "EUR"
        }
      }
    ]
  }
}
order.refunded

Une commande a été remboursée, totalement ou partiellement.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{
  "order": {
    "id": "ord_91ac04",
    "status": "refunded",
    "created_at": "2026-10-01T09:58:02Z",
    "paid_at": "2026-10-01T10:00:00Z",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    },
    "totals": {
      "gross": {
        "amount": 12000,
        "currency": "EUR"
      },
      "fees": {
        "amount": 600,
        "currency": "EUR"
      },
      "net": {
        "amount": 11400,
        "currency": "EUR"
      },
      "tax": {
        "amount": 2083,
        "currency": "EUR"
      }
    },
    "buyer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "lines": [
      {
        "ticket_type_id": "tt_full_pass",
        "name": "Full pass",
        "quantity": 1,
        "unit_price": {
          "amount": 12000,
          "currency": "EUR"
        }
      }
    ]
  },
  "refund": {
    "id": "ref_0c7d",
    "amount": {
      "amount": 12000,
      "currency": "EUR"
    },
    "refunded_at": "2026-10-03T08:12:40Z"
  }
}
checkout.abandoned

Un acheteur a commencé un paiement et est parti sans payer.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "checkout": {
    "id": "pin_3c8e21",
    "item": {
      "kind": "course",
      "id": "crs_9a20",
      "name": "Bachata Foundations"
    },
    "buyer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "amount": {
      "amount": 9900,
      "currency": "EUR"
    },
    "started_at": "2026-10-01T09:40:00Z"
  },
  "abandoned_at": "2026-10-01T10:40:00Z"
}

Billets

ticket.issued

Un billet a été émis à son titulaire.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "ticket": {
    "id": "tkt_33d0e1",
    "order_id": "ord_91ac04",
    "status": "active",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    },
    "ticket_type": {
      "id": "tt_full_pass",
      "name": "Full pass"
    },
    "holder": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "issued_at": "2026-10-01T10:00:01Z"
  }
}
ticket.reassigned

Un billet a été transféré à un autre titulaire.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  "ticket": {
    "id": "tkt_33d0e1",
    "order_id": "ord_91ac04",
    "status": "active",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    },
    "ticket_type": {
      "id": "tt_full_pass",
      "name": "Full pass"
    },
    "holder": {
      "entity_id": "ent_8e40",
      "name": "Marco Rossi",
      "email": "marco@example.com"
    },
    "issued_at": "2026-10-01T10:00:01Z"
  },
  "previous_holder": {
    "entity_id": "ent_5b21",
    "name": "Lucia Martin",
    "email": "lucia@example.com"
  },
  "reassigned_at": "2026-10-02T17:30:00Z"
}
ticket.canceled

Un billet a été annulé.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  "ticket": {
    "id": "tkt_33d0e1",
    "order_id": "ord_91ac04",
    "status": "canceled",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    },
    "ticket_type": {
      "id": "tt_full_pass",
      "name": "Full pass"
    },
    "holder": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "issued_at": "2026-10-01T10:00:01Z"
  },
  "canceled_at": "2026-10-04T12:00:00Z"
}

Participants

attendee.registered

Un participant a été inscrit à un événement.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "attendee": {
    "ticket_id": "tkt_33d0e1",
    "entity_id": "ent_5b21",
    "name": "Lucia Martin",
    "email": "lucia@example.com",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    }
  },
  "registered_at": "2026-10-01T10:05:00Z"
}
attendee.checked_in

Un participant a été enregistré à l'entrée.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "attendee": {
    "ticket_id": "tkt_33d0e1",
    "entity_id": "ent_5b21",
    "name": "Lucia Martin",
    "email": "lucia@example.com",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    }
  },
  "checked_in_at": "2026-10-10T19:02:11Z"
}
attendee.check_in_reverted

Un enregistrement à l'entrée a été annulé.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "attendee": {
    "ticket_id": "tkt_33d0e1",
    "entity_id": "ent_5b21",
    "name": "Lucia Martin",
    "email": "lucia@example.com",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    }
  },
  "reverted_at": "2026-10-10T19:04:30Z"
}
attendee.no_show

Un détenteur de billet ne s'est pas enregistré avant la fin de la séance.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "attendee": {
    "ticket_id": "tkt_33d0e1",
    "entity_id": "ent_5b21",
    "name": "Lucia Martin",
    "email": "lucia@example.com",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona 2026"
    }
  },
  "finalized_at": "2026-10-10T23:30:00Z"
}

Événements

event.ended

Un de vos événements est terminé.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "edition": {
    "id": "eed_2b71",
    "name": "Salsa Congress Barcelona 2026",
    "event": {
      "id": "evt_7f3c2a",
      "name": "Salsa Congress Barcelona"
    },
    "starts_at": "2026-10-09T16:00:00Z",
    "ends_at": "2026-10-11T22:00:00Z",
    "timezone": "Europe/Madrid"
  },
  "ended_at": "2026-10-11T22:00:00Z"
}

Réservations

booking.confirmed

Une réservation à une séance a été confirmée.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "booking": {
    "id": "reg_8e17c3",
    "status": "reserved",
    "session": {
      "id": "ses_62f1a8",
      "status": "scheduled",
      "program": {
        "id": "prg_0c4e",
        "name": "Contemporary Technique, Level 2"
      },
      "starts_at": "2026-10-08T17:00:00Z",
      "ends_at": "2026-10-08T18:30:00Z",
      "timezone": "Europe/Madrid",
      "location": {
        "delivery_mode": "in_person",
        "room": {
          "id": "room_a1",
          "name": "Studio A"
        }
      }
    },
    "attendee": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "confirmed_at": "2026-10-01T10:00:00Z"
}
booking.declined

Une demande de réservation a été refusée.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "booking": {
    "id": "reg_8e17c3",
    "status": "cancelled",
    "session": {
      "id": "ses_62f1a8",
      "status": "scheduled",
      "program": {
        "id": "prg_0c4e",
        "name": "Contemporary Technique, Level 2"
      },
      "starts_at": "2026-10-08T17:00:00Z",
      "ends_at": "2026-10-08T18:30:00Z",
      "timezone": "Europe/Madrid",
      "location": {
        "delivery_mode": "in_person",
        "room": {
          "id": "room_a1",
          "name": "Studio A"
        }
      }
    },
    "attendee": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "declined_at": "2026-10-01T10:00:00Z"
}
booking.canceled

Une réservation a été annulée ou a expiré.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
  "booking": {
    "id": "reg_8e17c3",
    "status": "cancelled",
    "session": {
      "id": "ses_62f1a8",
      "status": "scheduled",
      "program": {
        "id": "prg_0c4e",
        "name": "Contemporary Technique, Level 2"
      },
      "starts_at": "2026-10-08T17:00:00Z",
      "ends_at": "2026-10-08T18:30:00Z",
      "timezone": "Europe/Madrid",
      "location": {
        "delivery_mode": "in_person",
        "room": {
          "id": "room_a1",
          "name": "Studio A"
        }
      }
    },
    "attendee": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "reason": "canceled",
  "canceled_at": "2026-10-03T09:12:00Z"
}
booking.moved

Une réservation a été déplacée vers une autre séance.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{
  "booking": {
    "id": "reg_8e17c3",
    "status": "reserved",
    "session": {
      "id": "ses_7b90d2",
      "status": "scheduled",
      "program": {
        "id": "prg_0c4e",
        "name": "Contemporary Technique, Level 2"
      },
      "starts_at": "2026-10-15T17:00:00Z",
      "ends_at": "2026-10-15T18:30:00Z",
      "timezone": "Europe/Madrid",
      "location": {
        "delivery_mode": "in_person",
        "room": {
          "id": "room_a1",
          "name": "Studio A"
        }
      }
    },
    "attendee": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "previous_session": {
    "id": "ses_62f1a8",
    "status": "scheduled",
    "program": {
      "id": "prg_0c4e",
      "name": "Contemporary Technique, Level 2"
    },
    "starts_at": "2026-10-08T17:00:00Z",
    "ends_at": "2026-10-08T18:30:00Z",
    "timezone": "Europe/Madrid",
    "location": {
      "delivery_mode": "in_person",
      "room": {
        "id": "room_a1",
        "name": "Studio A"
      }
    }
  },
  "moved_at": "2026-10-04T11:40:00Z"
}
booking.no_show

Un participant réservé ne s'est pas enregistré avant la fin de la séance.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "booking": {
    "id": "reg_8e17c3",
    "status": "reserved",
    "session": {
      "id": "ses_62f1a8",
      "status": "scheduled",
      "program": {
        "id": "prg_0c4e",
        "name": "Contemporary Technique, Level 2"
      },
      "starts_at": "2026-10-08T17:00:00Z",
      "ends_at": "2026-10-08T18:30:00Z",
      "timezone": "Europe/Madrid",
      "location": {
        "delivery_mode": "in_person",
        "room": {
          "id": "room_a1",
          "name": "Studio A"
        }
      }
    },
    "attendee": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "finalized_at": "2026-10-08T19:30:00Z"
}
session.canceled

Une séance programmée a été annulée.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  "session": {
    "id": "ses_62f1a8",
    "status": "cancelled",
    "program": {
      "id": "prg_0c4e",
      "name": "Contemporary Technique, Level 2"
    },
    "starts_at": "2026-10-08T17:00:00Z",
    "ends_at": "2026-10-08T18:30:00Z",
    "timezone": "Europe/Madrid",
    "location": {
      "delivery_mode": "in_person",
      "room": {
        "id": "room_a1",
        "name": "Studio A"
      }
    }
  },
  "cancellation_reason": "Teacher unwell",
  "canceled_at": "2026-10-07T08:00:00Z"
}
session.rescheduled

Une séance programmée a été déplacée à un autre horaire.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "session": {
    "id": "ses_62f1a8",
    "status": "scheduled",
    "program": {
      "id": "prg_0c4e",
      "name": "Contemporary Technique, Level 2"
    },
    "starts_at": "2026-10-08T18:00:00Z",
    "ends_at": "2026-10-08T19:30:00Z",
    "timezone": "Europe/Madrid",
    "location": {
      "delivery_mode": "in_person",
      "room": {
        "id": "room_a1",
        "name": "Studio A"
      }
    }
  },
  "previous_starts_at": "2026-10-08T17:00:00Z",
  "previous_ends_at": "2026-10-08T18:30:00Z",
  "rescheduled_at": "2026-10-06T15:20:00Z"
}
pack.credits_low

Un forfait de cours est descendu sous son seuil bas de crédits.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "pack": {
    "id": "pkp_1e90",
    "product": {
      "id": "pck_10cls",
      "name": "10 class pack"
    },
    "holder": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "credits_remaining": 2,
    "credits_total": 10,
    "expires_at": "2027-01-31T23:59:59Z"
  },
  "threshold": 2,
  "crossed_at": "2026-10-08T17:00:05Z"
}

Inscriptions

enrollment.created

Un étudiant a été inscrit à un cours.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "enrollment": {
    "id": "crs_9a20:ent_31c7",
    "course": {
      "id": "crs_9a20",
      "name": "Bachata Foundations"
    },
    "edition": {
      "id": "ced_4b1e",
      "name": "January 2027",
      "starts_at": "2027-01-11T18:00:00Z",
      "ends_at": "2027-03-29T20:00:00Z",
      "timezone": "Europe/Madrid"
    },
    "student": {
      "entity_id": "ent_31c7",
      "name": "Lucia Fernandez",
      "email": "lucia@example.com"
    },
    "source": "subscription"
  },
  "enrolled_at": "2026-12-02T10:15:00Z"
}
enrollment.ended

L'inscription d'un étudiant à un cours a pris fin.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "enrollment": {
    "id": "crs_9a20:ent_31c7",
    "course": {
      "id": "crs_9a20",
      "name": "Bachata Foundations"
    },
    "edition": {
      "id": "ced_4b1e",
      "name": "January 2027",
      "starts_at": "2027-01-11T18:00:00Z",
      "ends_at": "2027-03-29T20:00:00Z",
      "timezone": "Europe/Madrid"
    },
    "student": {
      "entity_id": "ent_31c7",
      "name": "Lucia Fernandez",
      "email": "lucia@example.com"
    },
    "source": "subscription"
  },
  "ended_at": "2027-02-02T10:15:00Z"
}
enrollment.moved

Un étudiant a été déplacé vers une autre édition du cours.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "enrollment": {
    "id": "crs_9a20:ent_31c7",
    "course": {
      "id": "crs_9a20",
      "name": "Bachata Foundations"
    },
    "edition": {
      "id": "ced_7d02",
      "name": "April 2027",
      "starts_at": "2027-04-12T17:00:00Z",
      "ends_at": "2027-06-28T19:00:00Z",
      "timezone": "Europe/Madrid"
    },
    "student": {
      "entity_id": "ent_31c7",
      "name": "Lucia Fernandez",
      "email": "lucia@example.com"
    },
    "source": "subscription"
  },
  "previous_edition": {
    "id": "ced_4b1e",
    "name": "January 2027",
    "starts_at": "2027-01-11T18:00:00Z",
    "ends_at": "2027-03-29T20:00:00Z",
    "timezone": "Europe/Madrid"
  },
  "moved_at": "2026-12-20T09:00:00Z"
}
lesson.completed

Un étudiant a terminé une leçon de votre cours.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  "enrollment": {
    "id": "crs_9a20:ent_31c7",
    "course": {
      "id": "crs_9a20",
      "name": "Bachata Foundations"
    },
    "edition": {
      "id": "ced_4b1e",
      "name": "January 2027",
      "starts_at": "2027-01-11T18:00:00Z",
      "ends_at": "2027-03-29T20:00:00Z",
      "timezone": "Europe/Madrid"
    },
    "student": {
      "entity_id": "ent_31c7",
      "name": "Lucia Fernandez",
      "email": "lucia@example.com"
    },
    "source": "subscription"
  },
  "lesson": {
    "id": "itm_2f81",
    "name": "Basic step and timing"
  },
  "completed_at": "2026-12-05T19:40:00Z"
}
course.completed

Un étudiant a terminé votre cours.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "enrollment": {
    "id": "crs_9a20:ent_31c7",
    "course": {
      "id": "crs_9a20",
      "name": "Bachata Foundations"
    },
    "edition": {
      "id": "ced_4b1e",
      "name": "January 2027",
      "starts_at": "2027-01-11T18:00:00Z",
      "ends_at": "2027-03-29T20:00:00Z",
      "timezone": "Europe/Madrid"
    },
    "student": {
      "entity_id": "ent_31c7",
      "name": "Lucia Fernandez",
      "email": "lucia@example.com"
    },
    "source": "subscription"
  },
  "completed_at": "2027-03-29T20:10:00Z"
}

Abonnements

subscription.created

Un client a souscrit une formule d'abonnement.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "subscription": {
    "id": "sub_4d2e9a",
    "status": "active",
    "plan": {
      "id": "plan_7a10",
      "name": "Monthly membership"
    },
    "price": {
      "id": "price_2c3b",
      "amount": {
        "amount": 4900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-10-01T00:00:00Z",
    "current_period_end": "2026-11-01T00:00:00Z",
    "cancel_at_period_end": false,
    "canceled_at": null,
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  }
}
subscription.renewed

Un abonnement a été renouvelé et son paiement a abouti.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
  "subscription": {
    "id": "sub_4d2e9a",
    "status": "active",
    "plan": {
      "id": "plan_7a10",
      "name": "Monthly membership"
    },
    "price": {
      "id": "price_2c3b",
      "amount": {
        "amount": 4900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-11-01T00:00:00Z",
    "current_period_end": "2026-12-01T00:00:00Z",
    "cancel_at_period_end": false,
    "canceled_at": null,
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "invoice": {
    "id": "in_1Q2w3E",
    "amount": {
      "amount": 4900,
      "currency": "EUR"
    }
  },
  "renewed_at": "2026-11-01T00:04:12Z"
}
subscription.payment_failed

Le paiement d'un abonnement a échoué.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
  "subscription": {
    "id": "sub_4d2e9a",
    "status": "past_due",
    "plan": {
      "id": "plan_7a10",
      "name": "Monthly membership"
    },
    "price": {
      "id": "price_2c3b",
      "amount": {
        "amount": 4900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-10-01T00:00:00Z",
    "current_period_end": "2026-11-01T00:00:00Z",
    "cancel_at_period_end": false,
    "canceled_at": null,
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "access_ends_at": "2026-11-08T00:04:12Z",
  "failure_code": "card_declined",
  "failed_at": "2026-11-01T00:04:12Z"
}
subscription.canceled

Un abonnement a été annulé.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
  "subscription": {
    "id": "sub_4d2e9a",
    "status": "active",
    "plan": {
      "id": "plan_7a10",
      "name": "Monthly membership"
    },
    "price": {
      "id": "price_2c3b",
      "amount": {
        "amount": 4900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-10-01T00:00:00Z",
    "current_period_end": "2026-11-01T00:00:00Z",
    "cancel_at_period_end": true,
    "canceled_at": null,
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "cancel_at_period_end": true,
  "ends_at": "2026-11-01T00:00:00Z",
  "canceled_at": "2026-10-15T09:30:00Z"
}
subscription.reactivated

Un abonnement annulé a été réactivé.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  "subscription": {
    "id": "sub_4d2e9a",
    "status": "active",
    "plan": {
      "id": "plan_7a10",
      "name": "Monthly membership"
    },
    "price": {
      "id": "price_2c3b",
      "amount": {
        "amount": 4900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-10-01T00:00:00Z",
    "current_period_end": "2026-11-01T00:00:00Z",
    "cancel_at_period_end": false,
    "canceled_at": null,
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "reactivated_at": "2026-10-20T18:00:00Z"
}
subscription.plan_changed

Un client est passé à une autre formule.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
  "subscription": {
    "id": "sub_8f01bc",
    "status": "active",
    "plan": {
      "id": "plan_9b22",
      "name": "Full bundle"
    },
    "price": {
      "id": "price_5d6e",
      "amount": {
        "amount": 8900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-10-01T00:00:00Z",
    "current_period_end": "2026-11-01T00:00:00Z",
    "cancel_at_period_end": false,
    "canceled_at": null,
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "previous_subscription_ids": [
    "sub_4d2e9a"
  ],
  "credit_applied": {
    "amount": 2450,
    "currency": "EUR"
  },
  "next_billing_at": "2026-11-15T00:00:00Z",
  "changed_at": "2026-10-15T12:00:00Z"
}
subscription.ended

Un abonnement a pris fin et son accès s'est arrêté.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "subscription": {
    "id": "sub_4d2e9a",
    "status": "canceled",
    "plan": {
      "id": "plan_7a10",
      "name": "Monthly membership"
    },
    "price": {
      "id": "price_2c3b",
      "amount": {
        "amount": 4900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-10-01T00:00:00Z",
    "current_period_end": "2026-11-01T00:00:00Z",
    "cancel_at_period_end": false,
    "canceled_at": "2026-11-01T00:00:00Z",
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "reason": "cancellation_requested",
  "ended_at": "2026-11-01T00:00:00Z"
}
subscription.trial_ending

L'essai gratuit d'un abonné se termine dans quelques jours.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  "subscription": {
    "id": "sub_4d2e9a",
    "status": "trialing",
    "plan": {
      "id": "plan_7a10",
      "name": "Monthly membership"
    },
    "price": {
      "id": "price_2c3b",
      "amount": {
        "amount": 4900,
        "currency": "EUR"
      },
      "interval": "month",
      "interval_count": 1
    },
    "current_period_start": "2026-10-01T00:00:00Z",
    "current_period_end": "2026-11-01T00:00:00Z",
    "cancel_at_period_end": false,
    "canceled_at": null,
    "customer": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "trial_ends_at": "2026-10-15T00:00:00Z"
}

Certificats

certificate.issued

Un certificat a été délivré à son titulaire.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "certificate": {
    "id": "icrt_4d19b2",
    "number": "KD-2026-000142",
    "status": "active",
    "certificate": {
      "id": "crt_7a02",
      "name": "Contemporary Foundations"
    },
    "template": {
      "id": "tpl_31c8",
      "name": "2026 cohort"
    },
    "recipient": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "issued_at": "2026-10-01T10:00:00Z",
    "expires_at": null,
    "revoked_at": null,
    "verification_url": "https://kadens.io/verify-certificate/KD-2026-000142"
  }
}
certificate.revoked

Un certificat a été révoqué.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
  "certificate": {
    "id": "icrt_4d19b2",
    "number": "KD-2026-000142",
    "status": "revoked",
    "certificate": {
      "id": "crt_7a02",
      "name": "Contemporary Foundations"
    },
    "template": {
      "id": "tpl_31c8",
      "name": "2026 cohort"
    },
    "recipient": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "issued_at": "2026-10-01T10:00:00Z",
    "expires_at": null,
    "revoked_at": "2026-11-12T08:30:00Z",
    "verification_url": "https://kadens.io/verify-certificate/KD-2026-000142"
  },
  "reason": "Issued to the wrong student",
  "revoked_at": "2026-11-12T08:30:00Z"
}

Versements

payout.paid

Un versement est arrivé sur votre compte bancaire.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
{
  "payout": {
    "id": "po_1Q2w3E4r",
    "status": "paid",
    "amount": {
      "amount": 113400,
      "currency": "EUR"
    },
    "arrival_date": "2026-10-06T00:00:00Z"
  },
  "paid_at": "2026-10-06T06:14:09Z"
}
payout.failed

Un versement a échoué et l'argent n'a pas été transféré.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "payout": {
    "id": "po_1Q2w3E4r",
    "status": "failed",
    "amount": {
      "amount": 113400,
      "currency": "EUR"
    },
    "arrival_date": "2026-10-06T00:00:00Z"
  },
  "failure": {
    "code": "account_closed",
    "message": "The bank account has been closed."
  },
  "failed_at": "2026-10-06T06:14:09Z"
}

Contacts

lead.captured

Un nouveau lead a été capté.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "lead": {
    "id": "lead_4a90",
    "audience_id": "aud_12f0",
    "email": "lucia@example.com",
    "first_name": "Lucia",
    "last_name": "Martin",
    "consent_at": "2026-10-01T09:12:00Z",
    "source": {
      "site_id": "site_77a1",
      "page_id": "page_home",
      "block_id": "blk_newsletter",
      "url": "https://salsa.example.com/"
    }
  },
  "captured_at": "2026-10-01T09:12:00Z"
}
form.submitted

Un formulaire a été envoyé.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
  "submission": {
    "id": "sub_61c2",
    "form": {
      "id": "frm_0d3e",
      "title": "Audition application",
      "type": "application"
    },
    "target": {
      "scope": "course",
      "id": "crs_19ab"
    },
    "submitter": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "answers": [
      {
        "field_id": "b2c1e8f0-3a4d-4c5e-9f60-1a2b3c4d5e6f",
        "label": "Dance experience",
        "type": "textarea",
        "value": "Five years of salsa",
        "display": "Five years of salsa"
      },
      {
        "field_id": "c3d2f9a1-4b5e-4d6f-8a71-2b3c4d5e6f70",
        "label": "Preferred role",
        "type": "select",
        "value": "follower",
        "display": "Follower"
      }
    ],
    "submitted_at": "2026-10-02T11:40:00Z"
  }
}
application.decided

Vous avez approuvé, rejeté ou mis en liste d'attente une candidature.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  "submission": {
    "id": "sub_61c2",
    "form": {
      "id": "frm_0d3e",
      "title": "Audition application",
      "type": "application"
    },
    "target": {
      "scope": "course",
      "id": "crs_19ab"
    },
    "submitter": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "submitted_at": "2026-10-02T11:40:00Z"
  },
  "decision": "approved",
  "decided_at": "2026-10-06T09:00:00Z"
}
exam.results_released

Un candidat peut désormais voir les résultats de son examen.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  "submission": {
    "id": "sub_61c2",
    "form": {
      "id": "frm_0d3e",
      "title": "Audition application",
      "type": "exam"
    },
    "target": {
      "scope": "course",
      "id": "crs_19ab"
    },
    "submitter": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "submitted_at": "2026-10-02T11:40:00Z"
  },
  "result": {
    "passed": true,
    "score_percent": 86
  },
  "released_at": "2026-10-09T12:00:00Z"
}
follower.added

Quelqu'un a commencé à vous suivre.

Exemple de données
JSON
1
2
3
4
5
6
7
8
{
  "follower": {
    "entity_id": "ent_5b21",
    "name": "Lucia Martin",
    "email": "lucia@example.com"
  },
  "followed_at": "2026-10-01T08:00:00Z"
}
community.member.joined

Un membre a rejoint l'une de vos communautés.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
{
  "membership": {
    "member": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "source": "ticket_holder"
  },
  "joined_at": "2026-10-01T10:00:02Z"
}
community.member.left

Un membre a quitté l'une de vos communautés.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
{
  "membership": {
    "member": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "source": "ticket_holder"
  },
  "reason": "ticket_released",
  "left_at": "2026-10-05T08:00:00Z"
}
channel_automation.webhook

Une automatisation a atteint une étape d’envoi de webhook pour un contact.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "automation": {
    "id": "aut_2c81f0",
    "step_id": "step_send_webhook",
    "run_id": "run_8e41d7"
  },
  "contact": {
    "id": "con_51a9e2",
    "entity_id": null,
    "username": "lucia.dances",
    "email": "lucia@example.com",
    "tag_ids": [
      "tag_vip"
    ]
  },
  "channel": {
    "type": "instagram",
    "account_id": "cha_7d02b1"
  },
  "fired_at": "2026-10-01T10:00:00Z"
}

Retours

review.submitted

Quelqu'un a laissé un avis.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "review": {
    "id": "rev_8d02",
    "rating": 5,
    "comment": "Clear, patient and fun.",
    "target": {
      "kind": "course",
      "id": "crs_9a20",
      "name": "Bachata Foundations"
    },
    "author": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "submitted_at": "2026-10-12T20:15:00Z"
}
feedback.completed

Vous avez répondu à une demande de feedback d'un étudiant.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "request": {
    "id": "fbr_51a7",
    "offering": {
      "id": "mnt_33c0",
      "name": "Video feedback on your solo"
    },
    "student": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    }
  },
  "completed_at": "2026-10-14T10:30:00Z"
}

Récompenses

reward.expiring

Une récompense que vous avez offerte à quelqu'un expire bientôt.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "reward": {
    "id": "grw_0a4f",
    "name": "Free drop-in class",
    "kind": "free_class",
    "holder": {
      "entity_id": "ent_5b21",
      "name": "Lucia Martin",
      "email": "lucia@example.com"
    },
    "expires_at": "2026-11-01T00:00:00Z"
  }
}

Automatisations

automation.step_reached

Une séquence a atteint une étape webhook pour une personne.

Exemple de données
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "automation": {
    "id": "aut_3c81"
  },
  "run": {
    "id": "run_9d42"
  },
  "step": {
    "id": "s_hotlead",
    "key": "hot_lead"
  },
  "person": {
    "entity_id": "ent_5b21",
    "name": "Lucia Martin",
    "email": "lucia@example.com"
  },
  "reached_at": "2026-10-03T08:15:00Z"
}

Webhooks

webhook.test

Un événement de test que vous avez envoyé depuis Kadens.

Exemple de données
JSON
1
2
3
{
  "message": "This is a test event sent from Kadens."
}

Dépannage

Rien n'arrive

Vérifiez que l'endpoint est activé et abonné à l'événement, et que son adresse est publique et utilise HTTPS. Envoyez ensuite un événement de test et ouvrez la livraison pour voir ce que votre serveur a répondu.

La signature ne correspond jamais

Vérifiez sur le corps de requête brut, avant toute analyse JSON. Utilisez le secret de cet endpoint, et vérifiez l'horloge de votre serveur : les requêtes de plus de 300 secondes sont rejetées.

Le même événement arrive deux fois

C'est attendu après une nouvelle tentative, un renvoi ou une relecture. Ignorez tout webhook-id que vous avez déjà traité.

L'endpoint a été désactivé

Il a échoué pendant 5 jours sans succès, a répondu 410 Gone, ou quelqu'un l'a désactivé. Réparez le serveur, activez l'endpoint et rejouez la plage qu'il a manquée.

Les noms ou adresses e-mail sont absents

Les données personnelles sont retirées sauf si l'endpoint les inclut. Voir Données personnelles ci-dessus.

Et maintenant ?

Ouvrir dans le tableau de bord

Cet article vous a-t-il aidé ?

Précédent
Widgets pour site web
Suivant
Assistants IA (MCP)

Sur cette page

  1. Ce qu'est un webhook
  2. Démarrage rapide
  3. Tester sans serveur
  4. Corps de la requête
  5. Vérifier les signatures
  6. Gérer les événements en toute sécurité
  7. Nouvelles tentatives et limites
  8. Données personnelles
  9. Gérer les endpoints
  10. Catalogue des événements
  11. Dépannage
  12. Et maintenant ?