Выдача Open Badges через REST API Badges Ninja: быстрый старт

Аутентификация, создание издателя, дизайн или загрузка значка, выдача получателю — всё через REST. Примеры на JavaScript и Python.

Nacho Coll Автор Обновлено 8 мин чтения
Аутентификация, создание издателя, дизайн или загрузка значка, выдача получателю — всё через REST. Примеры на JavaScript и Python.

Большинству программ выдачи credentials API не нужен. Если вы ведёте курс с несколькими сотнями выпускников в год, панель управления делает всё сама: вы рисуете значок в визуальном дизайнере, загружаете CSV, и каждый получатель получает страницу верификации и PDF-сертификат. Если это про вас, начните со статьи как выдавать Open Badges из CSV и возвращайтесь позже.

API оправдывает себя, когда credentials должна выдавать другая система: ваша обучающая платформа отмечает курс как пройденный, инструмент регистрации закрывает мероприятие, HR-система фиксирует завершённый модуль по комплаенсу. В таких случаях никто не хочет выгружать таблицу в конце каждой недели. Один HTTP-запрос в момент завершения проще, а получатель получает значок, пока достижение ещё свежо.

Этот быстрый старт проводит через весь путь в четыре запроса: получить ключ, создать издателя, создать значок, выдать его. Затем разберём, как передать получателю ссылку на верификацию и проверить результат. Все формы запросов ниже взяты из развёрнутых обработчиков, так что их можно вставить и запустить.

Что нужно перед началом

  • Бесплатный аккаунт на 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 с сервера, из serverless-функции или инструмента автоматизации.
  • Используйте один ключ на одну интеграцию. Если один утечёт, вы отзовёте одну интеграцию, а не все.
  • Панель управления также принимает вашу сессию после входа (Cognito JWT в заголовке Authorization: Bearer), но для скриптов и интеграций правильный инструмент — 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» на ваших публичных страницах credentials.

В ответе приходит идентификатор издателя:

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

Сохраните это значение в точности как оно вернулось. Оно понадобится на следующем шаге.

Верификация издателя

Значки можно создавать только у верифицированного издателя. Верификация работает так:

  • Если email издателя совпадает с email вашего аккаунта, издатель верифицируется автоматически. Это самый быстрый путь для первого теста.
  • Если email другой, на этот адрес приходит письмо с кодом верификации. Вы подтверждаете код в панели управления (или через API издателей) до создания значков.

Поэтому для этого руководства используйте тот же email, с которым вы регистрировались.

Шаг 3: создайте значок

Значок — это многоразовый шаблон: название, описание, критерии и изображение. Каждая выдача, которую вы сделаете позже, ссылается на него.

Запрос — обычный JSON. Изображение передаётся строкой base64, так что бороться с multipart-загрузкой не придётся. Префикс data URL вроде data:image/png;base64, принимается и отбрасывается.

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>" }. Изображение сохраняется навсегда, и теперь значок — это BadgeClass Open Badge v2.0, который может получить любой желающий.

А нужно ли вообще создавать значки в коде?

