Skip to content

API de Webhooks

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.

Registrar un endpoint

POST /webhooks

Parámetros

ParámetroTipoObligatorioDescripción
urlstringTu endpoint HTTPS. Debe empezar por https://.
eventsstring[]NoTipos de evento a los que suscribirse. Omítelo o pasa ["*"] para recibir todos los eventos.

Ejemplo

bash
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"]
  }'

Respuesta

201 Created. El secreto de firma se devuelve una sola vez: guárdalo ahora; no podrás recuperarlo de nuevo.

json
{
  "id": "e4b19ff5-063d-4799-bd75-d03641be624f",
  "url": "https://example.com/hooks/badges",
  "events": ["credential.issued", "credential.delivered"],
  "secret": "2be6d335682c1658242fde3a523fd8a2493bab8c"
}

Listar endpoints

GET /webhooks

Devuelve tus endpoints registrados. Los secretos de firma nunca se incluyen.

json
{
  "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
    }
  ]
}

Eliminar un endpoint

DELETE /webhooks/{id}
bash
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.

Tipos de evento

EventoSe dispara cuando…
credential.issuedSe emite una credencial a un destinatario.
credential.deliveredSe envía al destinatario el correo de notificación de una credencial (individual o en lote).
credential.revokedSe revoca una credencial.
credential.viewedSe visualiza por primera vez la página pública de la credencial de un destinatario.

Cuerpo de la entrega (payload)

Cada entrega es un POST con un cuerpo JSON de esta forma:

json
{
  "id": "b1c2d3e4-...",
  "type": "credential.issued",
  "createdAt": 1787685415083,
  "data": { }
}
CampoDescripción
idId único de la entrega (úsalo para eliminar duplicados).
typeEl tipo de evento.
createdAtMarca de tiempo del evento (milisegundos epoch).
dataPayload específico del evento (ver más abajo).

data por tipo de evento

credential.issued

json
{
  "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

json
{
  "awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
  "recipient": { "email": "jane@example.com", "name": "Jane Doe" },
  "badgeName": "Advanced Certification"
}

credential.revoked

json
{ "awardId": "https://api.badges.ninja/certify-badge/award/<guid>", "reason": "Issued in error" }

credential.viewed

json
{
  "awardId": "https://api.badges.ninja/certify-badge/award/<guid>",
  "recipient": { "email": "jane@example.com", "name": "Jane Doe" }
}

Cabeceras de la solicitud

Cada entrega incluye estas cabeceras:

CabeceraDescripción
X-Bws-EventEl tipo de evento (igual que type en el cuerpo).
X-Bws-DeliveryEl id de la entrega (igual que id en el cuerpo).
X-Bws-Signaturesha256= seguido del HMAC-SHA256 del cuerpo bruto de la solicitud, con clave el secreto de tu endpoint.
User-Agentbadges.ninja-webhooks/1

Verificar firmas

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.

js
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.

Reintentos y fiabilidad

  • Una entrega se considera correcta cuando tu endpoint responde con un estado 2xx.
  • Las entregas fallidas se reintentan un número reducido de veces. Los endpoints que siguen fallando acumulan un 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.
  • Las entregas pueden llegar más de una vez. Usa el id X-Bws-Delivery (o el id del cuerpo) para hacer que tu manejador sea idempotente.
  • Responde con rapidez (en unos ~10 segundos). Realiza el trabajo pesado de forma asíncrona tras confirmar la recepción.

Gestionar webhooks en el panel

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.

badges.ninja Documentation