Badges Ninja REST API で Open Badges を発行する:クイックスタート

認証、発行者の作成、バッジのデザインまたはアップロード、受領者への付与まで、すべて REST で完結します。JavaScript と Python のサンプル付きです。

Nacho Coll 著者: 更新日 18 分で読了
認証、発行者の作成、バッジのデザインまたはアップロード、受領者への付与まで、すべて REST で完結します。JavaScript と Python のサンプル付きです。

ほとんどの資格認定プログラムに API は必要ありません。年間の修了者が数百人程度のコースであれば、ダッシュボードだけですべて済みます。ビジュアルデザイナーでバッジをデザインし、CSV をアップロードすれば、受領者全員に検証ページと PDF 証明書が届きます。そのような場合は、まずCSV から Open Badges を発行する方法から始めて、API はあとで検討してください。

API が力を発揮するのは、別のシステムから資格情報を発行したいときです。たとえば、学習プラットフォームがコースの修了を記録したとき、登録ツールがイベントを締め切ったとき、人事システムがコンプライアンス研修の修了を記録したときなどです。毎週末にスプレッドシートを書き出したい人はいません。修了した瞬間に HTTP コールを 1 回送るほうがシンプルですし、受領者も達成の記憶が新しいうちにバッジを受け取れます。

このクイックスタートでは、キーの取得、発行者の作成、バッジの作成、バッジの付与という 4 つのコールで全体の流れを説明します。そのあと、検証リンクを受領者に渡す方法と、結果の確認方法も見ていきます。以下のリクエスト形式はすべて、実際にデプロイされているハンドラーに基づいているので、そのままコピーして実行できます。

始める前に必要なもの

  • badges.ninja の無料アカウント。このチュートリアルなら Free プランで十分です。発行者 2 件、バッジ 5 件、シート 2 つ、API キー 1 つが含まれています。
  • ダッシュボードで作成した API キー 1 つ。
  • バッジ用の PNG または JPG 画像、もしくはビジュアルデザイナーでデザインしたバッジ。

すべてのベース URL は https://api.badges.ninja です。

ステップ 1:API キーを作成する

サインインして、サイドバーの API Keys を開き、Create API Key をクリックします。あとでキーをローテーションするときに区別できるよう、「LMS integration」のように、使用場所がわかる名前を付けましょう。

Newly created key revealed once

キーが表示されるのは一度きりです。すぐにシークレットマネージャーか環境変数にコピーしてください。キーは bws_ に 32 桁の 16 進数が続く形式で、すべてのリクエストの X-Api-Key ヘッダーに付けて送ります。同じ画面からキーを無効化すると、即座に反映されます。

あとで困らないための習慣をいくつか紹介します。

  • キーをフロントエンドのコードや公開リポジトリに置かないでください。API の呼び出しは、サーバー、サーバーレス関数、または自動化ツールから行います。
  • 連携ごとにキーを 1 つ使いましょう。キーが漏えいしても、無効化するのはその連携 1 つだけで済みます。
  • ダッシュボードでは、サインイン済みのセッション(Authorization: Bearer で送る Cognito JWT)も使えますが、スクリプトや連携には API キーが適しています。

以下のサンプルはすべて、BADGES_API_KEY という環境変数からキーを読み込みます。

ステップ 2:発行者を作成する

発行者は、バッジの発行元となる組織です。すべての検証ページと Open Badge v2.0 のデータに表示されるため、人々によく知られた名前を使ってください。

curl -X POST https://api.badges.ninja/issuers \
  -H "X-Api-Key: $BADGES_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme Academy","url":"https://acme.example.com","email":"badges@acme.example.com"}'

必須フィールドは name(3 文字以上)、url(有効な http または https のアドレス)、email です。任意フィールドは logo(base64 エンコードした画像)と linkedinOrganizationId で、後者を指定すると公開資格情報ページに「LinkedIn プロフィールに追加」ボタンが表示されます。

レスポンスには発行者の識別子が含まれます。

