CSV로 Open Badges를 5분 안에 발급하는 방법
단계별 안내: 수신자 CSV를 업로드하고, 배지를 고른 뒤, 발급을 누르세요. 배치 도중 일시정지하고 재개하며, 실패 항목을 다시 시도하고, 결과를 내보낼 수 있어요. 10명이든 10,000명 규모의 코호트든 다 됩니다.
코호트에 자격 증명을 한 명씩 발급해 본 적이 있다면 이미 그 문제를 알고 있을 거예요. 대략 열 명을 넘어가면 감당이 안 되고, 이름과 이메일을 복사해서 붙여넣는 데 오후 한나절이 통째로 날아가죠. 40명짜리 부트캠프 코호트, 500명 규모의 콘퍼런스 참석자 명단, 5,000명 규모의 기업 교육 롤아웃 모두 똑같은 걸 필요로 해요. 즉, 명단을 업로드하고, 배지를 고르고, 발급을 누르고, 자리를 뜨는 거죠.
바로 그것이 https://badges.ninja의 Bulk Credentials가 하는 일이에요. 이 안내는 전체 흐름을 다룹니다. CSV 준비하기, 배치 구성하기, 실행되는 걸 지켜보기, 그리고 현실 세계의 지저분한 경우들을 처리하기 — 오타가 있는 수신자 행, 중간에 끊긴 배치, 또는 대시보드가 아니라 자체 시스템에서 같은 방식으로 발급하고 싶은 프로그램 같은 것들이요.
시작하기 전에: 필요한 것
두 가지인데, 둘 다 아마 이미 가지고 있을 거예요.
- 배지 — 비주얼 디자이너에서 한 번만 디자인해서 배치의 모든 수신자에게 재사용해요. 아직 만들지 않았다면 첫 검증 가능한 인증서를 디자인하기 가이드를 참고하세요.
- 수신자 CSV — 이름, 이메일, 그리고 (선택적으로) 발급 날짜. 스키마는 이게 전부예요.
수신자별 발급자 계정도, 메일 서버도, 어떤 코드도 필요 없어요. 이 섹션의 모든 작업은 대시보드 안에서 이루어집니다.
1단계: CSV 준비하기
수신자 명단 형식은 일부러 최소한으로 만들어져 있어요.
name,email,issued_on
Maria Gonzalez,maria@example.com,2026-07-01
David Kim,david@example.com,2026-07-01
Priya Patel,priya@example.com,
- name — 필수. 어서션과 인증서의 수신자 필드를 채워요.
- email — 필수. 이것이 Open Badge v2.0 어서션의 수신자 신원이 돼요 — 저장 전에 자격 증명마다 별도의 salt로 해시 처리되며, 평문으로 보관되는 일은 절대 없어요.
- issued_on — 선택. 비워 두면 배치가 각 행이 처리되는 순간을 사용해요. 실제로는 지난달에 끝난 코호트를 소급해서 채워 넣는 경우라면 명시적으로 지정하세요.
대부분의 프로그램 담당자는 이미 수료 현황을 관리하고 있는 곳 — Airtable, Google Sheets, 강사가 넘겨준 스프레드시트, 또는 LMS 성적부에서 뽑은 CSV — 에서 이걸 바로 내보내요. 특별한 내보내기 도구는 필요 없고, 그 세 개의 열을 가진 CSV라면 무엇이든 됩니다.
흔한 CSV 함정 (그리고 미리보기가 이를 어떻게 잡아내는지)
현실의 수신자 명단에는 몇 가지 문제가 끊임없이 나타나는데, 보통은 CSV가 두세 개의 원본 시트를 합쳐서 만들어졌기 때문이에요.
- 이메일 주소 끝의 공백 문자 — PDF 명부나 Google 설문 내보내기에서 복사해 붙여넣으면 눈에 보이지 않는 공백이 딸려 오는 경우가 많아요. 스프레드시트 셀에서는 멀쩡해 보이지만 업로드 시 이메일 검증에서 실패해요.
- 중복된 행 — 코호트 명단과 뒤늦게 등록한 사람들의 명단이 중복 제거 없이 이어 붙여져서 같은 수신자가 두 번 나타나요.
- 일관되지 않은 날짜 형식 — 한 열의
2026-07-01과 다른 내보내기에서 온07/01/2026이 섞여 있어요. ISO 8601(YYYY-MM-DD)을 고수하면 이 문제는 완전히 사라져요. - 헤더 대소문자 불일치 —
Email대email대E-mail. 파서는 흔한 변형에 대해서는 관대하지만, 완전히 제멋대로인 헤더 이름은 자동으로 매핑되지 않아요.
이 중 어느 것도 치명적이지 않아요 — 미리보기 단계(아래)가 무엇이든 발급되기 전에 각각을 드러내 주므로, 해결책은 “3,000명의 수신자 중 누가 망가진 배지를 받았는지 알아내기”가 아니라 “스프레드시트를 수정하고 다시 업로드하기”가 됩니다.
2단계: 배치 구성하기
대시보드에서 Credentials → Bulk Credentials를 열고 발급할 배지를 고르세요. 이 단계는 배치 전체에 적용되는 것을 모두 설정하는 단계예요. 배지 자체, CSV에 행별 날짜를 넣지 않을 경우의 공통 발급 날짜, 그리고 (발급자 프로필에 있다면) 각 수신자가 한 번의 클릭으로 자격 증명을 자기 프로필에 추가할 수 있게 해 주는 LinkedIn 조직 ID 같은 것들이요.

