Kadens wysyła żądanie HTTPS do Twojego endpointu za każdym razem, gdy coś dzieje się na Twoim koncie. Każde żądanie jest podpisane, ponawiane do skutku i widoczne w dzienniku dostarczeń.
Webhook to wiadomość, którą Kadens wysyła pod wybrany przez Ciebie adres internetowy za każdym razem, gdy w Twoim koncie coś się dzieje: zamówienie zostaje opłacone, bilet wystawiony, ktoś się zameldowuje. Twój system odbiera ją i robi resztę, na przykład dodaje kupującego do listy mailingowej albo aktualizuje arkusz kalkulacyjny.
Używasz Zapiera, Make, n8n lub własnego kodu? Mogą tworzyć i usuwać endpointy za Ciebie za pomocą klucza API, poprzez REST API.
Kadens może hostować dla Ciebie testowy odbiornik. Wybierz Wypróbuj z testowym odbiornikiem na stronie Webhooków: Kadens tworzy prywatny adres testowy, podłącza endpoint, który odbiera każde zdarzenie, i wysyła mu testowe zdarzenie. Każde żądanie pojawia się na stronie tego endpointu w ciągu kilku sekund, wraz z nagłówkami, treścią i informacją, czy podpis się zgadzał.
Testowy odbiornik przechowuje ostatnie 50 żądań przez 7 dni, oraz pierwsze 64 KB każdej treści.
Każde zdarzenie przychodzi w tej samej kopercie JSON, wersja 2026-10-01. Samo zdarzenie znajduje się w data.
| Pole | Typ | Opis |
|---|---|---|
id | string | Unikalne id zdarzenia, zaczynające się od evt_. Ta sama wartość pojawia się w nagłówku webhook-id i pozostaje taka sama przy każdej ponownej próbie, ponownym wysłaniu i powtórce. |
type | string | Typ zdarzenia, na przykład order.paid. Katalog zdarzeń wymienia je wszystkie. |
version | string | Wersja kontraktu, którą stosuje ten payload. Obecnie jest to 2026-10-01. |
occurred_at | string | Kiedy to się wydarzyło, jako data i godzina w formacie ISO 8601. |
account | { id, name } | Konto Kadens, do którego należy zdarzenie: jego id i nazwa. |
subject.type | string | Rodzaj rekordu, którego dotyczy zdarzenie, na przykład order, booking lub subscription. |
subject.id | string | Id tego rekordu. Każde zdarzenie dotyczące tego samego rekordu ma to samo id. |
subject.sequence | integer | null | Liczba, która rośnie z każdą zmianą tego samego rekordu, dzięki czemu wiesz, które zdarzenie jest nowsze. null, gdy rekord nie ma kolejności zmian. |
correlation_id | string | null | Łączy zdarzenia pochodzące z tej samej akcji, jeśli taka istnieje. W przeciwnym razie null. |
livemode | boolean | true dla rzeczywistej aktywności. false dla zdarzeń testowych, których id są również oznaczone jako testowe. |
data | object | Samo zdarzenie. Jego pola zależą od typu: otwórz przykład w katalogu zdarzeń. |
{
"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"
}
}
]
}
}
}Żądania są zgodne ze specyfikacją Standard Webhooks, więc oficjalne biblioteki weryfikują je bez kodu specyficznego dla Kadens. Zawsze weryfikuj surową treść.
| Nagłówek | Opis |
|---|---|
webhook-id | Unikalny dla każdego zdarzenia. Użyj go, aby pominąć już przetworzone żądanie. |
webhook-timestamp | Sekundy Unix, w których podpisano żądanie. Odrzucaj żądania starsze niż 300 sekund. |
webhook-signature | Jeden lub więcej podpisów v1 oddzielonych spacjami. Przez 24 godz. po zmianie sekretu podpisuje zarówno stary, jak i nowy. |
// 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);
}
});To samo zdarzenie może dotrzeć dwukrotnie, z opóźnieniem lub w złej kolejności. Trzy nawyki sprawiają, że Twój odbiornik jest bezpieczny.
Zapisuj webhook-id każdego obsłużonego zdarzenia. Jeśli to samo zdarzenie dotrze ponownie po ponownej próbie, ponownym wysłaniu lub powtórce, odpowiedz 2xx i je pomiń.
Ponowna próba może sprawić, że starsze zdarzenie dotrze po nowszym. Gdy ustawione jest subject.sequence, zachowaj najwyższą wartość obsłużoną dla każdego subject.id i ignoruj wszystko niższe.
Odpowiedz 2xx, gdy tylko zdarzenie zostanie bezpiecznie zapisane, a wolniejszą pracę wykonaj w tle. Odpowiedź, która trwa dłużej niż 10 sekund, liczy się jako błąd i zostanie powtórzona.
Odpowiedz dowolnym statusem 2xx, aby potwierdzić dostarczenie. Każdy inny status lub brak odpowiedzi to błąd.
Nieudane dostarczenie jest ponawiane jeszcze 10 razy z rosnącymi odstępami, przez około 3 dni. Możesz też wysłać je ponownie lub powtórzyć zakres czasu w panelu.
Jeśli Twój endpoint odpowie 410 Gone, zostaje od razu wyłączony i nie otrzymuje nic więcej, dopóki go nie włączysz.
Endpoint, który przez 5 dni nie ma ani jednego sukcesu, zostaje wyłączony, a Ty dostajesz powiadomienie.
Zdarzenia i dostarczenia są przechowywane przez 30 dni.
Każde konto może mieć do 10 własnych endpointów. Endpointy tworzone przez Zapier, Make lub n8n nie wliczają się do tego limitu i mają własny limit 50.
| Ponowienie | Kiedy |
|---|---|
Próba 1 | 30 sekund po poprzedniej próbie |
Próba 2 | 2 minuty po poprzedniej próbie |
Próba 3 | 10 minut po poprzedniej próbie |
Próba 4 | 30 minut po poprzedniej próbie |
Próba 5 | 1 godzina po poprzedniej próbie |
Próba 6 | 3 godziny po poprzedniej próbie |
Próba 7 | 6 godzin po poprzedniej próbie |
Próba 8 | 12 godzin po poprzedniej próbie |
Próba 9 | 24 godziny po poprzedniej próbie |
Próba 10 | 24 godziny po poprzedniej próbie |
Imiona, nazwiska i adresy e-mail kupujących, posiadaczy biletów i uczestników to dane osobowe. Domyślnie Kadens usuwa te pola przed wysłaniem, więc endpoint otrzymuje zdarzenie bez nich.
Aby je otrzymywać, edytuj endpoint i włącz Uwzględnij dane osobowe. Gdy dane opuszczą Kadens, ich ochrona po Twojej stronie jest Twoją odpowiedzialnością.
| Akcja | Opis |
|---|---|
Zmień sekret | Tworzy nowy sekret podpisu. Stary nadal podpisuje przez 24 godzin, więc możesz zaktualizować swój serwer, nie tracąc żadnego zdarzenia. |
Wyślij ponownie | Wysyła ponownie każde zdarzenie z wybranego zakresu dat, którego endpoint nie otrzymał lub którego dostarczenie się nie powiodło, maksymalnie 30 dni wstecz. |
Wyślij ponownie | Wysyła ponownie jedno dostarczenie z dziennika dostarczeń endpointu. |
Wyślij zdarzenie testowe | Wysyła przykład dowolnego typu zdarzenia tylko do tego endpointu, oznaczony jako testowy. |
Wyłącz / Włącz | Zatrzymuje dostarczenia, dopóki ponownie nie włączysz endpointu. Po włączeniu powtórz zakres, który został pominięty. |
Endpoint, który przez 5 dni nie ma ani jednego udanego dostarczenia, jest wyłączany automatycznie, a Ty otrzymujesz powiadomienie.
Zasubskrybuj dla endpointu potrzebne zdarzenia. Przy każdym widać dane, które zawiera.
order.paidZamówienie zostało opłacone.
{
"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.refundedZamówienie zostało zwrócone w całości lub w części.
{
"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.abandonedKupujący zaczął zakup i odszedł bez zapłaty.
{
"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.issuedBilet został wystawiony dla posiadacza.
{
"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.reassignedBilet został przekazany innemu posiadaczowi.
{
"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.canceledBilet został anulowany.
{
"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.registeredUczestnik został zarejestrowany na wydarzenie.
{
"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_inUczestnik został odprawiony przy wejściu.
{
"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_revertedOdprawa została cofnięta.
{
"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_showPosiadacz biletu nie dokonał odprawy przed końcem sesji.
{
"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.endedJedno z Twoich wydarzeń zakończyło się.
{
"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.confirmedRezerwacja na sesję została potwierdzona.
{
"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.declinedProśba o rezerwację została odrzucona.
{
"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.canceledRezerwacja została anulowana lub wygasła.
{
"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.movedRezerwacja została przeniesiona na inną sesję.
{
"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_showZarezerwowany uczestnik nie dokonał odprawy przed końcem zajęć.
{
"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.canceledZaplanowana sesja została odwołana.
{
"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.rescheduledZaplanowana sesja została przeniesiona na inny termin.
{
"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_lowKarnet na zajęcia spadł do niskiego progu kredytów.
{
"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.createdKursant został zapisany na kurs.
{
"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.endedZapis kursanta na kurs dobiegł końca.
{
"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.movedKursant został przeniesiony do innej edycji kursu.
{
"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.completedUczeń zakończył lekcję Twojego kursu.
{
"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.completedUczeń zakończył Twój kurs.
{
"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.createdKlient wykupił subskrypcję planu.
{
"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.renewedSubskrypcja została odnowiona, a płatność przeszła.
{
"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_failedPłatność za subskrypcję nie powiodła się.
{
"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.canceledSubskrypcja została anulowana.
{
"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.reactivatedAnulowana subskrypcja została wznowiona.
{
"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_changedKlient przeszedł na inny plan.
{
"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.endedSubskrypcja wygasła i dostęp został zakończony.
{
"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_endingBezpłatny okres próbny subskrybenta kończy się za kilka dni.
{
"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.issuedCertyfikat został wystawiony posiadaczowi.
{
"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.revokedCertyfikat został cofnięty.
{
"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.paidWypłata dotarła na Twoje konto bankowe.
{
"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.failedWypłata nie powiodła się i pieniądze nie zostały przelane.
{
"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.capturedPozyskano nowego leada.
{
"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.submittedWysłano formularz.
{
"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.decidedZatwierdziłeś, odrzuciłeś lub umieściłeś na liście rezerwowej zgłoszenie.
{
"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_releasedKandydat może teraz zobaczyć wyniki swojego egzaminu.
{
"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.addedKtoś zaczął Cię obserwować.
{
"follower": {
"entity_id": "ent_5b21",
"name": "Lucia Martin",
"email": "lucia@example.com"
},
"followed_at": "2026-10-01T08:00:00Z"
}community.member.joinedCzłonek dołączył do jednej z Twoich społeczności.
{
"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.leftCzłonek opuścił jedną z Twoich społeczności.
{
"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.webhookAutomatyzacja dotarła do kroku wysyłania webhooka dla kontaktu.
{
"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.submittedKtoś dodał recenzję.
{
"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.completedOdpowiedziałeś na prośbę o opinię od ucznia.
{
"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.expiringNagroda, którą komuś przyznałeś, wkrótce wygasa.
{
"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_reachedSekwencja dotarła do kroku webhook dla osoby.
{
"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.testZdarzenie testowe wysłane z Kadens.
{
"message": "This is a test event sent from Kadens."
}Sprawdź, czy endpoint jest włączony i subskrybuje zdarzenie oraz czy jego adres jest publiczny i używa HTTPS. Następnie wyślij testowe zdarzenie i otwórz dostarczenie, aby zobaczyć, co odpowiedział Twój serwer.
Weryfikuj względem surowej treści żądania, przed jakimkolwiek parsowaniem JSON. Użyj sekretu tego endpointu i sprawdź zegar swojego serwera: żądania starsze niż 300 sekund są odrzucane.
To normalne po ponownej próbie, ponownym wysłaniu lub powtórce. Pomijaj każdy webhook-id, który już obsłużyłeś.
Przez 5 dni nie miał żadnego udanego dostarczenia, odpowiedział 410 Gone, albo ktoś go wyłączył. Napraw serwer, włącz endpoint i powtórz zakres, który został pominięty.
Dane osobowe są usuwane, chyba że endpoint je uwzględnia. Zobacz Dane osobowe powyżej.
Czy to pomogło?