API & MCP · Endpoints
REST endpoints
Base URL: https://academy.empomm.com. All endpoints require Authorization: Bearer empo_…. Errors return JSON { error: { code, message, field? } } with the appropriate HTTP status.
| Method | Path | Scope | Description |
|---|---|---|---|
| GET | /api/v1/me | any | Return the user that owns the bearer token + the key's scopes. |
| GET | /api/v1/courses | courses:read | List courses. Admins see all; instructors see own + collab. Supports `?limit=50` (max 100). |
| POST | /api/v1/courses | courses:write | Create a draft course. Body: { title, subtitle?, description?, categoryId?, price?, language? }. |
| GET | /api/v1/courses/{courseId} | courses:read | Get a single course with its modules and lesson stubs. |
| PATCH | /api/v1/courses/{courseId} | courses:write | Update course fields. Same body shape as POST, all fields optional. |
| POST | /api/v1/courses/{courseId}/status | courses:write | Transition course status. Body: { status: 'DRAFT' | 'PUBLISHED' | 'PRIVATE' | 'ARCHIVED' }. |
| POST | /api/v1/courses/{courseId}/modules | courses:write | Append a new module. Body: { title }. |
| POST | /api/v1/modules/{moduleId}/lessons | courses:write | Append a new lesson. Body: { title, contentType?, videoUrl?, content?, duration?, isFree? }. |
| GET | /api/v1/lessons/{lessonId}/blocks | courses:read | List a lesson's blocks (parents + nested children grouped). |
| POST | /api/v1/lessons/{lessonId}/blocks | courses:write | Append a single block to a lesson. Sanitised at storage. |
| POST | /api/v1/lessons/{lessonId}/blocks/from-markdown | courses:write | Bulk-create blocks from a Markdown body. Body: { markdown, replace? }. 250 KB cap. |
| POST | /api/v1/scaffold-course | courses:write | One-shot scaffold: course + modules + lessons + markdown blocks. 1 MB cap. |
| POST | /api/v1/certificates/external | certificates:issue | Issue a single EMPO T&C certificate. Admin-only. Body: holder info + trainingTitle + trainingDate + deliveryFormat. |
| POST | /api/v1/certificates/external/batch | certificates:issue | Bulk issue T&C certs (up to 200 holders). Admin-only. Body: { trainingTitle, trainingDate, deliveryFormat, holders[] }. |
| POST | /api/v1/certificates/{certId}/revoke | certificates:manage | Revoke a certificate. Body: { reason }. Reason is shown on the public verification page. |
| POST | /api/v1/certificates/{certId}/resend-email | certificates:manage | Resend the certificate notification email to the holder. |
| GET | /api/v1/notifications/templates | (admin) | List all notification email templates with their current overrides. |
| PATCH | /api/v1/notifications/templates/{type} | templates:write | Override one template. Body: { subject?, greeting?, ctaLabel?, footer?, enabled? }. |
Error format
{
"error": {
"code": "INVALID_INPUT",
"message": "trainingDate is required",
"field": "trainingDate"
}
}Common codes: UNAUTHORIZED (401), FORBIDDEN (403), MISSING_SCOPE (403), NOT_FOUND (404), INVALID_INPUT (400), RATE_LIMITED (429), PAYLOAD_TOO_LARGE (413), INTERNAL_ERROR (500).
Rate limits
60 requests/minute per API key, 120/minute per client IP. The stricter verdict wins. Every response carries RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers; 429s also set Retry-After. Need more headroom for a legitimate integration? Email academy@empomm.com before pointing prod traffic.
Looking for the MCP version?
All of these endpoints are also wrapped as MCP tools. See the MCP setup guide.