Cấp Open Badges qua REST API của Badges Ninja: Hướng dẫn nhanh
Xác thực, tạo tổ chức cấp, thiết kế hoặc tải lên huy hiệu, rồi trao cho người nhận — tất cả qua REST. Có kèm ví dụ JavaScript và Python.
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.
Phần lớn các chương trình chứng nhận không bao giờ cần đến API. Nếu bạn chạy một khóa học với vài trăm học viên tốt nghiệp mỗi năm, bảng điều khiển đã lo đủ mọi thứ: bạn thiết kế huy hiệu trong trình thiết kế trực quan, tải lên một tệp CSV, và mỗi người nhận có ngay một trang xác minh cùng chứng chỉ PDF. Nếu đó là trường hợp của bạn, hãy bắt đầu với cách cấp Open Badges từ CSV rồi quay lại đây sau.
API chỉ phát huy giá trị khi chứng nhận cần được cấp bởi một hệ thống khác: nền tảng học tập của bạn đánh dấu hoàn thành khóa học, công cụ đăng ký đóng một sự kiện, hệ thống nhân sự ghi nhận một học phần tuân thủ đã xong. Trong những trường hợp này, không ai muốn xuất bảng tính vào cuối mỗi tuần. Một lệnh gọi HTTP ngay lúc hoàn thành đơn giản hơn nhiều, và người nhận có được huy hiệu khi thành tích còn mới nguyên.
Hướng dẫn nhanh này đi qua toàn bộ quy trình chỉ với bốn lệnh gọi: lấy khóa, tạo tổ chức cấp, tạo huy hiệu, trao huy hiệu. Sau đó chúng ta xem cách gửi liên kết xác minh cho người nhận và kiểm tra kết quả. Mọi cấu trúc yêu cầu dưới đây đều lấy từ các handler đang triển khai, nên bạn có thể dán vào và chạy ngay.
Bạn cần gì trước khi bắt đầu
- Một tài khoản miễn phí tại badges.ninja. Gói Free là đủ cho hướng dẫn này: gói gồm 2 tổ chức cấp, 5 huy hiệu, 2 chỗ ngồi và 1 khóa API.
- Một khóa API, tạo từ bảng điều khiển.
- Một ảnh PNG hoặc JPG cho huy hiệu, hoặc một huy hiệu bạn đã thiết kế trong trình thiết kế trực quan.
URL gốc cho mọi thứ là https://api.badges.ninja.
Bước 1: Tạo khóa API
Đăng nhập, mở API Keys ở thanh bên và nhấp Create API Key. Hãy đặt tên cho biết khóa sẽ dùng ở đâu, chẳng hạn “LMS integration”, để bạn phân biệt được các khóa khi xoay vòng sau này.