Обычно нет. Дизайн значка — творческая задача, и визуальный дизайнер (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 обязательно. Отправляйте миллисекунды эпохи или строку с датой ISO, например 2026-09-28.
  • expires необязательно и принимает те же форматы.

Успех — это HTTP 200 с телом, содержащим awardId. Email получателя хранится в данных Open Badge как хеш SHA-256, поэтому публичный JSON его не раскрывает.

Шаг 5: найдите страницу верификации и JSON Open Badge

Ответ на выдачу даёт вам идентификатор, а не готовую ссылку. Идентификатор заканчивается GUID, и публичные страницы строятся из этого GUID:

  • Страница верификации для людей: https://badges.ninja/awards/<awardId>
  • Open Badge v2.0 JSON-LD: https://api.badges.ninja/certify-badge/award/<awardId>

Если ваш awardId приходит полным URL, возьмите последний сегмент пути как GUID.

Обе страницы публичные. Любой, у кого есть ссылка, может проверить credential без создания аккаунта, в этом и смысл: работодатель или сотрудник приёмной комиссии должен проверять значок за десять секунд.

Получите JSON, чтобы увидеть то, что видит мир:

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

Вы получите Assertion Open Badge v2.0: значок, на который она ссылается, хешированную идентичность получателя, дату выдачи и блок верификации, указывающий на размещённый assertion. Поскольку это стандартные данные Open Badges, их прочтёт любой инструмент, понимающий этот формат. Именно переносимость — причина выбрать Open Badges, а не проприетарный PDF; подробнее о компромиссе — в статье Open Badges против PDF-сертификатов.

Как получатели получают credential

Создание выдачи — это отдельно от уведомления получателя. Получатели могут открыть свои credentials через портал получателя на badges.ninja/me: вход по magic-ссылке без пароля, а также опубликовать публичный профиль по адресу badges.ninja/u/<handle>. На странице верификации они могут добавить значок в LinkedIn, скачать PDF-сертификат или поделиться ссылкой.

Для первых тестов отправьте выдачу самому себе на свой email и пройдите путь получателя. Это самый быстрый способ заметить, например, что описание значка читается неуклюже.

Обработка ошибок без боли

API использует обычные HTTP-коды состояния. Вот те, с которыми вы столкнётесь:

СтатусЗначениеЧто делать
200УспехПрочитайте тело JSON
400Поле отсутствует или некорректно, в том числе имя получателя короче 5 символовИсправьте данные; повтор того же запроса снова завершится ошибкой
401Отсутствует или неверен API-ключПроверьте заголовок X-Api-Key и не отозван ли ключ
402Закончились кредиты или квота планаПовысьте план или дождитесь следующего периода квоты
404Значок не найденПроверьте переданный badgeId

Два практических совета. Во-первых, считайте 400 проблемой данных и логируйте тело ответа: в нём указано проблемное поле. Во-вторых, сделайте свою интеграцию идемпотентной на своей стороне: сохраняйте awardId рядом с записью о завершении в вашей базе данных и проверяйте его перед повторным вызовом API. Так повторно отправленный вебхук или перезапущенная задача никогда не выдадут одному человеку две credentials.

Собираем всё в реальной интеграции

Типичная схема выглядит так:

  1. Нарисуйте значки в панели управления, по одному на курс или этап, и запишите ID каждого значка.
  2. Храните в своей системе соответствие «курс — ID значка».
  3. Когда учащийся завершает курс, ваш сервер вызывает POST /awards с его именем, email и датой завершения.
  4. Сохраните возвращённый awardId рядом с записью о завершении.
  5. Показывайте ссылку на верификацию внутри вашего продукта, чтобы учащийся видел её, не покидая его.

Если вы не хотите писать код, тот же запрос работает из любого инструмента автоматизации, который умеет отправлять HTTP-запрос с телом JSON и своим заголовком. Направьте его на https://api.badges.ninja/awards и сопоставьте поля формы или таблицы с badgeId, recipient.name, recipient.email и issuedOn.

Планы и лимиты, которые стоит знать

API доступен на каждом плане; за его разблокировку вы не платите дополнительно. План Free ($0) покрывает 2 издателей, 5 значков, 2 места, 1 API-ключ и 1 200 credentials в год. Starter стоит $9 в месяц, а Pro — $29 в месяц, с более высокими лимитами. Прежде чем рассчитывать масштаб запуска, посмотрите актуальные цифры на странице цен. Если вы сравниваете, сколько другие платформы берут за доступ к API, статья альтернатива Credly выкладывает стоимость бок о бок.

Что дальше

  • Полный справочник по эндпоинтам находится в документации API, доступной на 40 языках.
  • Подробности об аутентификации и работе с ключами — в руководстве по аутентификации.
  • Подробно о кодах ошибок — в справочнике по ошибкам.
  • Когда вам станет тесно в режиме «один запрос за раз», используйте массовую выдачу в панели управления: загрузите CSV и при необходимости приостанавливайте или возобновляйте выполнение.

Самое трудное — первая успешная выдача. Дальше остаётся встроить тот же запрос туда, где достижения и так фиксируются.

Готовы выдать свою первую проверяемую credential? Начните бесплатно на 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.

Назад в блог

Похожие статьи