Skip to content

Webhooks API

Веб-хуки уведомляют ваше приложение в реальном времени о событиях, происходящих с вашими учётными данными, — когда они выданы, доставлены, отозваны или просмотрены. Вместо опроса API вы регистрируете HTTPS-эндпоинт, и badges.ninja отправляет на него подписанный POST для каждого события, на которое вы подписаны.

Все управляющие эндпоинты требуют аутентификации через заголовок X-Api-Key. См. Аутентификация. Создание или удаление эндпоинтов требует ключа с областью доступа write; для получения списка нужна read. См. Ключи API.

Регистрация эндпоинта

POST /webhooks

Параметры

ПараметрТипОбязательныйОписание
urlstringДаВаш HTTPS-эндпоинт. Должен начинаться с https://.
eventsstring[]НетТипы событий, на которые нужно подписаться. Опустите или передайте ["*"], чтобы получать все события.

Пример

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

Ответ

201 Created. Секрет подписи возвращается только один раз — сохраните его сейчас; получить его повторно нельзя.

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

Список эндпоинтов

GET /webhooks

Возвращает ваши зарегистрированные эндпоинты. Секреты подписи никогда не включаются.

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
    }
  ]
}

Удаление эндпоинта

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"

Доставка на этот эндпоинт прекращается немедленно.

Типы событий

СобытиеСрабатывает, когда…
credential.issuedУчётные данные выданы получателю.
credential.deliveredПисьмо с уведомлением об учётных данных отправлено получателю (одиночно или массово).
credential.revokedУчётные данные отозваны.
credential.viewedПубличная страница учётных данных получателя просмотрена в первый раз.

Полезная нагрузка доставки

Каждая доставка — это POST с телом в формате JSON следующего вида:

json
{
  "id": "b1c2d3e4-...",
  "type": "credential.issued",
  "createdAt": 1787685415083,
  "data": { }
}
ПолеОписание
idУникальный идентификатор доставки (используйте его для дедупликации).
typeТип события.
createdAtМетка времени события (миллисекунды эпохи).
dataПолезная нагрузка, зависящая от события (см. ниже).

data по типам событий

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" }
}

Заголовки запроса

Каждая доставка несёт эти заголовки:

ЗаголовокОписание
X-Bws-EventТип события (тот же, что type в теле).
X-Bws-DeliveryИдентификатор доставки (тот же, что id в теле).
X-Bws-Signaturesha256=, за которым следует HMAC-SHA256 сырого тела запроса, вычисленный с ключом — секретом вашего эндпоинта.
User-Agentbadges.ninja-webhooks/1

Проверка подписей

Всегда проверяйте подпись, прежде чем доверять доставке. Вычислите HMAC-SHA256 сырого тела запроса, используя секрет подписи вашего эндпоинта, и сравните его (за постоянное время) с заголовком 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);
}

Используйте ровно те байты, которые вы получили, — разбор и повторная сериализация JSON изменят байты и нарушат подпись.

Повторные попытки и надёжность

  • Доставка считается успешной, когда ваш эндпоинт отвечает статусом 2xx.
  • Неудачные доставки повторяются небольшое число раз. Эндпоинты, которые продолжают давать сбой, накапливают failureCount; после 20 последовательных сбоев эндпоинт автоматически отключается (active: false) и перестаёт получать доставки, пока вы не устраните проблему и не зарегистрируете новый эндпоинт.
  • Доставки могут приходить более одного раза. Используйте идентификатор X-Bws-Delivery (или id из тела), чтобы сделать ваш обработчик идемпотентным.
  • Отвечайте быстро (в пределах ~10 секунд). Выполняйте тяжёлую работу асинхронно после подтверждения.

Управление веб-хуками в панели

Вы также можете управлять эндпоинтами без API — откройте Webhooks в боковом меню панели, чтобы добавлять, просматривать и удалять эндпоинты и выбирать, какие события получает каждый из них.

badges.ninja Documentation