Kadens envía una petición HTTPS a tu endpoint cada vez que ocurre algo en tu cuenta. Cada petición va firmada, se reintenta hasta que funciona y aparece en tu registro de entregas.
Un webhook es un mensaje que Kadens envía a una dirección web que elijas cada vez que ocurre algo en tu cuenta: se paga un pedido, se emite una entrada, alguien hace check-in. Tu sistema lo recibe y hace el resto, por ejemplo añadiendo al comprador a tu lista de correo o actualizando una hoja de cálculo.
¿Usas Zapier, Make, n8n o tu propio código? Pueden crear y eliminar endpoints por ti con una clave API, a través de la API REST.
Kadens puede alojar un receptor de pruebas por ti. Elige Probar con un receptor de pruebas en la página de Webhooks: Kadens crea una dirección de prueba privada, conecta un endpoint que recibe todos los eventos y le envía un evento de prueba. Cada petición aparece en la página de ese endpoint en segundos, con sus cabeceras, su cuerpo y si la firma coincidió.
El receptor de pruebas guarda las últimas 50 peticiones durante 7 días, y los primeros 64 KB de cada cuerpo.
Todos los eventos llegan en el mismo sobre JSON, versión 2026-10-01. El evento en sí va en data.
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id único del evento, que empieza por evt_. El mismo valor llega en la cabecera webhook-id y se mantiene igual en cada reintento, reenvío y repetición. |
type | string | El tipo de evento, por ejemplo order.paid. El catálogo de eventos los enumera todos. |
version | string | La versión del contrato que sigue el payload. Hoy es 2026-10-01. |
occurred_at | string | Cuándo ocurrió, como fecha y hora ISO 8601. |
account | { id, name } | La cuenta de Kadens a la que pertenece el evento: su id y su nombre. |
subject.type | string | El tipo de registro sobre el que trata el evento, por ejemplo order, booking o subscription. |
subject.id | string | El id de ese registro. Todos los eventos sobre el mismo registro llevan el mismo id. |
subject.sequence | integer | null | Un número que crece con cada cambio del mismo registro, para que puedas saber qué evento es más reciente. null cuando el registro no tiene un orden de cambios. |
correlation_id | string | null | Enlaza eventos que vienen de la misma acción, cuando la hay. En caso contrario, null. |
livemode | boolean | true para actividad real. false para eventos de prueba, cuyos id también están marcados como id de prueba. |
data | object | El evento en sí. Sus campos dependen del tipo: abre una muestra en el catálogo de eventos. |
{
"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"
}
}
]
}
}
}Las peticiones siguen la especificación Standard Webhooks, así que las bibliotecas oficiales las verifican sin código propio de Kadens. Verifica siempre sobre el cuerpo sin procesar.
| Cabecera | Descripción |
|---|---|
webhook-id | Único por evento. Úsalo para ignorar una petición que ya procesaste. |
webhook-timestamp | Segundos Unix en que se firmó la petición. Rechaza las peticiones con más de 300 segundos de antigüedad. |
webhook-signature | Una o más firmas v1 separadas por espacios. Durante 24 horas después de rotar un secreto, firman tanto el antiguo como el nuevo. |
// 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);
}
});El mismo evento puede llegar dos veces, tarde o desordenado. Tres hábitos hacen seguro tu receptor.
Guarda el webhook-id de cada evento que gestiones. Si el mismo vuelve a llegar tras un reintento, un reenvío o una repetición, responde 2xx y omítelo.
Un reintento puede hacer que un evento antiguo llegue después de uno más reciente. Cuando subject.sequence está definido, conserva el más alto que hayas gestionado para cada subject.id e ignora cualquiera inferior.
Responde 2xx en cuanto el evento esté guardado de forma segura, y haz el trabajo lento en segundo plano. Una respuesta que tarde más de 10 segundos cuenta como fallo y se reintenta.
Responde con cualquier estado 2xx para confirmar una entrega. Cualquier otro estado, o no responder, cuenta como fallo.
Una entrega fallida se reintenta 10 veces más con esperas cada vez mayores, durante unos 3 días. También puedes reenviarla o reproducir un intervalo de tiempo desde tu panel.
Si tu endpoint responde 410 Gone, se desactiva de inmediato y no recibe nada más hasta que lo actives.
Un endpoint que falla durante 5 días sin un solo éxito se desactiva, y te avisamos.
Los eventos y las entregas se guardan durante 30 días.
Cada cuenta puede tener hasta 10 endpoints propios. Los endpoints que crean Zapier, Make o n8n no cuentan para ese límite y tienen su propio máximo de 50.
| Reintento | Cuándo |
|---|---|
Reintento 1 | 30 segundos después del intento anterior |
Reintento 2 | 2 minutos después del intento anterior |
Reintento 3 | 10 minutos después del intento anterior |
Reintento 4 | 30 minutos después del intento anterior |
Reintento 5 | 1 hora después del intento anterior |
Reintento 6 | 3 horas después del intento anterior |
Reintento 7 | 6 horas después del intento anterior |
Reintento 8 | 12 horas después del intento anterior |
Reintento 9 | 24 horas después del intento anterior |
Reintento 10 | 24 horas después del intento anterior |
Los nombres y direcciones de correo de compradores, poseedores de entradas y asistentes son datos personales. Por defecto Kadens elimina esos campos de los datos antes de enviarlos, así que el endpoint recibe el evento sin ellos.
Para recibirlos, edita el endpoint y activa Incluir datos personales. Una vez que los datos salen de Kadens, protegerlos de tu lado es tu responsabilidad.
| Acción | Descripción |
|---|---|
Rotar secreto | Crea un nuevo secreto de firma. El antiguo sigue firmando durante 24 horas, para que puedas actualizar tu servidor sin perder ningún evento. |
Reenviar | Vuelve a enviar todos los eventos de un rango de fechas que el endpoint no recibió o no pudo recibir, hasta 30 días atrás. |
Volver a enviar | Vuelve a enviar una entrega, desde el registro de entregas del endpoint. |
Enviar evento de prueba | Envía una muestra de cualquier tipo de evento solo a este endpoint, marcada como prueba. |
Desactivar / Activar | Detiene las entregas hasta que vuelvas a activar el endpoint. Después de activarlo, repite el rango que se perdió. |
Un endpoint que falla durante 5 días sin un solo éxito se desactiva automáticamente, y se te notifica.
Suscribe un endpoint a los eventos que necesita. Cada uno muestra los datos que lleva.
order.paidSe ha pagado un pedido.
{
"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.refundedSe ha reembolsado un pedido, total o parcialmente.
{
"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.abandonedUn comprador empezó una compra y se fue sin pagar.
{
"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.issuedSe ha emitido una entrada a su titular.
{
"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.reassignedUna entrada ha pasado a otro titular.
{
"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.canceledSe ha cancelado una entrada.
{
"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.registeredSe ha registrado un asistente en un evento.
{
"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_inSe ha registrado la llegada de un asistente en la puerta.
{
"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_revertedSe ha deshecho un registro de llegada.
{
"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_showUn titular de entrada no hizo el check in antes de terminar la sesión.
{
"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.endedUno de tus eventos terminó.
{
"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.confirmedSe confirmó una reserva para una sesión.
{
"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.declinedSe rechazó una solicitud de reserva.
{
"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.canceledSe canceló una reserva o caducó.
{
"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.movedSe movió una reserva a otra sesión.
{
"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_showUn asistente reservado no hizo el check in antes de que terminara la sesión.
{
"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.canceledSe canceló una sesión programada.
{
"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.rescheduledSe cambió la hora de una sesión programada.
{
"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_lowUn bono de clases llegó a su umbral bajo de créditos.
{
"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.createdSe inscribió a un estudiante en un curso.
{
"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.endedTerminó la inscripción de un estudiante en un curso.
{
"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.movedSe movió a un estudiante a otra edición del curso.
{
"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.completedUn estudiante completó una lección de tu curso.
{
"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.completedUn estudiante completó tu curso.
{
"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.createdUn cliente se suscribió a un plan.
{
"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.renewedSe renovó una suscripción y se cobró su pago.
{
"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_failedFalló el pago de una suscripción.
{
"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.canceledSe canceló una suscripción.
{
"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.reactivatedSe reactivó una suscripción cancelada.
{
"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_changedUn cliente cambió a otro 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.endedTerminó una suscripción y se cortó su acceso.
{
"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_endingLa prueba gratuita de un suscriptor termina en unos días.
{
"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.issuedSe emitió un certificado a su titular.
{
"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.revokedSe revocó un certificado.
{
"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.paidUn pago llegó a tu cuenta bancaria.
{
"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.failedUn pago falló y el dinero no se movió.
{
"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.capturedSe captó un nuevo lead.
{
"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.submittedSe envió un formulario.
{
"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.decidedAprobaste, rechazaste o pusiste en lista de espera una solicitud.
{
"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_releasedUn candidato ya puede ver los resultados de su examen.
{
"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.addedAlguien empezó a seguirte.
{
"follower": {
"entity_id": "ent_5b21",
"name": "Lucia Martin",
"email": "lucia@example.com"
},
"followed_at": "2026-10-01T08:00:00Z"
}community.member.joinedUn miembro se unió a una de tus comunidades.
{
"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.leftUn miembro dejó una de tus comunidades.
{
"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.webhookUna automatización llegó a un paso de envío de webhook para un contacto.
{
"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.submittedAlguien dejó una reseña.
{
"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.completedRespondiste la solicitud de feedback de un estudiante.
{
"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.expiringUna recompensa que le diste a alguien caduca pronto.
{
"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_reachedUna secuencia llegó a un paso de webhook para una persona.
{
"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.testUn evento de prueba que enviaste desde Kadens.
{
"message": "This is a test event sent from Kadens."
}Comprueba que el endpoint está activado y suscrito al evento, y que su dirección es pública y usa HTTPS. Después envía un evento de prueba y abre la entrega para ver qué respondió tu servidor.
Verifica contra el cuerpo de la petición sin procesar, antes de cualquier análisis JSON. Usa el secreto de este endpoint y comprueba el reloj de tu servidor: las peticiones más antiguas de 300 segundos se rechazan.
Es normal tras un reintento, un reenvío o una repetición. Omite cualquier webhook-id que ya hayas gestionado.
Falló durante 5 días sin un éxito, respondió 410 Gone, o alguien lo desactivó. Arregla el servidor, activa el endpoint y repite el rango que se perdió.
Los datos personales se eliminan a menos que el endpoint los incluya. Consulta Datos personales más arriba.
¿Te ha resultado útil?