Badges Ninja REST API로 Open Badges 발급하기: 퀵스타트
인증, 발급자 생성, 배지 디자인 또는 업로드, 수령자에게 수여까지 모두 REST로 처리해요. JavaScript와 Python 예제도 함께 있어요.
대부분의 자격 증명 프로그램에는 API가 필요 없어요. 1년에 수료생이 몇백 명인 과정을 운영한다면 대시보드만으로 충분해요. 비주얼 디자이너에서 배지를 디자인하고 CSV를 업로드하면, 모든 수령자가 검증 페이지와 PDF 인증서를 받아요. 그런 상황이라면 먼저 CSV로 Open Badges를 발급하는 방법부터 보고, API는 나중에 다시 찾아 주세요.
API가 제 몫을 하는 때는 다른 시스템이 자격 증명을 발급해야 할 때예요. 학습 플랫폼이 과정 수료를 기록할 때, 등록 도구가 행사를 마감할 때, 인사 시스템이 컴플라이언스 교육 이수를 기록할 때처럼요. 이런 경우에 매주 말마다 스프레드시트를 내보내고 싶은 사람은 없어요. 수료하는 순간 HTTP 호출을 한 번 보내는 편이 더 간단하고, 수령자도 성취의 기억이 생생할 때 배지를 받을 수 있어요.
이 퀵스타트에서는 키 받기, 발급자 생성, 배지 생성, 배지 수여라는 네 번의 호출로 전체 흐름을 살펴봐요. 그다음 검증 링크를 수령자에게 전달하고 결과를 확인하는 방법도 알아봐요. 아래의 모든 요청 형식은 실제로 배포된 핸들러를 기준으로 하니, 그대로 붙여 넣어 실행할 수 있어요.
시작하기 전에 필요한 것
- 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”처럼 키가 쓰일 곳을 알 수 있는 이름을 붙여 주세요.

키는 딱 한 번만 표시돼요. 바로 시크릿 매니저나 환경 변수에 복사해 두세요. 키는 bws_ 뒤에 32자리 16진수가 붙은 형태이고, 모든 요청의 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예요. 후자를 지정하면 공개 자격 증명 페이지에 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)
다섯 개 필드(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은 필수예요. epoch 밀리초 또는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자 미만의 수령자 이름 포함) | 페이로드를 고치세요. 같은 요청을 재시도해도 다시 실패해요 |
| 401 | API 키가 없거나 잘못됨 | X-Api-Key 헤더와 키가 폐기되지 않았는지 확인하세요 |
| 402 | 크레딧 또는 요금제 할당량 소진 | 요금제를 업그레이드하거나 다음 할당량 기간을 기다리세요 |
| 404 | 배지를 찾을 수 없음 | 전달한 badgeId를 확인하세요 |
실용적인 팁이 두 가지 있어요. 첫째, 400은 데이터 문제로 다루고 응답 본문을 로그에 남기세요. 본문에 실패한 필드가 나와 있어요. 둘째, 연동 쪽에서 멱등성을 확보하세요. awardId를 자체 데이터베이스의 수료 기록 옆에 저장하고, API를 다시 호출하기 전에 그 값이 있는지 확인하세요. 그러면 웹훅이 재전송되거나 작업이 다시 실행돼도 같은 사람에게 자격 증명이 두 번 발급되지 않아요.
실제 연동으로 조립하기
전형적인 구성은 이래요.
- 대시보드에서 과정이나 마일스톤마다 배지를 하나씩 디자인하고, 각 배지 ID를 적어 두세요.
- 시스템에 과정에서 배지 ID로 가는 매핑을 저장하세요.
- 학습자가 과정을 수료하면 서버가 이름, 이메일, 수료일을 담아
POST /awards를 호출해요. - 반환된
awardId를 수료 기록에 연결해 저장하세요. - 자체 제품 안에 검증 링크를 보여 주면, 학습자가 제품을 벗어나지 않고도 확인할 수 있어요.
코드를 작성하고 싶지 않다면, 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 문서에 있어요.
- 인증 방법과 키 관리에 대해서는 인증 가이드를 참고하세요.
- 오류 코드를 자세히 알고 싶다면 오류 레퍼런스를 참고하세요.
- 한 번에 한 건씩 호출하는 방식이 한계에 이르면 대시보드의 일괄 수여를 사용하세요. CSV를 업로드하고, 필요하면 실행을 일시 중지했다가 다시 시작할 수 있어요.
가장 어려운 부분은 첫 번째 수여를 성공시키는 일이에요. 그다음부터는 성취가 기록되는 곳마다 같은 호출을 연결하기만 하면 돼요.
첫 번째 검증 가능한 자격 증명을 발급할 준비가 되셨나요? badges.ninja에서 무료로 시작하기 — 비주얼 디자이너, 공개 검증 페이지, PDF 인증서, Open Badge v2.0 출력. 신용카드는 필요 없어요.
이 글이 만들어진 과정
이 블로그의 일부 게시물은 AI 어시스턴트의 도움으로 초안이 작성된 후, 게시 전에 Badges Ninja 팀이 검토, 사실 확인, 편집합니다. 모든 코드 샘플과 가격은 실제 제품과 대조해 검증됩니다. 저희의 편집 및 AI 프로세스에 대해 더 알아보려면 저희 편집 프로세스 페이지를 확인해 보세요 .

작성자 소개
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.

