日本語
日本語
Appearance
日本語
日本語
Appearance
Webhooks は、クレデンシャルに何かが起きたとき——発行、配信、失効、閲覧されたとき——にアプリケーションへリアルタイムで通知します。API をポーリングする代わりに、HTTPS エンドポイントを登録すると、badges.ninja が購読している各イベントごとに署名付きの POST を送信します。
すべての管理エンドポイントは X-Api-Key ヘッダーによる認証が必要です。認証 を参照してください。エンドポイントの作成または削除には write スコープを持つキーが必要で、一覧取得には read が必要です。API キー を参照してください。
POST /webhooks| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
url | string | はい | あなたの HTTPS エンドポイント。https:// で始まる必要があります。 |
events | string[] | いいえ | 購読するイベントタイプ。省略するか ["*"] を渡すとすべてのイベントを受信します。 |
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。署名シークレットは一度だけ返されます——今すぐ保存してください。再取得することはできません。
{
"id": "e4b19ff5-063d-4799-bd75-d03641be624f",
"url": "https://example.com/hooks/badges",
"events": ["credential.issued", "credential.delivered"],
"secret": "2be6d335682c1658242fde3a523fd8a2493bab8c"
}GET /webhooks登録済みのエンドポイントを返します。署名シークレットが含まれることはありません。
{
"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"そのエンドポイントへの配信は直ちに停止します。
| イベント | 発火するタイミング… |
|---|---|
credential.issued | クレデンシャルが受信者に発行されたとき。 |
credential.delivered | クレデンシャルの通知メールが受信者に送信されたとき(単一または一括)。 |
credential.revoked | クレデンシャルが失効したとき。 |
credential.viewed | 受信者の公開クレデンシャルページが 初めて 閲覧されたとき。 |
すべての配信は、次の形状の JSON 本文を持つ POST です:
{
"id": "b1c2d3e4-...",
"type": "credential.issued",
"createdAt": 1787685415083,
"data": { }
}| フィールド | 説明 |
|---|---|
id | 一意の配信 id(重複排除に使用します)。 |
type | イベントタイプ。 |
createdAt | イベントのタイムスタンプ(エポックミリ秒)。 |
data | イベント固有のペイロード(下記参照)。 |
data 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" }
}各配信は次のヘッダーを持ちます:
| ヘッダー | 説明 |
|---|---|
X-Bws-Event | イベントタイプ(本文の type と同じ)。 |
X-Bws-Delivery | 配信 id(本文の id と同じ)。 |
X-Bws-Signature | sha256= に続けて、あなたのエンドポイントシークレットを鍵とした、生のリクエスト本文の HMAC-SHA256。 |
User-Agent | badges.ninja-webhooks/1 |
配信を信頼する前に、必ず署名を検証してください。エンドポイントの署名シークレットを使って 生のリクエスト本文 の HMAC-SHA256 を計算し、それを(定数時間で)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);
}受信したバイトそのものを使用してください——先に JSON をパースして再シリアライズすると、バイトが変わり署名が壊れます。
2xx ステータスで応答すると、配信は成功とみなされます。failureCount を蓄積し、20 回連続で失敗するとエンドポイントは 自動的に無効化 され(active: false)、修正して新しいエンドポイントを登録するまで配信の受信を停止します。X-Bws-Delivery id(または本文の id)を使ってハンドラーを冪等にしてください。API を使わずにエンドポイントを管理することもできます——ダッシュボードのサイドバーで Webhooks を開くと、エンドポイントの追加、一覧表示、削除ができ、各エンドポイントが受信するイベントを選択できます。