通过 Badges Ninja REST API 颁发 Open Badges:快速入门

认证身份、创建颁发者、设计或上传徽章,再把它颁发给接收者——全部通过 REST 完成。附 JavaScript 和 Python 示例。

Nacho Coll 作者 更新于 15 分钟阅读
认证身份、创建颁发者、设计或上传徽章,再把它颁发给接收者——全部通过 REST 完成。附 JavaScript 和 Python 示例。

大多数证书项目其实用不上 API。如果你开设的课程每年只有几百名毕业生,控制台就能搞定一切:在可视化设计器里设计数字徽章,上传一个 CSV,每位接收者都会得到一个验证页面和一份 PDF 证书。如果你的情况正是如此,请先看如何通过 CSV 颁发 Open Badges,以后再回来。

当证书需要由其他系统来颁发时,API 就派上用场了:你的学习平台把某门课程标记为完成,你的报名工具结束了一场活动,你的 HR 系统记录下一个已完成的合规模块。在这些场景里,没人愿意每周末都导出一次电子表格。在完成的那一刻发起一次 HTTP 调用要简单得多,接收者也能在成就还新鲜的时候拿到数字徽章。

本快速入门用四次调用走完整个流程:获取密钥、创建颁发者、创建徽章、颁发徽章。之后我们再看如何把验证链接交给接收者,以及如何检查结果。下面所有请求格式都来自已部署的 handler,所以你可以直接复制并运行。

开始之前你需要准备什么

  • 一个 badges.ninja 的免费账号。Free 套餐足够完成本教程:它包含 2 个颁发者、5 个徽章、2 个席位和 1 个 API 密钥。
  • 一个在控制台中创建的 API 密钥。
  • 一张用作徽章图像的 PNG 或 JPG,或者一个你在可视化设计器中设计好的徽章。

所有请求的基础 URL 都是 https://api.badges.ninja。

第 1 步:创建 API 密钥

登录后,在侧边栏打开 API Keys,点击 Create API Key。给它起一个能说明用途的名字,比如 “LMS integration”,这样以后轮换密钥时你就能分清它们。

Newly created key revealed once

密钥只会显示一次。请立即把它复制到你的密钥管理器或环境变量中。密钥以 bws_ 开头,后面跟 32 个十六进制字符,每次请求都要把它放在 X-Api-Key 请求头里发送。在同一个界面中吊销密钥会立即生效。

几个能省去日后麻烦的习惯:

  • 永远不要把密钥放进前端代码或公开仓库。请从服务器、无服务器函数或自动化工具中调用 API。
  • 每个集成使用一个密钥。一旦某个密钥泄露,你只需要吊销这一个集成,而不是全部。
  • 控制台也接受你已登录的会话(以 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,后者会在你的公开证书页面上启用 Add to LinkedIn Profile 按钮。

响应中包含颁发者标识符:

{
  "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)

这五个字段(name、description、criteria、image、issuerId)都是必填的。另有两个值得了解的可选字段:shareText,即接收者在社交网络上分享时看到的默认文案(支持 {{badge_name}}、{{issuer_name}} 和 {{award_url}} 占位符);以及 designJson,它保存可视化设计器的文档,以便之后可以逐图层编辑徽章。

成功时会返回 HTTP 200 和 { "badgeId": "<id>" }。图像会被永久保存,这个徽章现在就是一个任何人都可以获取的 Open Badge v2.0 BadgeClass。

到底该不该用代码创建徽章?

通常不该。徽章设计是创意工作,可视化设计器(80 多个模板、形状、图标、11 种字体以及自定义上传)比脚本合适得多。常见的做法是:在控制台里把每个徽章设计一次,然后让你的集成只针对它颁发授予。你可以用 GET /badges 列出你的徽章,并复制所需徽章的 id。

当你需要以编程方式生成徽章时,例如为拥有数百门课程的目录每门课程生成一个,或者在搭建测试环境时,再通过 API 创建徽章。

第 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。

两者都是公开的。任何拿到链接的人都无需创建账号就能验证这份证书,这正是关键所在:雇主或招生官应该能在十秒内查验一枚徽章。

获取这份 JSON,看看外界看到的是什么:

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

你会得到一个 Open Badge v2.0 Assertion:它所引用的徽章、经过哈希的接收者身份、颁发日期,以及一个指回托管 assertion 的验证块。由于这是标准的 Open Badges 数据,任何理解该格式的工具都能读取。这种可移植性正是选择 Open Badges 而不是专有 PDF 的原因;Open Badges vs PDF certificates 对这一取舍有更深入的讨论。

接收者如何收到证书

创建授予和通知接收者是两件事。接收者可以通过接收者门户 badges.ninja/me 打开自己的证书,该门户使用免密码的魔法链接登录,他们还可以在 badges.ninja/u/<handle> 发布公开主页。在验证页面上,他们可以把徽章添加到 LinkedIn、下载 PDF 证书,或分享链接。

最初几次测试时,用你自己的邮箱给自己颁发一个徽章,亲自走一遍接收者的体验。这是发现徽章描述读起来别扭之类问题的最快办法。

不会让你头疼的错误处理

API 使用常规的 HTTP 状态码。你会遇到的有:

Status含义该怎么做
200成功读取 JSON 响应体
400字段缺失或无效,包括接收者姓名少于 5 个字符修正请求内容;重试同样的请求还会失败
401API 密钥缺失或错误检查 X-Api-Key 请求头,以及密钥是否已被吊销
402额度或套餐配额用完升级套餐,或等待下一个配额周期
404未找到该徽章检查你传入的 badgeId

两条实用建议。第一,把 400 当作数据问题,并记录响应体,因为它会指明出错的字段。第二,在你这一侧实现幂等:把 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 个席位、1 个 API 密钥,以及每年 1,200 份证书。Starter 为每月 $9,Pro 为每月 $29,限额更高。在规划部署规模之前,请查看定价页面了解当前数字。如果你在比较其他平台对 API 访问的收费,Credly alternative 把各家的费用并排列了出来。

接下来去哪里

  • 完整的端点参考位于 API 文档,提供 40 种语言版本。
  • 关于认证和密钥处理的细节,请参阅认证指南。
  • 关于错误码的详细说明,请参阅错误参考。
  • 当一次一个调用不够用时,请使用控制台中的批量颁发:上传一个 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.

返回博客

相关文章