The Admin API provides privileged access to Sealearn’s platform management features — from reviewing content and approving AI-generated questions to managing user roles and exporting data as CSV. All endpoints in this group require a valid JWT and an elevated role. Standard learner accounts are rejected withDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/DerBasilisk/SEA-ServicioEvaluaconAsistida/llms.txt
Use this file to discover all available pages before exploring further.
403 Forbidden.
Sealearn defines two elevated roles. The
admin role grants access to the full Admin API: statistics, user management, content CRUD, question moderation, CSV export, and shop item management. The superadmin role inherits all admin permissions and additionally has exclusive access to the role-change endpoint (PUT /api/admin/users/:id/role). Superadmins are also the only users who can promote or demote other accounts to/from admin and superadmin.isAdmin middleware (applied globally to every route in this group) accepts either admin or superadmin. The isSuperAdmin middleware is layered on top of individual routes that require the higher tier.
Statistics
GET /api/admin/stats
Returns a snapshot of platform-wide aggregate counts. Useful for the admin dashboard home screen.Response 200 OK
true on success.Total number of registered user accounts.
Total number of subjects in the content tree.
Total number of units across all subjects.
Total number of lessons across all units.
Total number of questions in the database.
Number of questions with
isReviewed: false that are awaiting admin approval before going live.User Management
GET /api/admin/users
Returns a paginated list of user accounts. Supports filtering by search string, role, and account status.Page number (1-based). Defaults to
1.Results per page. Defaults to
20.Case-insensitive substring match against
username, email, and displayName.Filter by role. One of
"student", "admin", "superadmin". Omit or pass "all" to return all roles.Filter by account status.
"active" or "inactive". Omit or pass "all" to return both.Response 200 OK
Array of user objects. The
password field is always excluded.Total matching user count across all pages.
Current page number.
Total number of pages.
GET /api/admin/users/:id/progress
Returns all learning progress records for a specific user, each populated with the lesson’sname and xpReward, sorted by most recently updated first.
MongoDB ObjectId of the target user.
Response 200 OK
PUT /api/admin/users/:id
Updates editable fields on a user account. Only the fields provided in the request body are changed.MongoDB ObjectId of the user to update.
New display name for the user.
New email address.
Set account active (
true) or inactive (false).Response 200 OK
PUT /api/admin/users/:id/role
Changes the platform role of a user account. Valid values are"student", "admin", and "superadmin".
MongoDB ObjectId of the target user.
The new role to assign. Must be one of
"student", "admin", or "superadmin".Response 200 OK
Error Responses
| Status | Condition |
|---|---|
400 | role is not one of the three valid values. |
400 | The superadmin tried to change their own role. |
403 | Requester is not a superadmin. |
PUT /api/admin/users/:id/ban
Toggles theisActive flag on a user account. If the user is currently active they become inactive (banned); if inactive they become active again. The response always returns the updated user object.
MongoDB ObjectId of the user to ban or unban.
Response 200 OK
DELETE /api/admin/users/:id
Permanently deletes a user account and all associatedUserProgress records. This action cannot be undone.
MongoDB ObjectId of the user to delete.
Response 200 OK
Content Management
Subjects
GET /api/admin/subjects
Returns all subjects sorted by theirorder field.
Response 200 OK
POST /api/admin/subjects
Creates a new subject. All fields accepted by theSubject model may be provided in the request body.
Response 201 Created
PUT /api/admin/subjects/:id
Updates an existing subject by its ID.MongoDB ObjectId of the subject to update.
Response 200 OK
DELETE /api/admin/subjects/:id
Permanently deletes a subject.MongoDB ObjectId of the subject to delete.
Response 200 OK
Units
GET /api/admin/units
Returns all units across every subject. Each unit is populated with its parent subject’sname, icon, and color, sorted by order.
Response 200 OK
GET /api/admin/subjects/:subjectId/units
Returns units that belong to a specific subject, sorted byorder.
MongoDB ObjectId of the parent subject.
Response 200 OK
POST /api/admin/subjects/:subjectId/units
Creates a new unit nested under the given subject. Thesubject field is set automatically from the URL parameter.
MongoDB ObjectId of the parent subject.
Response 201 Created
PUT /api/admin/units/:id
Updates an existing unit.MongoDB ObjectId of the unit to update.
Response 200 OK
DELETE /api/admin/units/:id
Permanently deletes a unit.MongoDB ObjectId of the unit to delete.
Response 200 OK
Lessons
GET /api/admin/lessons
Returns all lessons across every unit, each populated with its parent unit (including the grandparent subject), sorted by unit order then lesson order.Response 200 OK
GET /api/admin/units/:unitId/lessons
Returns lessons belonging to a specific unit, sorted byorder.
MongoDB ObjectId of the parent unit.
Response 200 OK
POST /api/admin/units/:unitId/lessons
Creates a new lesson nested under the given unit. Theunit field is set automatically from the URL parameter.
MongoDB ObjectId of the parent unit.
Response 201 Created
PUT /api/admin/lessons/:id
Updates an existing lesson.MongoDB ObjectId of the lesson to update.
Response 200 OK
DELETE /api/admin/lessons/:id
Permanently deletes a lesson.MongoDB ObjectId of the lesson to delete.
Response 200 OK
Question Management
GET /api/admin/questions
Returns a paginated list of questions. Supports granular filtering across the content hierarchy as well as by type, difficulty, review status, and whether a question has active reports.Filter to questions belonging to a specific lesson.
Filter to questions belonging to any lesson within a specific unit.
Filter to questions belonging to any lesson within any unit under a specific subject.
Filter by question type (e.g.,
"multiple_choice", "true_false").Filter by difficulty level (e.g.,
"easy", "medium", "hard").Filter by review status. Pass
"true" for approved questions, "false" for pending. Omit or pass "all" for no filter.Pass
"true" to return only questions that have at least one active report, sorted by most recently reported first.Case-insensitive substring search against the question
prompt field.Page number (1-based). Defaults to
1.Results per page. Defaults to
15.Response 200 OK
POST /api/admin/questions
Manually creates a new question. All fields defined by theQuestion model may be supplied in the request body.
Response 201 Created
PUT /api/admin/questions/:id
Updates the fields of an existing question.MongoDB ObjectId of the question to update.
Response 200 OK
PUT /api/admin/questions/:id/review
Approves or rejects a question. Sets bothisReviewed and isActive to the value of approved. After approval (approved: true) the question becomes live and will appear in learner sessions.
MongoDB ObjectId of the question to review.
true to approve the question (sets isReviewed: true, isActive: true). false to reject it (sets both to false).Response 200 OK
PUT /api/admin/questions/:id/clear-reports
Clears all user-submitted reports on a question by setting itsreports array to []. Use this after investigating a report to mark the question as clean without deleting it.
MongoDB ObjectId of the question whose reports should be cleared.
Response 200 OK
DELETE /api/admin/questions/:id
Permanently deletes a question.MongoDB ObjectId of the question to delete.
Response 200 OK
POST /api/admin/questions/generate
Uses an AI service (Groq or Gemini) to automatically generate a batch of questions for a given lesson. Generated questions are saved withisReviewed: false and isActive: false — they will not appear in learner sessions until an admin approves them via PUT /api/admin/questions/:id/review.
MongoDB ObjectId of the lesson the questions should be associated with. The generator uses the lesson’s subject and unit context to produce relevant content.
Number of questions to generate. Defaults to
5.Target difficulty level for all generated questions (e.g.,
"easy", "medium", "hard"). Defaults to "medium".Array of question type strings the generator may produce (e.g.,
["multiple_choice", "true_false"]). When omitted, all supported types are permitted.Response 201 Created
Confirmation message indicating how many questions were saved and that they require review.
Array of the newly inserted question documents, all with
isReviewed: false and isActive: false.Error Responses
| Status | Condition |
|---|---|
404 | No lesson found for the provided lessonId. |
CSV Export
All export endpoints respond with atext/csv file download. The Content-Disposition header is set to attachment with a timestamped filename. No query parameters are required — each endpoint exports the full dataset.
GET /api/admin/export/subjects
Downloads all subjects as a CSV file.GET /api/admin/export/units
Downloads all units as a CSV file. Each row includes the parent subject’sname via population.
GET /api/admin/export/lessons
Downloads all lessons as a CSV file. Each row includes the parent unit’sname via population.
GET /api/admin/export/questions
Downloads all questions as a CSV file. Complex nested fields are flattened:tags is serialised as a semicolon-delimited string, and only the lesson name (not the full object) is included as lessonName. The export includes the following columns:
| Column | Description |
|---|---|
_id | Question ObjectId |
prompt | Question text |
type | Question type |
difficulty | Difficulty level |
xpValue | XP awarded on correct answer |
explanation | Explanation shown after answering |
hint | Optional hint available to the learner |
conceptExplanation | Deeper conceptual explanation |
tags | Semicolon-delimited tag list |
isAIGenerated | Whether the question was AI-generated |
aiModel | Model used for generation (if AI-generated) |
isReviewed | Whether the question has been approved |
isActive | Whether the question is live |
lessonName | Name of the associated lesson |
createdAt | Creation timestamp |
updatedAt | Last-updated timestamp |
Shop Item Management
Admins can create, update, and deleteShopItem documents independently of the public shop endpoints. All items — including those with isActive: false — are accessible from these endpoints.
GET /api/admin/shop-items
Returns all shop items, with optional filters. Results are sorted bytype then price.
Filter by item type. One of
"frame" or "background". Omit or pass "all" for no filter.Filter by rarity tier. One of
"common", "rare", "epic", "legendary". Omit or pass "all" for no filter.Filter by active status.
"true" or "false". Omit or pass "all" for no filter.Case-insensitive substring match against the item
name.Response 200 OK
POST /api/admin/shop-items
Creates a new shop item.Display name for the item.
Item category. Must be
"frame" or "background".Cost in gems.
Short flavour text. Defaults to
"".Rarity tier. One of
"common", "rare", "epic", "legendary". Defaults to "common".Whether the item is visible in the public shop. Defaults to
true.Raw CSS string used to render the item.
For
type: "background" items — "gradient" or "svg". Leave null for a plain CSS background.Adaptive gradient CSS values. Object with optional
light, dark, and highContrast string keys. Only used when backgroundType is "gradient".Full SVG string for overlay patterns. Only used when
backgroundType is "svg".Overlay opacity between
0 and 1. Defaults to 0.25.CSS
background-size string for tiling. Defaults to "40px 40px".Optional URL to an external image asset.
Response 201 Created
PUT /api/admin/shop-items/:id
Updates an existing shop item. Only the fields provided in the body are changed.MongoDB ObjectId of the shop item to update.
Response 200 OK
Error Responses
| Status | Condition |
|---|---|
404 | No item found with the given ID. |
DELETE /api/admin/shop-items/:id
Permanently deletes a shop item.MongoDB ObjectId of the shop item to delete.
Response 200 OK
Error Responses
| Status | Condition |
|---|---|
404 | No item found with the given ID. |