Webhooks — Eventos en tiempo real
Speaknosis envía eventos en tiempo real al endpoint configurado en tu sistema cada vez que ocurre un cambio relevante en las suscripciones o licencias de tus providers hijos.
💡 Configuración: El endpoint receptor debe ser acordado y registrado con el equipo de Speaknosis antes de comenzar. Contacta a soporte técnico para configurarlo.
↔️ Estos son los eventos que Speaknosis te envía a vos. Si tu provider opera en régimen de self-billing, además existe un webhook en sentido inverso —de tu sistema hacia Speaknosis— para notificar altas, cambios de cantidad y bajas. 👉 Ver Self-billing
Estructura general del payload
Todos los eventos comparten la misma estructura base:
{
"type": "nombre.del.evento",
"message": {
"providerId": 1042,
...
}
}
| Campo | Tipo | Descripción |
|---|---|---|
type | string | Identificador del tipo de evento. |
message | object | Cuerpo del evento. Varía según el tipo. |
providerId | number | ID interno del provider que originó el evento en Speaknosis. |
Eventos disponibles
| Evento | Cuándo se dispara |
|---|---|
subscription.contracted | El provider completa el pago de un plan por primera vez (o upgrade desde trial) |
subscription.updated | El provider cambia la cantidad de licencias, o se aplica un downgrade al renovarse |
subscription.cancelled | El provider cancela la suscripción (se hará efectiva al fin del período actual) |
license.associated | Se asignan uno o más usuarios a licencias |
license.dissociated | Se remueven uno o más usuarios de sus licencias |
Qué eventos se disparan en cada régimen de facturación
| Evento | STRIPE | PARTNER_SELF (self-billing) |
|---|---|---|
subscription.contracted | Al confirmarse el pago en Stripe | Al procesarse tu checkout.session.completed |
subscription.updated | Al cambiar cantidades desde el portal, o al aplicarse un downgrade programado | Al procesarse tu customer.subscription.updated con cambio de cantidades |
subscription.cancelled | Al cancelar la suscripción desde el portal | No se envía: la baja la originás vos con customer.subscription.deleted |
license.associated | ✅ | ✅ |
license.dissociated | ✅ | ✅ |
En self-billing, subscription.contracted y subscription.updated funcionan como confirmación de
que el evento que enviaste se aplicó.
🟢 subscription.contracted
Se dispara cuando el provider completa el pago de un plan por primera vez.
{
"type": "subscription.contracted",
"message": {
"providerId": 1042,
"licenses": [
{ "plan": "BASIC", "total": 5 },
{ "plan": "ELITE", "total": 3 }
]
}
}
| Campo | Tipo | Descripción |
|---|---|---|
licenses | array | Lista de planes contratados con su cantidad total de slots. |
licenses[].plan | string | Nombre del plan: BASIC o ELITE. |
licenses[].total | number | Cantidad total de slots contratados para ese plan. |
🔵 subscription.updated
Se dispara cuando el provider modifica la cantidad de licencias contratadas. También se dispara al inicio de un período de renovación cuando hay un downgrade programado que se aplica.
ℹ️ En renovaciones simples (sin cambio de cantidad) no se envía este evento.
{
"type": "subscription.updated",
"message": {
"providerId": 1042,
"licenses": [
{ "plan": "BASIC", "total": 8 },
{ "plan": "ELITE", "total": 8 }
]
}
}
| Campo | Tipo | Descripción |
|---|---|---|
licenses | array | Lista de planes con su cantidad total vigente tras el cambio (no el delta). |
licenses[].plan | string | Nombre del plan: BASIC o ELITE. |
licenses[].total | number | Nueva cantidad total contratada para ese plan. |
🟠 subscription.cancelled
Se dispara cuando el provider cancela la suscripción. La cancelación no es inmediata: se hace efectiva al final del período de facturación actual (hasta esa fecha los doctores mantienen su acceso).
{
"type": "subscription.cancelled",
"message": {
"providerId": 1042,
"cancelAt": "2026-09-01 00:00:00"
}
}
| Campo | Tipo | Descripción |
|---|---|---|
cancelAt | string | Fecha y hora (UTC) en que la cancelación se hace efectiva (fin del período actual). |
🟡 license.associated
Se dispara cuando se asignan uno o más usuarios a licencias. Puede incluir múltiples usuarios en un solo evento si la asignación fue en lote.
{
"type": "license.associated",
"message": {
"providerId": 1042,
"users": [
{ "userId": "tu-id-externo-1", "plan": "BASIC" },
{ "userId": "tu-id-externo-2", "plan": "ELITE" }
]
}
}
| Campo | Tipo | Descripción |
|---|---|---|
users | array | Lista de usuarios que recibieron una licencia. |
users[].userId | string | ID externo del usuario en tu sistema (el id enviado al registrar el doctor). |
users[].plan | string | Plan asignado: BASIC o ELITE. |
🔴 license.dissociated
Se dispara cuando se remueve uno o más usuarios de sus licencias. Puede incluir múltiples usuarios en un solo evento si la remoción fue en lote.
{
"type": "license.dissociated",
"message": {
"providerId": 1042,
"users": [{ "userId": "tu-id-externo-1" }, { "userId": "tu-id-externo-2" }]
}
}
| Campo | Tipo | Descripción |
|---|---|---|
users | array | Lista de usuarios que perdieron su licencia. |
users[].userId | string | ID externo del usuario en tu sistema. |
ℹ️ Este evento no incluye el plan que tenía el usuario, ya que la licencia fue liberada.
Consideraciones de implementación
- Los eventos se envían de forma asíncrona. Tu endpoint debe responder con
HTTP 2xxpara confirmar la recepción. - El endpoint debe estar disponible públicamente y soportar solicitudes
POSTconContent-Type: application/json. - Si el endpoint no responde o devuelve un error, Speaknosis no reintenta el envío automáticamente.
- El campo
providerIdsiempre hace referencia al provider que originó el evento, útil si un mismo endpoint recibe eventos de múltiples providers hijos.