Español (ES)
Español (ES)
Appearance
Español (ES)
Español (ES)
Appearance
Los webhooks notifican a tu aplicación en tiempo real cuando ocurre algo con tus credenciales: cuando se emite, se entrega, se revoca o se visualiza una. En lugar de sondear la API, registras un endpoint HTTPS y badges.ninja le envía un POST firmado por cada evento al que te suscribas.
Todos los endpoints de gestión requieren autenticación mediante la cabecera X-Api-Key. Consulta Autenticación. Crear o eliminar endpoints requiere una clave con permiso de escritura; listar requiere lectura. Consulta Claves API.
POST /webhooks| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
url | string | Sí | Tu endpoint HTTPS. Debe empezar por https://. |
events | string[] | No | Tipos de evento a los que suscribirse. Omítelo o pasa ["*"] para recibir todos los eventos. |
curl -X POST https://api.badges.ninja/webhooks \
-H "X-Api-Key: bws_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/badges",
"events": ["credential.issued", "credential.delivered"]
}'201 Created. El secreto de firma se devuelve una sola vez: guárdalo ahora; no podrás recuperarlo de nuevo.
{
"id": "e4b19ff5-063d-4799-bd75-d03641be624f",
"url": "https://example.com/hooks/badges",
"events": ["credential.issued", "credential.delivered"],
"secret": "2be6d335682c1658242fde3a523fd8a2493bab8c"
}GET /webhooksDevuelve tus endpoints registrados. Los secretos de firma nunca se incluyen.
{
"webhooks": [
{
"id": "e4b19ff5-063d-4799-bd75-d03641be624f",
"url": "https://example.com/hooks/badges",
"events": ["credential.issued", "credential.delivered"],
"active": true,
"failureCount": 0,
"createdAt": 1787685415083,
"lastStatus": 200,
"lastDeliveryAt": 1787685480777
}
]
}DELETE /webhooks/{id}curl -X DELETE https://api.badges.ninja/webhooks/e4b19ff5-063d-4799-bd75-d03641be624f \
-H "X-Api-Key: bws_your_api_key_here"Las entregas al endpoint se detienen de inmediato.
| Evento | Se dispara cuando… |
|---|---|
credential.issued | Se emite una credencial a un destinatario. |
credential.delivered | Se envía al destinatario el correo de notificación de una credencial (individual o en lote). |
credential.revoked | Se revoca una credencial. |
credential.viewed | Se visualiza por primera vez la página pública de la credencial de un destinatario. |
Cada entrega es un POST con un cuerpo JSON de esta forma:
{
"id": "b1c2d3e4-...",
"type": "credential.issued",
"createdAt": 1787685415083,
"data": { }
}| Campo | Descripción |
|---|---|
id | Id único de la entrega (úsalo para eliminar duplicados). |
type | El tipo de evento. |
createdAt | Marca de tiempo del evento (milisegundos epoch). |
data | Payload específico del evento (ver más abajo). |
data por tipo de evento credential.issued
{
"awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
"badgeId": "https://api.badges.ninja/certify-badge/badge/<guid>",
"badgeName": "Advanced Certification",
"recipient": { "email": "jane@example.com", "name": "Jane Doe" },
"issuedOn": "2026-08-25",
"expires": null
}credential.delivered
{
"awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
"recipient": { "email": "jane@example.com", "name": "Jane Doe" },
"badgeName": "Advanced Certification"
}credential.revoked
{ "awardId": "https://api.badges.ninja/certify-badge/award/<guid>", "reason": "Issued in error" }credential.viewed
{
"awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
"recipient": { "email": "jane@example.com", "name": "Jane Doe" }
}Cada entrega incluye estas cabeceras:
| Cabecera | Descripción |
|---|---|
X-Bws-Event | El tipo de evento (igual que type en el cuerpo). |
X-Bws-Delivery | El id de la entrega (igual que id en el cuerpo). |
X-Bws-Signature | sha256= seguido del HMAC-SHA256 del cuerpo bruto de la solicitud, con clave el secreto de tu endpoint. |
User-Agent | badges.ninja-webhooks/1 |
Verifica siempre la firma antes de confiar en una entrega. Calcula el HMAC-SHA256 del cuerpo bruto de la solicitud usando el secreto de firma de tu endpoint y compáralo (en tiempo constante) con la cabecera X-Bws-Signature.
import crypto from "node:crypto";
function verify(rawBody, signatureHeader, secret) {
const expected = "sha256=" +
crypto.createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
const a = Buffer.from(signatureHeader);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Usa exactamente los bytes que has recibido: analizar y volver a serializar el JSON antes cambiará los bytes y romperá la firma.
2xx.failureCount; tras 20 fallos consecutivos, un endpoint se desactiva automáticamente (active: false) y deja de recibir entregas hasta que lo arregles y registres un nuevo endpoint.X-Bws-Delivery (o el id del cuerpo) para hacer que tu manejador sea idempotente.También puedes gestionar los endpoints sin la API: abre Webhooks en la barra lateral del panel para añadir, listar y eliminar endpoints y elegir qué eventos recibe cada uno.