Authentication
Every request must include a valid API key in one of three ways:
- Header (preferred): X-CertBoost-Key: <your-key>
- Bearer token: Authorization: Bearer <your-key>
- Query string: ?api_key=<your-key>
Master Key
Configured in appsettings.json under LmsApi:MasterKey. Has "Admin" permission across all users. Use only from trusted backends. Rotate before production.
User-Scoped Keys
Created from /Authorized/Settings -> API Keys. Each key has Permission (ReadOnly | ReadWrite | Admin), IsActive, and LastUsedAt. Can only access the key owner's /users/{userId}/progress.
Auth Failure Codes
- 401 — key missing, unknown, expired, or inactive
- 403 — key valid but lacks required permission
- 429 — rate limit exceeded (future)
Endpoint Summary
GET /api/lms/v1 — Directory
Returns metadata describing the API.
GET /api/lms/v1/categories
Lists every certification category. Query params: search (substring match), includeOff (bool).
GET /api/lms/v1/users/{userId}/progress
Returns a user's complete progress snapshot: every attempt plus per-category averages. Query params: recent (int), fromUtc (ISO).
Permission: Master key -> any userId. User-scoped key -> only the key owner's userId (else 403).
POST /api/lms/v1/assignments
Creates a quiz assignment for a user. Also fires the assignment.created webhook.
Integration tip: Deep-link the user into CertBoost by opening launchUrl in an iframe or new tab.
Webhooks API
Manage webhook subscriptions via the REST API. See the Webhooks Guide for full event details.
- GET
/api/lms/v1/webhooks— list your subscriptions - POST
/api/lms/v1/webhooks— register a new webhook - DELETE
/api/lms/v1/webhooks/{id}— remove a subscription - POST
/api/lms/v1/webhooks/{id}/test— send a test event
Error Handling
All non-2xx responses return a JSON body with a single error string:
- 400 Bad Request — malformed JSON, missing required field
- 401 Unauthorized — missing / invalid key
- 403 Forbidden — key valid but lacks required permission
- 404 Not Found — unknown userId, categoryId, or webhook id
- 409 Conflict — duplicate webhook URL for the same event set
- 500 Internal — unexpected server error