Skip to content

Webhooks API

Webhooks thông báo cho ứng dụng của bạn theo thời gian thực khi có sự kiện xảy ra với chứng chỉ của bạn — khi một chứng chỉ được cấp, gửi đi, thu hồi hoặc được xem. Thay vì phải liên tục truy vấn API, bạn đăng ký một điểm cuối HTTPS và badges.ninja sẽ gửi tới đó một POST đã ký cho mỗi sự kiện mà bạn đăng ký.

Tất cả các điểm cuối quản lý đều yêu cầu xác thực qua header X-Api-Key. Xem Xác thực. Việc tạo hoặc xóa điểm cuối yêu cầu khóa có phạm vi write; việc liệt kê yêu cầu phạm vi read. Xem Khóa API.

Đăng ký điểm cuối

POST /webhooks

Tham số

Tham sốKiểuBắt buộcMô tả
urlstringĐiểm cuối HTTPS của bạn. Phải bắt đầu bằng https://.
eventsstring[]KhôngCác loại sự kiện muốn đăng ký. Bỏ trống hoặc truyền ["*"] để nhận tất cả các sự kiện.

Ví dụ

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

Phản hồi

201 Created. Khóa bí mật để ký chỉ được trả về một lần — hãy lưu ngay bây giờ; bạn không thể lấy lại nó nữa.

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

Liệt kê điểm cuối

GET /webhooks

Trả về các điểm cuối bạn đã đăng ký. Khóa bí mật để ký không bao giờ được bao gồm.

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

Xóa điểm cuối

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"

Việc gửi tới điểm cuối sẽ dừng lại ngay lập tức.

Các loại sự kiện

Sự kiệnKích hoạt khi…
credential.issuedMột chứng chỉ được cấp cho người nhận.
credential.deliveredEmail thông báo của một chứng chỉ được gửi tới người nhận (đơn lẻ hoặc hàng loạt).
credential.revokedMột chứng chỉ bị thu hồi.
credential.viewedTrang chứng chỉ công khai của người nhận được xem lần đầu tiên.

Payload gửi đi

Mỗi lần gửi là một POST với phần thân JSON có dạng sau:

json
{
  "id": "b1c2d3e4-...",
  "type": "credential.issued",
  "createdAt": 1787685415083,
  "data": { }
}
TrườngMô tả
idId gửi đi duy nhất (dùng để loại bỏ trùng lặp).
typeLoại sự kiện.
createdAtDấu thời gian sự kiện (mili-giây epoch).
dataPayload riêng theo từng sự kiện (xem bên dưới).

data theo loại sự kiện

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

Header của yêu cầu

Mỗi lần gửi mang theo các header sau:

HeaderMô tả
X-Bws-EventLoại sự kiện (giống với type trong phần thân).
X-Bws-DeliveryId lần gửi (giống với id trong phần thân).
X-Bws-Signaturesha256= theo sau là HMAC-SHA256 của phần thân yêu cầu thô, được ký bằng khóa bí mật của điểm cuối.
User-Agentbadges.ninja-webhooks/1

Xác minh chữ ký

Luôn xác minh chữ ký trước khi tin tưởng một lần gửi. Tính HMAC-SHA256 của phần thân yêu cầu thô bằng khóa bí mật ký của điểm cuối, rồi so sánh nó (theo thời gian hằng số) với header 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);
}

Hãy dùng đúng các byte bạn nhận được — việc phân tích và tuần tự hóa lại JSON trước sẽ làm thay đổi các byte và phá vỡ chữ ký.

Thử lại & độ tin cậy

  • Một lần gửi được coi là thành công khi điểm cuối của bạn phản hồi với trạng thái 2xx.
  • Các lần gửi thất bại sẽ được thử lại một vài lần. Những điểm cuối liên tục thất bại sẽ tích lũy một failureCount; sau 20 lần thất bại liên tiếp, một điểm cuối sẽ bị tự động vô hiệu hóa (active: false) và ngừng nhận các lần gửi cho đến khi bạn khắc phục và đăng ký một điểm cuối mới.
  • Các lần gửi có thể tới nhiều hơn một lần. Hãy dùng id X-Bws-Delivery (hoặc id trong phần thân) để làm cho trình xử lý của bạn có tính bất biến (idempotent).
  • Phản hồi nhanh (trong khoảng ~10 giây). Hãy thực hiện các công việc nặng theo cách bất đồng bộ sau khi đã xác nhận.

Quản lý webhooks trong bảng điều khiển

Bạn cũng có thể quản lý các điểm cuối mà không cần API — mở Webhooks trong thanh bên của bảng điều khiển để thêm, liệt kê và xóa điểm cuối cũng như chọn sự kiện nào mà mỗi điểm cuối sẽ nhận.

badges.ninja Documentation