{
  "issuerId": "https://api.badges.ninja/certify-badge/issuer/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

この値は返されたとおりに保管してください。次のステップの入力になります。

発行者の検証

バッジを作成できるのは、検証済みの発行者のもとだけです。検証は次のように行われます。

  • 発行者のメールアドレスがアカウントのメールアドレスと一致する場合、発行者は自動的に検証されます。最初のテストでは、これが最も手早い方法です。
  • メールアドレスが異なる場合は、コード付きの検証メールがそのアドレスに届きます。バッジを作成する前に、ダッシュボード(または発行者 API)でそのコードを確認してください。

そのため、このチュートリアルでは、サインアップに使ったのと同じメールアドレスを使ってください。

ステップ 3:バッジを作成する

バッジは再利用できるテンプレートで、名前、説明、取得基準、画像で構成されます。あとで発行する個々の付与は、すべてこのバッジを参照します。

リクエストはシンプルな JSON です。画像は base64 文字列として渡すので、multipart アップロードで悩む必要はありません。data:image/png;base64, のような data URL プレフィックスも受け付けられ、自動的に取り除かれます。

JavaScript(Node 18 以降):

import { readFileSync } from "node:fs";
const API_KEY = process.env.BADGES_API_KEY;
const image = readFileSync("./badge.png").toString("base64");
const res = await fetch("https://api.badges.ninja/badges", {
  method: "POST",
  headers: { "X-Api-Key": API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "JavaScript Fundamentals",
    description: "Demonstrates proficiency in core JavaScript concepts",
    criteria: "Completed the JavaScript Fundamentals course with a score of 80% or higher",
    image,
    issuerId: "https://api.badges.ninja/certify-badge/issuer/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  }),
});
const { badgeId } = await res.json();
console.log(badgeId);

Python:

import base64, os, requests
API_KEY = os.environ["BADGES_API_KEY"]
with open("badge.png", "rb") as f:
    image = base64.b64encode(f.read()).decode()
res = requests.post(
    "https://api.badges.ninja/badges",
    headers={"X-Api-Key": API_KEY},
    json={
        "name": "JavaScript Fundamentals",
        "description": "Demonstrates proficiency in core JavaScript concepts",
        "criteria": "Completed the JavaScript Fundamentals course with a score of 80% or higher",
        "image": image,
        "issuerId": "https://api.badges.ninja/certify-badge/issuer/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    },
)
badge_id = res.json()["badgeId"]
print(badge_id)

5 つのフィールド(name、description、criteria、image、issuerId)はすべて必須です。知っておくと便利な任意フィールドが 2 つあります。1 つは shareText で、受領者がソーシャルネットワークで共有するときのデフォルトのテキストです({{badge_name}}、{{issuer_name}}、{{award_url}} のプレースホルダーが使えます)。もう 1 つは designJson で、ビジュアルデザイナーのドキュメントを保存しておくと、あとでレイヤー単位でバッジを編集できます。

成功すると、HTTP 200 と { "badgeId": "<id>" } が返ります。画像は永続的に保存され、バッジは誰でも取得できる Open Badge v2.0 の BadgeClass になります。

そもそもコードでバッジを作るべきか

通常は不要です。バッジのデザインはクリエイティブな作業なので、スクリプトよりもビジュアルデザイナー(80 種類以上のテンプレート、シェイプ、アイコン、11 種類のフォント、カスタムアップロードに対応)のほうがはるかに向いています。よくあるパターンは、ダッシュボードで各バッジを一度だけデザインし、連携側ではそのバッジに対する付与だけを行うというものです。GET /badges でバッジの一覧を取得し、目的のバッジの id をコピーできます。

API でバッジを作成するのは、プログラムで生成する場合に向いています。たとえば、数百件あるカタログのコースごとに 1 つずつ作る場合や、テスト環境を準備する場合です。

ステップ 4:バッジを付与する

連携が何千回も実行するのが、このコールです。バッジ、受領者、日付を送信します。

curl:

curl -X POST https://api.badges.ninja/awards \
  -H "X-Api-Key: $BADGES_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"badgeId":"<badge-id>","recipient":{"name":"Jane Smith","email":"jane@example.com"},"issuedOn":"2026-09-28"}'

JavaScript:

const res = await fetch("https://api.badges.ninja/awards", {
  method: "POST",
  headers: { "X-Api-Key": API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    badgeId,
    recipient: { name: "Jane Smith", email: "jane@example.com" },
    issuedOn: Date.now(),
  }),
});
const { awardId } = await res.json();

Python:

import time, requests
res = requests.post(
    "https://api.badges.ninja/awards",
    headers={"X-Api-Key": API_KEY},
    json={
        "badgeId": badge_id,
        "recipient": {"name": "Jane Smith", "email": "jane@example.com"},
        "issuedOn": int(time.time() * 1000),
    },
)
award_id = res.json()["awardId"]

つまずきやすいルールは次のとおりです。

  • recipient は name と email を持つネストされたオブジェクトです。recipientEmail のようなフラットなフィールドは拒否されます。
  • recipient.name は 5 文字以上にする必要があります。
  • issuedOn は必須です。エポックミリ秒、または 2026-09-28 のような ISO 日付文字列で送ってください。
  • expires は任意で、同じ形式を受け付けます。

成功すると HTTP 200 が返り、本文に awardId が含まれます。受領者のメールアドレスは、Open Badge データ内では SHA-256 ハッシュとして保存されるため、公開 JSON に表示されることはありません。

ステップ 5:検証ページと Open Badge JSON を確認する

付与のレスポンスで返ってくるのは識別子であり、すぐに使えるリンクではありません。識別子の末尾は GUID になっていて、公開ページはこの GUID から組み立てられます。

  • 人が読める検証ページ:https://badges.ninja/awards/<awardId>
  • Open Badge v2.0 JSON-LD:https://api.badges.ninja/certify-badge/award/<awardId>

awardId が完全な URL で返ってきた場合は、パスの最後のセグメントを GUID として使ってください。

どちらも公開されています。リンクを知っていれば、誰でもアカウントを作らずに資格情報を検証できます。これが重要なポイントで、雇用主や入学審査の担当者が 10 秒でバッジを確認できるべきだからです。

JSON を取得して、世間から見える内容を確認してみましょう。

curl https://api.badges.ninja/certify-badge/award/<awardId>

返ってくるのは Open Badge v2.0 の Assertion です。参照先のバッジ、ハッシュ化された受領者の識別情報、発行日、ホストされた Assertion を指す検証ブロックが含まれています。標準の Open Badges データなので、この形式に対応するツールならどれでも読み取れます。この可搬性こそ、独自形式の PDF ではなく Open Badges を選ぶ理由です。トレードオフについては、Open Badges と PDF 証明書の比較で詳しく説明しています。

受領者が資格情報を受け取る方法

付与を作成することと、受領者に知らせることは別の話です。受領者は、badges.ninja/me の受領者ポータルから自分の資格情報を開けます。ポータルはパスワード不要のマジックリンクでサインインでき、badges.ninja/u/<handle> で公開プロフィールも公開できます。検証ページからは、バッジを LinkedIn に追加したり、PDF 証明書をダウンロードしたり、リンクを共有したりできます。

最初の数回のテストでは、自分のメールアドレスで付与を送り、受領者の体験を一通りたどってみてください。バッジの説明文が不自然に読めるといった点に気づくには、これが最も手早い方法です。

面倒にならないエラー処理

API は一般的な HTTP ステータスコードを使います。遭遇するのは次のコードです。

ステータス意味対処
200成功JSON 本文を読む
400フィールドの不足または不正(5 文字未満の受領者名を含む)ペイロードを修正する。同じリクエストを再試行しても再び失敗する
401API キーがない、または誤っているX-Api-Key ヘッダーと、キーが無効化されていないかを確認する
402クレジットまたはプランの上限を超過プランをアップグレードするか、次の上限期間まで待つ
404バッジが見つからない渡した badgeId を確認する

実践的なヒントが 2 つあります。1 つ目は、400 はデータの問題として扱い、レスポンス本文をログに残すことです。本文には失敗したフィールドが示されています。2 つ目は、連携側で冪等性を確保することです。awardId を自社のデータベースの修了記録と一緒に保存し、API を再度呼び出す前にその有無を確認してください。そうすれば、Webhook の再送やジョブの再実行があっても、同じ人に資格情報を二重に発行することはありません。

実際の連携としてまとめる

典型的な構成は次のとおりです。

  1. ダッシュボードでコースやマイルストーンごとにバッジをデザインし、各バッジ ID を控えておきます。
  2. 自社システムに、コースからバッジ ID へのマッピングを保存します。
  3. 学習者がコースを修了したら、サーバーが氏名、メールアドレス、修了日を付けて POST /awards を呼び出します。
  4. 返された awardId を修了記録に紐づけて保存します。
  5. 自社プロダクトの中に検証リンクを表示し、学習者がその場で確認できるようにします。

コードを書きたくない場合は、JSON 本文とカスタムヘッダーを付けて HTTP リクエストを送れる自動化ツールなら、同じコールが使えます。https://api.badges.ninja/awards を指定し、フォームやスプレッドシートのフィールドを badgeId、recipient.name、recipient.email、issuedOn に対応付けてください。

知っておきたいプランと上限

API はすべてのプランで利用でき、使うために追加料金はかかりません。Free プラン($0)には、発行者 2 件、バッジ 5 件、シート 2 つ、API キー 1 つ、年間 1,200 件の資格情報が含まれます。Starter は月額 $9、Pro は月額 $29 で、上限がさらに高くなります。導入規模を見積もる前に、料金ページで最新の数字を確認してください。他のプラットフォームの API 利用料金と比較したい場合は、Credly の代替サービスで費用を並べて紹介しています。

次のステップ

  • エンドポイントの完全なリファレンスは、40 言語で利用できるAPI ドキュメントにあります。
  • 認証の詳細とキーの扱いについては、認証ガイドをご覧ください。
  • エラーコードの詳細については、エラーリファレンスをご覧ください。
  • 1 件ずつのコールでは手が回らなくなったら、ダッシュボードの一括付与を使いましょう。CSV をアップロードすれば、必要に応じて実行を一時停止したり再開したりできます。

最初の付与が成功するまでが一番の山場です。それ以降は、達成が記録される場所に同じコールを組み込んでいくだけです。

最初の検証可能な資格情報を発行する準備はできましたか? badges.ninja で無料で始める — ビジュアルデザイナー、公開検証ページ、PDF 証明書、Open Badge v2.0 出力。クレジットカードは不要です。

Nacho Coll

著者について

Founder & Engineer at Badges Ninja

Nacho founded Badges Ninja to make issuing verifiable digital credentials as simple as a single API call — Open Badge v2.0 badges and certificates, minted, hosted, and verifiable without standing up your own issuer infrastructure. Writes about the Open Badges spec, credential verification, and running a credentialing platform serverless on AWS, from the operator side of the wire.

ブログに戻る

関連記事