Terminplanung
Kadens sendet jedes Mal eine HTTPS-Anfrage an deinen Endpunkt, wenn in deinem Konto etwas passiert. Jede Anfrage ist signiert, wird bis zum Erfolg wiederholt und erscheint in deinem Zustellungsprotokoll.
Ein Webhook ist eine Nachricht, die Kadens an eine von dir gewählte Webadresse sendet, sobald in deinem Konto etwas passiert: eine Bestellung wird bezahlt, ein Ticket wird ausgestellt, jemand checkt ein. Dein System empfängt sie und erledigt den Rest, zum Beispiel indem es die käufende Person zu deiner Mailingliste hinzufügt oder eine Tabelle aktualisiert.
Nutzt du Zapier, Make, n8n oder eigenen Code? Diese können über einen API-Schlüssel per REST-API Endpunkte für dich erstellen und entfernen.
Kadens kann für dich einen Test-Empfänger hosten. Wähle auf der Webhooks-Seite Mit Test-Empfänger ausprobieren: Kadens erstellt eine private Testadresse, verbindet einen Endpunkt, der jedes Ereignis empfängt, und sendet ihm ein Testereignis. Jede Anfrage erscheint innerhalb von Sekunden auf der Seite dieses Endpunkts, mit ihren Headern, ihrem Inhalt und ob die Signatur übereinstimmte.
Der Test-Empfänger behält die letzten 50 Anfragen 7 Tage lang, sowie die ersten 64 KB jedes Inhalts.
Jedes Ereignis kommt im selben JSON-Umschlag, Version 2026-10-01. Das Ereignis selbst steht in data.
| Feld | Typ | Beschreibung |
|---|---|---|
id | string | Eindeutige Id des Ereignisses, beginnend mit evt_. Derselbe Wert erscheint im Header webhook-id und bleibt bei jeder Wiederholung, jedem erneuten Senden und jeder Wiedergabe gleich. |
type | string | Der Ereignistyp, zum Beispiel order.paid. Der Ereigniskatalog listet sie alle auf. |
version | string | Die Vertragsversion, der der Inhalt folgt. Aktuell ist es 2026-10-01. |
occurred_at | string | Wann es geschah, als ISO-8601-Datum und -Uhrzeit. |
account | { id, name } | Das Kadens-Konto, zu dem das Ereignis gehört: seine Id und sein Name. |
subject.type | string | Die Art des Datensatzes, um den es im Ereignis geht, zum Beispiel order, booking oder subscription. |
subject.id | string | Die Id dieses Datensatzes. Jedes Ereignis zu demselben Datensatz trägt dieselbe Id. |
subject.sequence | integer | null | Eine Zahl, die mit jeder Änderung an demselben Datensatz wächst, damit du erkennst, welches Ereignis neuer ist. null, wenn der Datensatz keine Änderungsreihenfolge hat. |
correlation_id | string | null | Verknüpft Ereignisse aus derselben Aktion, sofern vorhanden. Sonst null. |
livemode | boolean | true für echte Aktivität. false für Testereignisse, deren Ids ebenfalls als Test-Ids markiert sind. |
data | object | Das Ereignis selbst. Seine Felder hängen vom Typ ab: Öffne ein Beispiel im Ereigniskatalog. |
{
"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"
}
}
]
}
}
}Anfragen folgen der Spezifikation Standard Webhooks, daher prüfen die offiziellen Bibliotheken sie ohne Kadens-spezifischen Code. Prüfe immer den unveränderten Rohtext.
| Header | Beschreibung |
|---|---|
webhook-id | Eindeutig pro Ereignis. Nutze ihn, um eine bereits verarbeitete Anfrage zu ignorieren. |
webhook-timestamp | Unix-Sekunden, zu denen die Anfrage signiert wurde. Lehne Anfragen ab, die älter als 300 Sekunden sind. |
webhook-signature | Eine oder mehrere v1-Signaturen, durch Leerzeichen getrennt. 24 Stunden nach dem Erneuern eines Geheimnisses signieren das alte und das neue. |
// 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);
}
});Dasselbe Ereignis kann doppelt, verspätet oder in falscher Reihenfolge ankommen. Drei Gewohnheiten machen deinen Empfänger sicher.
Speichere den webhook-id jedes Ereignisses, das du verarbeitest. Kommt dasselbe nach einer Wiederholung, einem erneuten Senden oder einer Wiedergabe erneut an, antworte mit 2xx und überspringe es.
Eine Wiederholung kann dazu führen, dass ein älteres Ereignis nach einem neueren ankommt. Wenn subject.sequence gesetzt ist, behalte für jede subject.id die höchste verarbeitete Nummer und ignoriere alles Niedrigere.
Antworte mit 2xx, sobald das Ereignis sicher gespeichert ist, und erledige die langsame Arbeit danach im Hintergrund. Eine Antwort, die länger als 10 Sekunden dauert, zählt als Fehlschlag und wird wiederholt.
Antworte mit einem beliebigen 2xx-Status, um eine Zustellung zu bestätigen. Jeder andere Status oder keine Antwort gilt als Fehler.
Eine fehlgeschlagene Zustellung wird noch 10 Mal mit wachsenden Abständen wiederholt, über etwa 3 Tage. Du kannst sie auch über dein Dashboard erneut senden oder einen Zeitraum wiederholen.
Antwortet dein Endpunkt mit 410 Gone, wird er sofort deaktiviert und erhält nichts mehr, bis du ihn wieder aktivierst.
Ein Endpunkt, der 5 Tage lang ohne einen einzigen Erfolg fehlschlägt, wird deaktiviert, und du wirst benachrichtigt.
Ereignisse und Zustellungen werden 30 Tage lang aufbewahrt.
Jedes Konto kann bis zu 10 eigene Endpunkte haben. Endpunkte, die Zapier, Make oder n8n anlegen, zählen nicht zu dieser Grenze und haben eine eigene Obergrenze von 50.
| Wiederholung | Wann |
|---|---|
Wiederholung 1 | 30 Sekunden nach dem vorherigen Versuch |
Wiederholung 2 | 2 Minuten nach dem vorherigen Versuch |
Wiederholung 3 | 10 Minuten nach dem vorherigen Versuch |
Wiederholung 4 | 30 Minuten nach dem vorherigen Versuch |
Wiederholung 5 | 1 Stunde nach dem vorherigen Versuch |
Wiederholung 6 | 3 Stunden nach dem vorherigen Versuch |
Wiederholung 7 | 6 Stunden nach dem vorherigen Versuch |
Wiederholung 8 | 12 Stunden nach dem vorherigen Versuch |
Wiederholung 9 | 24 Stunden nach dem vorherigen Versuch |
Wiederholung 10 | 24 Stunden nach dem vorherigen Versuch |
Namen und E-Mail-Adressen von Käufern, Ticketinhabern und Teilnehmenden sind personenbezogene Daten. Standardmäßig entfernt Kadens diese Felder vor dem Senden, sodass der Endpunkt das Ereignis ohne sie erhält.
Um sie zu erhalten, bearbeite den Endpunkt und aktiviere Personenbezogene Daten einschließen. Sobald die Daten Kadens verlassen, liegt ihr Schutz in deiner Verantwortung.
| Aktion | Beschreibung |
|---|---|
Geheimnis erneuern | Erstellt ein neues Signaturgeheimnis. Das alte signiert noch 24 Stunden lang weiter, sodass du deinen Server aktualisieren kannst, ohne ein Ereignis zu verpassen. |
Erneut senden | Sendet jedes Ereignis aus einem Zeitraum erneut, das der Endpunkt verpasst hat oder nicht empfangen konnte, bis zu 30 Tage zurück. |
Erneut senden | Sendet eine Zustellung aus dem Zustellprotokoll des Endpunkts erneut. |
Testereignis senden | Sendet ein Beispiel eines beliebigen Ereignistyps nur an diesen Endpunkt, markiert als Test. |
Deaktivieren / Aktivieren | Stoppt Zustellungen, bis du den Endpunkt wieder aktivierst. Wiederhole nach dem Aktivieren den Zeitraum, den er verpasst hat. |
Ein Endpunkt, der 5 Tage lang ohne einen einzigen Erfolg fehlschlägt, wird automatisch deaktiviert, und du wirst benachrichtigt.
Abonniere für einen Endpunkt die Ereignisse, die er braucht. Zu jedem siehst du die Daten, die es enthält.
order.paidEine Bestellung wurde bezahlt.
{
"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.refundedEine Bestellung wurde ganz oder teilweise erstattet.
{
"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.abandonedEin Käufer hat einen Checkout begonnen und ohne Bezahlung verlassen.
{
"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"
}ticket.issuedEin Ticket wurde für seinen Inhaber ausgestellt.
{
"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.reassignedEin Ticket wurde an einen anderen Inhaber übertragen.
{
"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.canceledEin Ticket wurde storniert.
{
"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"
}attendee.registeredEin Teilnehmer wurde für eine Veranstaltung angemeldet.
{
"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_inEin Teilnehmer wurde am Einlass eingecheckt.
{
"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_revertedEin Check-in wurde rückgängig gemacht.
{
"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_showEin Ticketinhaber hat vor Ende des Termins nicht eingecheckt.
{
"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"
}event.endedEine deiner Veranstaltungen ist beendet.
{
"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"
}booking.confirmedEine Buchung für eine Sitzung wurde bestätigt.
{
"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.declinedEine Buchungsanfrage wurde abgelehnt.
{
"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.canceledEine Buchung wurde storniert oder ist abgelaufen.
{
"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.movedEine Buchung wurde in eine andere Sitzung verschoben.
{
"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_showEin gebuchter Teilnehmer hat vor Ende der Einheit nicht eingecheckt.
{
"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.canceledEine geplante Sitzung wurde abgesagt.
{
"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.rescheduledEine geplante Sitzung wurde auf eine andere Zeit verlegt.
{
"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_lowEin Kurspaket hat seinen niedrigen Guthaben-Schwellenwert erreicht.
{
"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"
}enrollment.createdEin Teilnehmer wurde in einen Kurs eingeschrieben.
{
"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.endedDie Kurseinschreibung eines Teilnehmers wurde beendet.
{
"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.movedEin Teilnehmer wurde in eine andere Ausgabe des Kurses verschoben.
{
"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.completedEin Schüler hat eine Lektion deines Kurses abgeschlossen.
{
"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.completedEin Schüler hat deinen Kurs abgeschlossen.
{
"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"
}subscription.createdEin Kunde hat einen Plan abonniert.
{
"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.renewedEin Abonnement wurde verlängert und die Zahlung ist eingegangen.
{
"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_failedDie Zahlung für ein Abonnement ist fehlgeschlagen.
{
"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.canceledEin Abonnement wurde gekündigt.
{
"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.reactivatedEin gekündigtes Abonnement wurde reaktiviert.
{
"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_changedEin Kunde hat zu einem anderen Plan gewechselt.
{
"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.endedEin Abonnement ist beendet und der Zugang wurde gestoppt.
{
"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_endingDie kostenlose Testphase eines Abonnenten endet in wenigen Tagen.
{
"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"
}certificate.issuedEin Zertifikat wurde an seinen Inhaber ausgestellt.
{
"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.revokedEin Zertifikat wurde widerrufen.
{
"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"
}payout.paidEine Auszahlung ist auf deinem Bankkonto eingegangen.
{
"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.failedEine Auszahlung ist fehlgeschlagen und das Geld wurde nicht überwiesen.
{
"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"
}lead.capturedEin neuer Lead wurde erfasst.
{
"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.submittedEin Formular wurde abgeschickt.
{
"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.decidedDu hast eine Bewerbung angenommen, abgelehnt oder auf die Warteliste gesetzt.
{
"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_releasedEin Kandidat kann jetzt seine Prüfungsergebnisse sehen.
{
"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.addedJemand folgt dir jetzt.
{
"follower": {
"entity_id": "ent_5b21",
"name": "Lucia Martin",
"email": "lucia@example.com"
},
"followed_at": "2026-10-01T08:00:00Z"
}community.member.joinedEin Mitglied ist einer deiner Communitys beigetreten.
{
"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.leftEin Mitglied hat eine deiner Communitys verlassen.
{
"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.webhookEine Automatisierung hat für einen Kontakt einen Webhook-Sendeschritt erreicht.
{
"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"
}review.submittedJemand hat eine Bewertung abgegeben.
{
"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.completedDu hast die Feedback-Anfrage eines Schülers beantwortet.
{
"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"
}reward.expiringEine Belohnung, die du jemandem gegeben hast, läuft bald ab.
{
"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"
}
}automation.step_reachedEine Sequenz hat für eine Person einen Webhook-Schritt erreicht.
{
"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"
}webhook.testEin Testereignis, das du aus Kadens gesendet hast.
{
"message": "This is a test event sent from Kadens."
}Prüfe, ob der Endpunkt aktiviert und für das Ereignis abonniert ist und ob seine Adresse öffentlich ist und HTTPS verwendet. Sende dann ein Testereignis und öffne die Zustellung, um zu sehen, was dein Server geantwortet hat.
Prüfe gegen den rohen Anfragekörper, vor jeder JSON-Auswertung. Verwende das Geheimnis dieses Endpunkts und prüfe die Uhr deines Servers: Anfragen, die älter als 300 Sekunden sind, werden abgelehnt.
Das ist nach einer Wiederholung, einem erneuten Senden oder einer Wiedergabe zu erwarten. Überspringe jede webhook-id, die du bereits verarbeitet hast.
Er ist 5 Tage lang ohne Erfolg fehlgeschlagen, hat mit 410 Gone geantwortet, oder jemand hat ihn deaktiviert. Behebe den Server, aktiviere den Endpunkt und wiederhole den verpassten Zeitraum.
Personenbezogene Daten werden entfernt, sofern der Endpunkt sie nicht einschließt. Siehe Personenbezogene Daten oben.
War das hilfreich?