Learn more
- Authentication — token flow, scope, and key rotation in depth.
- Concepts — issuance, achievement, holder, and the response envelope.
- Errors — RFC 9457 problem+json.
- API reference — full endpoints, schemas, and interactive exploration.
A getting-started guide for direct customers (the data controller of their own club) who want to automate Kolleges via API.
The canonical contract = the Open API v2 reference.
If you’re a channel partner operating multiple clubs on others’ behalf, see the separate Partner API reference (host partner.kolleges.net).
If you only need to verify or read back issued credentials (verifiers, wallets, an LMS), use the unauthenticated Open Badges 3.0 public verification reference (host api.kolleges.net) — the signed VC-JWT is the only frozen record, and the criteria, skills and engraved description are read from it.
apiClient) = the credential unit you issue in the dashboard. Bound to exactly one club.client_credentials. No long-lived static keys — exchange your client_secret for a 15-minute ES256 token and use that.https://openapi.kolleges.net/v2/clubs/{clubDomain}/…. clubDomain lives in the path only (one exception: GET /v2/me, the bootstrap route that tells you which workspace your client is bound to).{ data } (single) · { data, meta } (cursor list) · BatchResultDto (issuance batch). Errors = RFC 9457 application/problem+json.In the admin-next sidebar, Developers › “New client”:
client_id + client_secret once, on screen — this is the only time they’re shown. The platform keeps only a hash and cannot show them again. If lost, rotate.clubs:read · billing:read · achievements:read · achievements:manage · designs:read · designs:manage · issuance:read · issuance:write · issuance:revoke · events:read.curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \ -d 'grant_type=client_credentials' \ -d 'scope=kolleges:openapi:issuance:write kolleges:openapi:issuance:read' \ https://auth.kolleges.net/token# → { "access_token": "<ES256 JWT>", "token_type": "Bearer", "expires_in": 900, "scope": "…" }clubDomain)Every other path is /v2/clubs/{clubDomain}/…, but the token does not carry the workspace domain.
GET /v2/me gives it to you — the one route without clubDomain in the path, callable by any valid
token with no particular scope.
TOKEN=<access_token>
curl -s -H "Authorization: Bearer $TOKEN" https://openapi.kolleges.net/v2/me# → { data: { clientId, clubDomain, operations } }
CLUB=<clubDomain from the response># Club identity and whether issuance is allowedcurl -s -H "Authorization: Bearer $TOKEN" \ https://openapi.kolleges.net/v2/clubs/$CLUB/# → { data: { domain, name, canIssue, grantedOperations } }curl -s -X POST -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H "Idempotency-Key: order-2026-07-19-0001" \ -d '{ "achievementFormId": 123, "mode": "email", "recipients": [{ "externalUserId": "u-42", "name": "Jane Doe", "email": "jane@example.com" }] }' \ https://openapi.kolleges.net/v2/clubs/$CLUB/issuances# → { results: [{ ref, status: "issued|skipped|failed", resourceId, error }],# summary: { total, ok, skipped, failed } }# List issuances (cursor)curl -s -H "Authorization: Bearer $TOKEN" "https://openapi.kolleges.net/v2/clubs/$CLUB/issuances?limit=20"# Detail (recipient PII)curl -s -H "Authorization: Bearer $TOKEN" "https://openapi.kolleges.net/v2/clubs/$CLUB/issuances/456"# Certificate filecurl -s -H "Authorization: Bearer $TOKEN" "https://openapi.kolleges.net/v2/clubs/$CLUB/issuances/456/file?format=pdf" -o cert.pdf# Revoke (= invalidate)curl -s -X POST -H "Authorization: Bearer $TOKEN" "https://openapi.kolleges.net/v2/clubs/$CLUB/issuances/456/revoke"# Event feedcurl -s -H "Authorization: Bearer $TOKEN" "https://openapi.kolleges.net/v2/clubs/$CLUB/events?limit=20"Learn more