Khóa chỉ hiển thị đúng một lần. Hãy sao chép ngay vào trình quản lý bí mật hoặc một biến môi trường. Khóa có dạng bws_ theo sau là 32 ký tự thập lục phân, và bạn gửi nó trong header X-Api-Key ở mọi yêu cầu. Thu hồi khóa ngay trên cùng màn hình đó có hiệu lực tức thì.
Một vài thói quen giúp tránh rắc rối về sau:
- Đừng bao giờ đặt khóa trong mã front-end hay kho mã công khai. Hãy gọi API từ máy chủ, hàm serverless hoặc công cụ tự động hóa.
- Dùng mỗi khóa cho một tích hợp. Nếu một khóa bị lộ, bạn chỉ thu hồi một tích hợp thay vì tất cả.
- Bảng điều khiển cũng chấp nhận phiên đăng nhập của bạn (một Cognito JWT gửi dưới dạng
Authorization: Bearer), nhưng với script và tích hợp, khóa API mới là công cụ phù hợp.
Mọi ví dụ bên dưới đều đọc khóa từ một biến môi trường tên BADGES_API_KEY.
Bước 2: Tạo tổ chức cấp
Tổ chức cấp là đơn vị đứng sau huy hiệu. Tên này xuất hiện trên mọi trang xác minh và trong dữ liệu Open Badge v2.0, vì vậy hãy dùng tên mà mọi người thực sự biết đến.
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"}'
Các trường bắt buộc là name (ít nhất 3 ký tự), url (địa chỉ http hoặc https hợp lệ) và email. Các trường tùy chọn là logo (ảnh mã hóa base64) và linkedinOrganizationId, giúp bật nút Add to LinkedIn Profile trên các trang chứng nhận công khai của bạn.
Phản hồi chứa mã định danh của tổ chức cấp:
{
"issuerId": "https://api.badges.ninja/certify-badge/issuer/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Hãy giữ nguyên giá trị đó đúng như được trả về. Nó là đầu vào cho bước kế tiếp.
Xác minh tổ chức cấp
Huy hiệu chỉ có thể được tạo dưới một tổ chức cấp đã xác minh. Việc xác minh diễn ra như sau:
- Nếu email của tổ chức cấp trùng với email tài khoản của bạn, tổ chức cấp được xác minh tự động. Đây là đường nhanh nhất cho lần thử đầu tiên.
- Nếu email khác, một email xác minh kèm mã sẽ được gửi đến địa chỉ đó. Bạn xác nhận mã trong bảng điều khiển (hoặc qua API tổ chức cấp) trước khi tạo huy hiệu.
Vì vậy với hướng dẫn này, hãy dùng chính email bạn đã đăng ký.
Bước 3: Tạo huy hiệu
Huy hiệu là mẫu có thể tái sử dụng: tên, mô tả, tiêu chí và hình ảnh. Mỗi lần trao sau này sẽ trỏ về huy hiệu này.
Yêu cầu chỉ là JSON thuần. Hình ảnh được gửi dưới dạng chuỗi base64, nên không phải vật lộn với tải lên multipart. Tiền tố data URL như data:image/png;base64, được chấp nhận và sẽ bị loại bỏ.
JavaScript (Node 18 trở lên):
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)
Cả năm trường (name, description, criteria, image, issuerId) đều bắt buộc. Có hai trường tùy chọn đáng biết: shareText, đoạn văn bản mặc định người nhận thấy khi chia sẻ lên mạng xã hội (hỗ trợ các placeholder {{badge_name}}, {{issuer_name}} và {{award_url}}), và designJson, lưu một tài liệu của trình thiết kế trực quan để sau này có thể chỉnh sửa huy hiệu từng lớp một.
Thành công trả về HTTP 200 với { "badgeId": "<id>" }. Hình ảnh được lưu vĩnh viễn, và huy hiệu giờ là một BadgeClass Open Badge v2.0 mà ai cũng có thể truy xuất.
Có nên tạo huy hiệu bằng mã không?
Thường là không. Thiết kế huy hiệu là công việc sáng tạo, và trình thiết kế trực quan (80+ mẫu, hình dạng, biểu tượng, 11 phông chữ và tải lên tùy chỉnh) là nơi phù hợp hơn nhiều so với một script. Cách làm phổ biến là thiết kế mỗi huy hiệu một lần trong bảng điều khiển, rồi để tích hợp của bạn chỉ cấp các lượt trao dựa trên nó. Bạn có thể liệt kê huy hiệu bằng GET /badges và sao chép id của huy hiệu mình muốn.
Hãy tạo huy hiệu qua API khi bạn sinh chúng theo chương trình, ví dụ mỗi khóa học một huy hiệu trong danh mục hàng trăm khóa, hoặc khi bạn đang dựng dữ liệu cho môi trường thử nghiệm.
Bước 4: Trao huy hiệu
Đây là lệnh gọi mà tích hợp của bạn sẽ thực hiện hàng nghìn lần. Gửi huy hiệu, người nhận và ngày cấp.
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"]
Những quy tắc hay làm người ta vấp:
recipientlà một đối tượng lồng nhau gồmnamevàemail. Các trường phẳng nhưrecipientEmailsẽ bị từ chối.recipient.namephải có ít nhất 5 ký tự.issuedOnlà bắt buộc. Gửi epoch mili giây hoặc chuỗi ngày ISO như2026-09-28.expireslà tùy chọn và nhận cùng các định dạng.
Thành công là HTTP 200 với nội dung chứa awardId. Email người nhận được lưu dưới dạng băm SHA-256 trong dữ liệu Open Badge, nên JSON công khai không bao giờ để lộ nó.
Bước 5: Tìm trang xác minh và JSON Open Badge
Phản hồi của lượt trao cho bạn một mã định danh, chứ không phải một liên kết làm sẵn. Mã định danh kết thúc bằng một GUID, và các trang công khai được dựng từ GUID đó:
- Trang xác minh dễ đọc:
https://badges.ninja/awards/<awardId> - JSON-LD Open Badge v2.0:
https://api.badges.ninja/certify-badge/award/<awardId>
Nếu awardId của bạn trả về là một URL đầy đủ, hãy dùng đoạn đường dẫn cuối cùng làm GUID.
Cả hai đều công khai. Bất kỳ ai có liên kết đều có thể xác minh chứng nhận mà không cần tạo tài khoản, và đó chính là mục đích: nhà tuyển dụng hay cán bộ tuyển sinh phải kiểm tra được huy hiệu trong mười giây.
Hãy lấy JSON để xem thế giới nhìn thấy gì:
curl https://api.badges.ninja/certify-badge/award/<awardId>
Bạn nhận được một Assertion Open Badge v2.0: huy hiệu mà nó tham chiếu, danh tính người nhận đã được băm, ngày cấp, và một khối xác minh trỏ về assertion được lưu trữ. Vì đây là dữ liệu Open Badges chuẩn, mọi công cụ hiểu định dạng này đều đọc được. Khả năng di chuyển đó là lý do nên chọn Open Badges thay vì một tệp PDF độc quyền; Open Badges so với chứng chỉ PDF đi sâu hơn vào sự đánh đổi này.
Người nhận nhận chứng nhận như thế nào
Tạo lượt trao là một việc, thông báo cho người nhận là việc khác. Người nhận có thể mở các chứng nhận của mình qua cổng người nhận tại badges.ninja/me, nơi dùng đăng nhập bằng magic link không cần mật khẩu, và họ có thể công khai một hồ sơ tại badges.ninja/u/<handle>. Từ trang xác minh, họ có thể thêm huy hiệu vào LinkedIn, tải chứng chỉ PDF hoặc chia sẻ liên kết.
Trong vài lần thử đầu, hãy tự trao một huy hiệu cho chính email của bạn và trải nghiệm hành trình của người nhận. Đó là cách nhanh nhất để nhận ra những điều như phần mô tả huy hiệu đọc nghe gượng gạo.
Xử lý lỗi không đau đầu
API dùng các mã trạng thái HTTP thông thường. Những mã bạn sẽ gặp:
| Status | Ý nghĩa | Cần làm gì |
|---|---|---|
| 200 | Thành công | Đọc nội dung JSON |
| 400 | Thiếu hoặc sai một trường, kể cả tên người nhận dưới 5 ký tự | Sửa payload; thử lại cùng yêu cầu sẽ lại thất bại |
| 401 | Thiếu hoặc sai khóa API | Kiểm tra header X-Api-Key và xem khóa đã bị thu hồi chưa |
| 402 | Hết tín dụng hoặc hạn mức gói | Nâng cấp gói hoặc chờ kỳ hạn mức tiếp theo |
| 404 | Không tìm thấy huy hiệu | Kiểm tra badgeId bạn đã truyền |
Hai mẹo thực tế. Thứ nhất, hãy coi 400 là vấn đề dữ liệu và ghi log nội dung phản hồi, vì nó nêu rõ trường bị lỗi. Thứ hai, hãy làm cho tích hợp của bạn có tính lũy đẳng (idempotent) ở phía bạn: lưu awardId cạnh bản ghi hoàn thành trong cơ sở dữ liệu của bạn, và kiểm tra nó trước khi gọi API lần nữa. Nhờ vậy, một webhook được gửi lại hay một job chạy lại sẽ không bao giờ cấp cho cùng một người hai chứng nhận.
Ghép tất cả lại trong một tích hợp thực tế
Một cách nối điển hình trông như sau:
- Thiết kế huy hiệu trong bảng điều khiển, mỗi khóa học hoặc cột mốc một huy hiệu, và ghi lại ID của từng huy hiệu.
- Lưu một bảng ánh xạ từ khóa học sang ID huy hiệu trong hệ thống của bạn.
- Khi người học hoàn thành khóa học, máy chủ của bạn gọi
POST /awardsvới tên, email và ngày hoàn thành của họ. - Lưu
awardIdđược trả về vào bản ghi hoàn thành. - Hiển thị liên kết xác minh ngay trong sản phẩm của bạn, để người học thấy nó mà không phải rời đi.
Nếu bạn không muốn viết mã, cùng lệnh gọi này hoạt động từ bất kỳ công cụ tự động hóa nào có thể gửi yêu cầu HTTP với nội dung JSON và header tùy chỉnh. Hãy trỏ nó tới https://api.badges.ninja/awards và ánh xạ các trường biểu mẫu hoặc bảng tính của bạn vào badgeId, recipient.name, recipient.email và issuedOn.
Các gói và giới hạn đáng biết
API có sẵn ở mọi gói; bạn không phải trả thêm để mở khóa nó. Gói Free ($0) gồm 2 tổ chức cấp, 5 huy hiệu, 2 chỗ ngồi, 1 khóa API và 1.200 chứng nhận mỗi năm. Starter là $9 mỗi tháng và Pro là $29 mỗi tháng, với giới hạn cao hơn. Hãy xem trang giá để biết con số hiện hành trước khi bạn tính quy mô triển khai. Nếu bạn đang so sánh mức phí truy cập API của các nền tảng khác, Credly alternative trình bày các chi phí cạnh nhau.
Tiếp theo nên đi đâu
- Tài liệu tham chiếu đầy đủ về endpoint nằm trong tài liệu API, có sẵn bằng 40 ngôn ngữ.
- Về chi tiết xác thực và cách xử lý khóa, xem hướng dẫn xác thực.
- Về mã lỗi chuyên sâu, xem tài liệu tham chiếu lỗi.
- Khi gọi từng lệnh một không còn đủ, hãy dùng trao hàng loạt trong bảng điều khiển: tải lên một tệp CSV, và tạm dừng hoặc tiếp tục lượt chạy nếu cần.
Lượt trao thành công đầu tiên là phần khó nhất. Sau đó, phần còn lại chỉ là nối cùng một lệnh gọi vào những nơi thành tích vốn đã được ghi nhận.
Sẵn sàng cấp chứng nhận có thể xác minh đầu tiên của bạn? Bắt đầu miễn phí tại badges.ninja — trình thiết kế trực quan, trang xác minh công khai, chứng chỉ PDF, đầu ra Open Badge v2.0. Không cần thẻ tín dụng.
Bài viết này được thực hiện như thế nào
Một số bài viết trên blog này được soạn với sự hỗ trợ của trợ lý AI, sau đó được đội ngũ Badges Ninja xem xét, kiểm chứng và biên tập trước khi xuất bản. Mọi đoạn code và mức giá đều được đối chiếu với sản phẩm thực tế. Tìm hiểu thêm về quy trình biên tập và AI của chúng tôi tại trang quy trình biên tập .

Về tác giả
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.

