Skip to content

Webhooks API

當你的憑證發生某些事件時——被頒發、送達、撤銷或檢視——Webhooks 會即時通知你的應用程式。你無需輪詢 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唯一的投遞 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(與主體中的 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(或主體中的 id)使你的處理程式具有冪等性。
  • 快速回應(在約 10 秒內)。在確認之後再非同步執行繁重工作。

在儀表板中管理 Webhooks

你也可以不使用 API 來管理端點——在儀表板側邊欄開啟 Webhooks,即可新增、列出和刪除端點,並選擇每個端點接收哪些事件。

badges.ninja Documentation