Recibir eventos de forma fiable
Las reglas que debe seguir todo endpoint de webhook sobre autenticidad, comprobación de la organización, duplicados, confirmación rápida y obtención de datos de la API.
Esta página describe cómo construir un endpoint que reciba los webhooks de BreezeAuth de forma segura, sin perder eventos ni procesarlos dos veces. Está pensada para desarrolladores, pero el resumen siguiente es útil para cualquier persona responsable de una integración.
Resumen
Para cada petición que recibe, tu endpoint debe:
- Verificar la firma. Rechazar la petición si falta o no es válida.
- Comprobar la organización. Rechazar el mensaje si
organizationsUuidno es la organización esperada. - Ignorar los duplicados. Si ya ha recibido este
webhook-id, responder2xxy parar. - Guardar el mensaje y responder
2xxde inmediato, mucho antes de los 15 segundos. - Procesar el mensaje en segundo plano: obtener los datos actuales de la API y actualizar tu sistema.
POST /webhooks/breezeauth
├─ ¿firma no válida? → 401, parar
├─ ¿organizationsUuid inesperado? → 403, parar
├─ ¿webhook-id ya recibido? → 204, parar
├─ guardar mensaje + webhook-id (una sola transacción)
└─ 204 → un proceso en segundo plano trata el mensaje guardado
Verificar la firma
La firma es la única prueba de que un mensaje lo ha enviado BreezeAuth. Compruébala antes de leer cualquier otro
contenido del mensaje y rechaza la petición con un estado 4xx si falla. Todos los detalles, con ejemplos de código,
están en Verificar firmas.
Comprobar la organización
Una firma válida demuestra que el mensaje viene de BreezeAuth, pero BreezeAuth da servicio a muchas organizaciones, y todas firman con las mismas claves. Tu endpoint también debe asegurarse de que el mensaje se refiere a tu organización.
Compara el campo organizationsUuid del cuerpo con el identificador de la organización que espera tu sistema y rechaza
el mensaje si no coinciden. Esto te protege, por ejemplo, si la URL de tu endpoint se registra por error, o
intencionadamente, como webhook en otra organización.
Si un mismo endpoint da servicio a varias organizaciones, por ejemplo en un producto multi-tenant, mantén la lista de identificadores de organización que acepta y busca cada mensaje en esa lista.
Nota: el identificador de tu organización es el valor de organizationsUuid. Aparece debajo del nombre de la
organización en la página Gestionar organización, con un botón para copiarlo.
Ignorar los duplicados
BreezeAuth entrega cada evento al menos una vez. En algunas situaciones, el mismo mensaje puede llegar más de una vez, por ejemplo:
- tu endpoint procesó el mensaje, pero su respuesta tardó más de 15 segundos o se perdió en la red, así que BreezeAuth consideró fallido el intento y lo reintentó;
- un fallo temporal en la infraestructura de BreezeAuth hizo que se volviera a enviar un mensaje que ya se había entregado;
- dos webhooks de tu organización apuntan a la misma URL y se suscriben al mismo evento.
Por eso, la detección de duplicados por tu parte es obligatoria. Cada mensaje tiene un identificador único, enviado
en la cabecera webhook-id y repetido como uuid en el cuerpo. Es el mismo en todas las entregas del mismo evento.
Un enfoque sencillo y robusto es una tabla con una restricción de unicidad sobre el identificador:
CREATE TABLE breezeauth_webhook_messages (
webhook_id VARCHAR(64) PRIMARY KEY,
received_at TIMESTAMP NOT NULL,
payload TEXT NOT NULL,
processed_at TIMESTAMP NULL
);
Cuando llegue un mensaje, inserta su identificador y su contenido en una sola transacción. Si la inserción falla porque
el identificador ya existe, el mensaje es un duplicado: responde 2xx sin hacer nada más. Conserva los identificadores
al menos unos días; guardarlos más tiempo cuesta poco y hace más completo tu registro de auditoría.
Consejo: responde 2xx a los duplicados, no un error. Un error haría que BreezeAuth reintentara un mensaje que ya
has recibido.
Confirmar rápido, procesar después
BreezeAuth espera como máximo 15 segundos una respuesta. Tu endpoint debería responder en cuanto el mensaje esté guardado de forma segura y dejar el trabajo real (llamar a la API, actualizar bases de datos, enviar correos) a un proceso en segundo plano, como una cola de tareas, un worker o una tarea programada.
- Responde con cualquier estado
2xx, como200 OKo204 No Content. El cuerpo de la respuesta se ignora. - No llames a la API de BreezeAuth ni a otros servicios lentos antes de responder.
- Si tu endpoint no puede guardar el mensaje (por ejemplo, porque tu base de datos no está disponible), responde con un
estado
5xxpara que BreezeAuth lo reintente.
Hacer trabajo pesado de forma síncrona es la causa más habitual de los tiempos de espera agotados y, por tanto, de los reintentos y los duplicados.
Obtener los detalles de la API
Los mensajes solo incluyen identificadores. Cuando tu
proceso en segundo plano necesita más información, lee el estado actual de la API de BreezeAuth, en
https://api.breezeauth.com.
-
En la consola de administración, crea un usuario de servicio en Usuarios › Usuarios de servicio y genera una credencial para él. Obtendrás un client ID y un client secret. Da al usuario de servicio solo el acceso que necesite tu integración, por ejemplo el rol Auditor para un acceso de solo lectura. Consulta Usuarios de servicio.
-
Intercambia la credencial por un token de acceso:
curl -X POST https://api.breezeauth.com/oauth/token \ -H 'Content-Type: application/json' \ -d '{"grant_type": "client_credentials", "client_id": "<client ID>", "client_secret": "<client secret>"}'La respuesta contiene un
access_tokeny su validez en segundos,expires_in. Reutiliza el token hasta que caduque y después solicita uno nuevo. Consulta Tokens de acceso para ver más detalles y ejemplos de código. -
Llama a la API con el token en la cabecera
Authorization:curl https://api.breezeauth.com/organizations/<organizationsUuid>/memberships/<membershipsUuid> \ -H 'Authorization: Bearer <token de acceso>'
Dónde leer cada recurso:
| Eventos | Petición a la API |
|---|---|
membership.* |
GET /organizations/{organizationsUuid}/memberships/{membershipsUuid} |
group.* |
GET /organizations/{organizationsUuid}/groups/{groupsUuid} |
group_assignment.* |
GET /organizations/{organizationsUuid}/groups/{groupsUuid}/assignments/{groupAssignmentsUuid} |
application.* |
GET /organizations/{organizationsUuid}/applications/{applicationsUuid} |
application_assignment.* |
GET /organizations/{organizationsUuid}/applications/{applicationsUuid}/assignments/{applicationAssignmentsUuid} |
domain.* |
GET /organizations/{organizationsUuid}/domains/{domainsUuid} |
Ten en cuenta que:
- Recursos eliminados. Tras un evento
*.deleted, normalmente el recurso ya no está disponible y la API responde404 Not Found. Tómalo como confirmación de la eliminación. - El orden no está garantizado. Los mensajes pueden llegar en un orden distinto al de los eventos, por ejemplo un
membership.updatedantes delmembership.createdcorrespondiente. Como siempre lees el estado actual de la API, el orden no importa: trata cada mensaje como “algo ha cambiado en este recurso, voy a mirarlo ahora”. - Varios mensajes, una lectura. Cuando llegan muchos eventos seguidos sobre el mismo recurso, tu proceso en segundo plano puede leer el recurso una sola vez y tratarlos todos.
Reconciliar periódicamente
Los webhooks mantienen tu sistema actualizado casi en tiempo real, pero no son un mecanismo de sincronización completo. Si tu endpoint no está disponible durante más tiempo que el margen de reintentos, o si un webhook está desactivado durante un tiempo, algunos eventos no se entregarán. Por ahora, BreezeAuth no ofrece una forma de reenviarlos.
En integraciones en las que perder un cambio es grave, como retirar el acceso a quien ha dejado la empresa, añade una reconciliación periódica: por ejemplo, una vez al día, obtén de la API la lista de recursos relevantes y corrige cualquier diferencia con tu sistema. Los webhooks se encargan de los cambios del día a día, y la reconciliación recoge lo que se haya escapado.
Lista de comprobación
- El endpoint usa
https://y la URL registrada en BreezeAuth es la dirección final (sin redirecciones). - Opcionalmente, el cortafuegos solo acepta peticiones de las direcciones IP de BreezeAuth.
- La firma se verifica sobre el cuerpo sin procesar, antes que nada.
- Se rechazan los mensajes con un
organizationsUuidinesperado. - El
webhook-idse guarda con una restricción de unicidad, y los duplicados reciben2xx. - El endpoint responde en pocos segundos y procesa los mensajes en segundo plano.
- Los tipos de evento desconocidos reciben
2xxy se ignoran. - Los detalles se obtienen de la API, y se gestiona el
404tras una eliminación. - Existe una reconciliación periódica para los datos críticos.
- Alguien revisa el historial de eventos cuando fallan las entregas.
Última actualización: 13 de octubre de 2026