지금이 선택한 배지가 최종 버전인지 다시 한번 확인하기에 좋은 순간이에요 — 수신자는 나중에 업데이트한 모습이 아니라, 발급하는 그 순간 배지에 붙어 있는 이미지와 기준을 보게 됩니다.
3단계: 업로드하고 미리보기
CSV를 끌어다 놓으면 플랫폼이 이를 파싱하고, 미리보기 표를 보여 주며, 처리할 수 없는 것 — 누락된 이메일, 형식이 잘못된 날짜, 중복된 행 — 에 표시를 해요. 미리보기를 확인하기 전에는 아무것도 발급되지 않아요.

이 미리보기 단계는 보기보다 훨씬 중요해요. 2,000행짜리 CSV의 한 행에 있는 오타는 눈으로는 놓치기 쉽고, 1,999개의 올바른 행이 이미 발급된 뒤에 되돌리려 애쓰는 것보다 그 전에 잡는 편이 훨씬 저렴해요. 스프레드시트에서 표시된 행을 고치고 다시 업로드하면 미리보기가 갱신돼요.
4단계: 배치 실행하기
발급을 누르면 배치가 처리를 시작해요. 진행 표시줄이 완료된 행과 남은 행을 추적하고, 배치는 서버 쪽에서 실행돼요 — 탭을 계속 열어 둘 필요가 없고, 배치 도중에 노트북을 닫아도 진행 상태를 잃지 않아요.
이 마지막 부분은 대규모 코호트에서 실제로 중요한 세부 사항이라 명확히 짚어 둘 가치가 있어요. 배치 상태는 브라우저가 아니라 서버에 있어요. 연결이 끊기든, 노트북이 절전 모드로 들어가든, 회의가 시작돼서 그냥 탭을 닫든, 배치는 처음부터 다시 시작하는 게 아니라 계속 실행돼요(일시정지했다면 정확히 멈춘 지점에서 재개해요). 40명짜리 부트캠프 코호트에게 이건 있으면 좋은 기능이에요. 5,000행짜리 기업 롤아웃에게는 “그냥 잘 돌아간다”와 “누군가 20분 동안 브라우저 탭을 지켜봐야 한다” 사이의 차이예요.
실행 중인 배치를 일부러 일시정지할 수도 있어요 — 예를 들어 3,000행짜리 실행 도중에 누군가 배지 기준 텍스트를 손봐야 한다고 지적하면 — 문제를 고치고, 이미 완료된 행을 다시 발급하지 않은 채로 재개할 수 있어요.
5단계: 실패 처리하기
실제 수신자 명단에는 불량 행이 있어요. 오타가 난 이메일 도메인, 실은 비어 있는 이름 필드, 두 개의 내보낸 시트가 합쳐지며 생긴 중복 항목 같은 것들이요. 어떤 행이 실패해도 배치는 멈추지 않아요 — 나머지를 계속 처리하고, 나중에 검토할 수 있게 그 실패에 표시를 해요. 어떤 행이 성공했고 어떤 행이 실패했는지 정확히 보여 주는 결과 내보내기를 받게 되므로, 명단 전체를 다시 확인하는 대신 실패한 행만 고쳐서 작은 후속 배치를 다시 실행할 수 있어요.
이건 자격 증명 대시보드에서 이미 흔한 CSV 내보내기 습관에 유의미해요 — 실제로 발급된 것의 CSV를 언제든 뽑아서, 원본 명단과 교차 대조하고, 누가 아직 배지가 필요한지 정확히 알 수 있어요.
API 경로: 같은 흐름, 대시보드 없이
위의 모든 내용은 누군가가 대시보드 앞에 앉아 마법사를 클릭해 나간다는 전제예요. 수료 데이터가 이미 어떤 시스템 — LMS, CRM, 스프레드시트 자동화 — 에 있다면, 대신 Awards API에서 같은 대량 자격 증명 흐름을 직접 구동할 수 있어요.
수신자별 최소 발급 호출은 이렇게 생겼어요.
curl -X POST https://api.badges.ninja/awards \
-H "X-Api-Key: bws_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d" \
-H "Content-Type: application/json" \
-d '{
"badgeId": "badge_9f8e7d6c5b4a",
"recipient": {
"name": "Maria Gonzalez",
"email": "maria@example.com"
},
"issuedOn": "2026-07-01T00:00:00Z"
}'
또는 Python에서, 손으로 업로드했을 바로 그 CSV에서 읽어 온 행들을 반복 처리하려면 이렇게 해요.
import csv
import requests
API_KEY = "bws_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d"
BADGE_ID = "badge_9f8e7d6c5b4a"
with open("recipients.csv") as f:
for row in csv.DictReader(f):
requests.post(
"https://api.badges.ninja/awards",
headers={"X-Api-Key": API_KEY},
json={
"badgeId": BADGE_ID,
"recipient": {"name": row["name"], "email": row["email"]},
"issuedOn": row.get("issued_on") or None,
},
)
자격 증명 발급이 사람이 CSV를 수동으로 내보내는 것이 아니라 완전히 다른 무언가 — 강좌 수료 webhook, CRM 단계 변경, 폼 제출 — 에 의해 트리거될 때 이 방법에 손을 뻗을 가치가 있어요. 인증과 요청/응답의 전체 형태는 API 빠른 시작에서 다뤄요. 이 방식으로 만들어진 모든 자격 증명은 대시보드 마법사로 만든 것과 동일해요. 같은 Open Badge v2.0 어서션, 같은 검증 URL, 같은 PDF 인증서죠.
대시보드 마법사 vs. API: 실제로 어느 쪽을 원하나요?
| Dashboard Bulk Credentials | Awards API | |
|---|---|---|
| 가장 적합한 경우 | 일회성 또는 가끔 있는 배치(코호트 졸업, 콘퍼런스 참석) | 반복되는 트리거(강좌 수료마다, 구매마다) |
| 설정 노력 | 없음 — CSV를 내보내서 업로드 | 일회성 통합 작업(webhook 또는 스크립트) |
| 누가 실행하나 | 프로그램 담당자, 코드 불필요 | 트리거하는 시스템의 소유자 |
| 실패 처리 | 미리보기 + 행별 결과 내보내기 | 요청별 HTTP 상태, 자체 재시도 로직에서 처리 |
대부분의 팀은 대시보드 마법사로 시작해요. CSV 하나 말고는 아무것도 필요하지 않으니까요. 그리고 같은 배치를 수동으로 서너 번 실행해서 그 패턴을 자동화할 가치가 분명해진 뒤에야 API로 옮겨 가요.
개인정보: 실제로 저장되는 것
이름과 이메일이 담긴 CSV는 개인 데이터이므로, 업로드 후 그것이 어떻게 되는지 알아 둘 가치가 있어요. 수신자의 이메일 주소는 자격 증명 자체에 절대 평문으로 저장되지 않아요 — 사양의 hashed 수신자 신원 형식을 따라, Open Badge v2.0 어서션의 일부로 자격 증명마다 별도의 salt로 해시 처리돼요. 검증자가 대조하는 것은 원본 주소가 아니라 이 해시예요. 이름 필드는 입력한 그대로 저장되는데, 인증서와 검증 페이지에 보이도록 의도된 것이기 때문이에요. 발급 후에 어떤 행을 수정해야 한다면 — 가장 흔하게는 잘못 적힌 이름 — 배치의 나머지를 건드리지 않고 자격 증명 대시보드에서 개별 자격 증명을 편집하거나 취소할 수 있어요.
배치 이후: 수신자에게 알리기
배지를 발급하는 것과 수신자에게 그 사실을 알리는 것은 별개의 두 단계예요. CSV가 이미 자체 시스템을 통해 이메일을 트리거하지 않는다면, 대시보드의 대량 공유 흐름을 통해 방금 만든 자격 증명들을 여러 개 선택해서 한 번에 그 전부에게 개인화된 공유 이메일을 보낼 수 있어요 — 수신자별 개인화(이름, 배지 이미지, 검증 링크)가 자동으로 치환되는 방식을 포함한 전체 안내는 공유 이메일 대량 발송하기를 참고하세요.
Bulk Credentials가 알맞은 도구일 때
“배치”라는 틀이 현실에 들어맞을 때라면 언제나 대량 발급이 옳은 선택이에요. 같은 날 수료한 코호트, 방금 끝난 콘퍼런스, 규정 준수 마감을 앞둔 교육 롤아웃 같은 것들이죠. 반대로 개별 이정표가 달성될 때마다 일회성 자격 증명을 발급하는 거라면 — 한 건의 승진, 한 건의 프로젝트 완료 — 한 행짜리 CSV를 짜맞추는 것보다 단일 자격 증명 폼이 더 빨라요.
반복되는 무언가 — 매달 열리는 같은 강좌, 계속 굴러가는 온보딩 파이프라인 — 에 대해서는 위의 API 경로를 한 번 설정해 둘 가치가 있어요. 그것은 “코호트마다 수동으로 대량 자격 증명을 실행하기”를 “수료가 이미 자동으로 자격 증명을 발급하기”로 바꿔 줘요. 이것이 바로 대부분의 프로그램 담당자가 두세 번째 수동 배치 이후에 진짜로 원하는 이 워크플로의 모습이에요.
첫 검증 가능한 자격 증명을 발급할 준비가 되셨나요? 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.


