Skip to main content

Documentation 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.

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 with 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.
Both roles are enforced by middleware. The 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.
curl -X GET https://your-sealearn-api.com/api/admin/stats \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{
  "ok": true,
  "data": {
    "totalUsers": 1420,
    "totalSubjects": 8,
    "totalUnits": 42,
    "totalLessons": 310,
    "totalQuestions": 4875,
    "pendingQuestions": 63
  }
}
ok
boolean
true on success.
data.totalUsers
number
Total number of registered user accounts.
data.totalSubjects
number
Total number of subjects in the content tree.
data.totalUnits
number
Total number of units across all subjects.
data.totalLessons
number
Total number of lessons across all units.
data.totalQuestions
number
Total number of questions in the database.
data.pendingQuestions
number
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
Page number (1-based). Defaults to 1.
limit
number
Results per page. Defaults to 20.
Case-insensitive substring match against username, email, and displayName.
role
string
Filter by role. One of "student", "admin", "superadmin". Omit or pass "all" to return all roles.
status
string
Filter by account status. "active" or "inactive". Omit or pass "all" to return both.
curl -X GET "https://your-sealearn-api.com/api/admin/users?page=1&limit=20&search=alice&role=student" \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{
  "ok": true,
  "data": {
    "users": [ /* user objects without password field */ ],
    "total": 87,
    "page": 1,
    "pages": 5
  }
}
data.users
array
Array of user objects. The password field is always excluded.
data.total
number
Total matching user count across all pages.
data.page
number
Current page number.
data.pages
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’s name and xpReward, sorted by most recently updated first.
id
string
required
MongoDB ObjectId of the target user.
curl -X GET https://your-sealearn-api.com/api/admin/users/663c0e1a2b3c4d5e6f789000/progress \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{
  "ok": true,
  "data": [
    {
      "lesson": { "_id": "...", "name": "Intro to Variables", "xpReward": 30 },
      "completed": true,
      "score": 95,
      "updatedAt": "2024-05-21T10:00:00.000Z"
    }
  ]
}

PUT /api/admin/users/:id

Updates editable fields on a user account. Only the fields provided in the request body are changed.
id
string
required
MongoDB ObjectId of the user to update.
displayName
string
New display name for the user.
email
string
New email address.
isActive
boolean
Set account active (true) or inactive (false).
curl -X PUT https://your-sealearn-api.com/api/admin/users/663c0e1a2b3c4d5e6f789000 \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "displayName": "Alice Revised", "email": "alice-new@example.com" }'

Response 200 OK

{
  "ok": true,
  "data": { /* updated user object without password */ }
}

PUT /api/admin/users/:id/role

This endpoint is restricted to superadmin only. Sending a request with an admin-role token returns 403 Forbidden. A superadmin cannot change their own role — attempting to do so returns 400 Bad Request.
Changes the platform role of a user account. Valid values are "student", "admin", and "superadmin".
id
string
required
MongoDB ObjectId of the target user.
role
string
required
The new role to assign. Must be one of "student", "admin", or "superadmin".
curl -X PUT https://your-sealearn-api.com/api/admin/users/663c0e1a2b3c4d5e6f789000/role \
  -H "Authorization: Bearer <superadmin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "role": "admin" }'

Response 200 OK

{
  "ok": true,
  "data": { /* updated user object without password */ }
}

Error Responses

StatusCondition
400role is not one of the three valid values.
400The superadmin tried to change their own role.
403Requester is not a superadmin.

PUT /api/admin/users/:id/ban

Toggles the isActive 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.
id
string
required
MongoDB ObjectId of the user to ban or unban.
curl -X PUT https://your-sealearn-api.com/api/admin/users/663c0e1a2b3c4d5e6f789000/ban \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{
  "ok": true,
  "data": { /* user object with updated isActive, password omitted */ }
}

DELETE /api/admin/users/:id

Permanently deletes a user account and all associated UserProgress records. This action cannot be undone.
id
string
required
MongoDB ObjectId of the user to delete.
curl -X DELETE https://your-sealearn-api.com/api/admin/users/663c0e1a2b3c4d5e6f789000 \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "message": "Usuario eliminado" }

Content Management

Subjects

GET /api/admin/subjects

Returns all subjects sorted by their order field.
curl -X GET https://your-sealearn-api.com/api/admin/subjects \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "data": [ /* subject objects */ ] }

POST /api/admin/subjects

Creates a new subject. All fields accepted by the Subject model may be provided in the request body.
curl -X POST https://your-sealearn-api.com/api/admin/subjects \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Mathematics", "icon": "📐", "color": "#4F46E5", "order": 1 }'

Response 201 Created

{ "ok": true, "data": { /* new subject object */ } }

PUT /api/admin/subjects/:id

Updates an existing subject by its ID.
id
string
required
MongoDB ObjectId of the subject to update.
curl -X PUT https://your-sealearn-api.com/api/admin/subjects/664a000000000000000000aa \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Advanced Mathematics" }'

Response 200 OK

{ "ok": true, "data": { /* updated subject object */ } }

DELETE /api/admin/subjects/:id

Permanently deletes a subject.
id
string
required
MongoDB ObjectId of the subject to delete.
curl -X DELETE https://your-sealearn-api.com/api/admin/subjects/664a000000000000000000aa \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "message": "Materia eliminada" }

Units

GET /api/admin/units

Returns all units across every subject. Each unit is populated with its parent subject’s name, icon, and color, sorted by order.
curl -X GET https://your-sealearn-api.com/api/admin/units \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "data": [ /* unit objects with populated subject */ ] }

GET /api/admin/subjects/:subjectId/units

Returns units that belong to a specific subject, sorted by order.
subjectId
string
required
MongoDB ObjectId of the parent subject.
curl -X GET https://your-sealearn-api.com/api/admin/subjects/664a000000000000000000aa/units \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "data": [ /* unit objects */ ] }

POST /api/admin/subjects/:subjectId/units

Creates a new unit nested under the given subject. The subject field is set automatically from the URL parameter.
subjectId
string
required
MongoDB ObjectId of the parent subject.
curl -X POST https://your-sealearn-api.com/api/admin/subjects/664a000000000000000000aa/units \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Algebra Basics", "order": 1 }'

Response 201 Created

{ "ok": true, "data": { /* new unit object */ } }

PUT /api/admin/units/:id

Updates an existing unit.
id
string
required
MongoDB ObjectId of the unit to update.
curl -X PUT https://your-sealearn-api.com/api/admin/units/664b000000000000000000bb \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Algebra Fundamentals", "order": 2 }'

Response 200 OK

{ "ok": true, "data": { /* updated unit object */ } }

DELETE /api/admin/units/:id

Permanently deletes a unit.
id
string
required
MongoDB ObjectId of the unit to delete.
curl -X DELETE https://your-sealearn-api.com/api/admin/units/664b000000000000000000bb \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "message": "Unidad eliminada" }

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.
curl -X GET https://your-sealearn-api.com/api/admin/lessons \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "data": [ /* lesson objects with fully populated unit → subject */ ] }

GET /api/admin/units/:unitId/lessons

Returns lessons belonging to a specific unit, sorted by order.
unitId
string
required
MongoDB ObjectId of the parent unit.
curl -X GET https://your-sealearn-api.com/api/admin/units/664b000000000000000000bb/lessons \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "data": [ /* lesson objects */ ] }

POST /api/admin/units/:unitId/lessons

Creates a new lesson nested under the given unit. The unit field is set automatically from the URL parameter.
unitId
string
required
MongoDB ObjectId of the parent unit.
curl -X POST https://your-sealearn-api.com/api/admin/units/664b000000000000000000bb/lessons \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Solving Linear Equations", "xpReward": 40, "order": 1 }'

Response 201 Created

{ "ok": true, "data": { /* new lesson object */ } }

PUT /api/admin/lessons/:id

Updates an existing lesson.
id
string
required
MongoDB ObjectId of the lesson to update.
curl -X PUT https://your-sealearn-api.com/api/admin/lessons/664c000000000000000000cc \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "xpReward": 50 }'

Response 200 OK

{ "ok": true, "data": { /* updated lesson object */ } }

DELETE /api/admin/lessons/:id

Permanently deletes a lesson.
id
string
required
MongoDB ObjectId of the lesson to delete.
curl -X DELETE https://your-sealearn-api.com/api/admin/lessons/664c000000000000000000cc \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "message": "Lección eliminada" }

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.
lessonId
string
Filter to questions belonging to a specific lesson.
unitId
string
Filter to questions belonging to any lesson within a specific unit.
subjectId
string
Filter to questions belonging to any lesson within any unit under a specific subject.
type
string
Filter by question type (e.g., "multiple_choice", "true_false").
difficulty
string
Filter by difficulty level (e.g., "easy", "medium", "hard").
reviewed
string
Filter by review status. Pass "true" for approved questions, "false" for pending. Omit or pass "all" for no filter.
reported
string
Pass "true" to return only questions that have at least one active report, sorted by most recently reported first.
search
string
Case-insensitive substring search against the question prompt field.
page
number
Page number (1-based). Defaults to 1.
limit
number
Results per page. Defaults to 15.
curl -X GET "https://your-sealearn-api.com/api/admin/questions?lessonId=664c000000000000000000cc&reviewed=false&page=1" \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{
  "ok": true,
  "data": {
    "questions": [
      {
        "_id": "665d...",
        "prompt": "What is the value of x in 2x + 4 = 12?",
        "type": "multiple_choice",
        "difficulty": "easy",
        "isReviewed": false,
        "isActive": false,
        "lesson": { "_id": "...", "name": "Solving Linear Equations", "unit": { "_id": "...", "name": "Algebra Basics" } }
      }
    ],
    "total": 63,
    "page": 1,
    "pages": 5
  }
}

POST /api/admin/questions

Manually creates a new question. All fields defined by the Question model may be supplied in the request body.
curl -X POST https://your-sealearn-api.com/api/admin/questions \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "lesson": "664c000000000000000000cc",
    "prompt": "What is the slope-intercept form of a line?",
    "type": "multiple_choice",
    "difficulty": "medium",
    "isReviewed": true,
    "isActive": true,
    "xpValue": 20
  }'

Response 201 Created

{ "ok": true, "data": { /* new question object */ } }

PUT /api/admin/questions/:id

Updates the fields of an existing question.
id
string
required
MongoDB ObjectId of the question to update.
curl -X PUT https://your-sealearn-api.com/api/admin/questions/665d000000000000000000dd \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "difficulty": "hard", "xpValue": 35 }'

Response 200 OK

{ "ok": true, "data": { /* updated question object */ } }

PUT /api/admin/questions/:id/review

Approves or rejects a question. Sets both isReviewed and isActive to the value of approved. After approval (approved: true) the question becomes live and will appear in learner sessions.
id
string
required
MongoDB ObjectId of the question to review.
approved
boolean
required
true to approve the question (sets isReviewed: true, isActive: true). false to reject it (sets both to false).
curl -X PUT https://your-sealearn-api.com/api/admin/questions/665d000000000000000000dd/review \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "approved": true }'

Response 200 OK

{ "ok": true, "data": { /* updated question object with isReviewed: true, isActive: true */ } }

PUT /api/admin/questions/:id/clear-reports

Clears all user-submitted reports on a question by setting its reports array to []. Use this after investigating a report to mark the question as clean without deleting it.
id
string
required
MongoDB ObjectId of the question whose reports should be cleared.
curl -X PUT https://your-sealearn-api.com/api/admin/questions/665d000000000000000000dd/clear-reports \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{
  "ok": true,
  "message": "Todos los reportes de esta pregunta han sido eliminados.",
  "data": { /* question object with empty reports array */ }
}

DELETE /api/admin/questions/:id

Permanently deletes a question.
id
string
required
MongoDB ObjectId of the question to delete.
curl -X DELETE https://your-sealearn-api.com/api/admin/questions/665d000000000000000000dd \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "message": "Pregunta eliminada" }

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 with isReviewed: false and isActive: false — they will not appear in learner sessions until an admin approves them via PUT /api/admin/questions/:id/review.
lessonId
string
required
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.
count
number
Number of questions to generate. Defaults to 5.
difficulty
string
Target difficulty level for all generated questions (e.g., "easy", "medium", "hard"). Defaults to "medium".
allowedTypes
array
Array of question type strings the generator may produce (e.g., ["multiple_choice", "true_false"]). When omitted, all supported types are permitted.
curl -X POST https://your-sealearn-api.com/api/admin/questions/generate \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "lessonId": "664c000000000000000000cc",
    "count": 10,
    "difficulty": "medium",
    "allowedTypes": ["multiple_choice", "true_false"]
  }'

Response 201 Created

{
  "ok": true,
  "message": "10 preguntas generadas con IA. Deben ser revisadas antes de activarse.",
  "data": [ /* array of newly created question objects */ ]
}
message
string
Confirmation message indicating how many questions were saved and that they require review.
data
array
Array of the newly inserted question documents, all with isReviewed: false and isActive: false.

Error Responses

StatusCondition
404No lesson found for the provided lessonId.

CSV Export

All export endpoints respond with a text/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.
curl -X GET https://your-sealearn-api.com/api/admin/export/subjects \
  -H "Authorization: Bearer <admin-token>" \
  -o subjects.csv

GET /api/admin/export/units

Downloads all units as a CSV file. Each row includes the parent subject’s name via population.
curl -X GET https://your-sealearn-api.com/api/admin/export/units \
  -H "Authorization: Bearer <admin-token>" \
  -o units.csv

GET /api/admin/export/lessons

Downloads all lessons as a CSV file. Each row includes the parent unit’s name via population.
curl -X GET https://your-sealearn-api.com/api/admin/export/lessons \
  -H "Authorization: Bearer <admin-token>" \
  -o lessons.csv

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:
ColumnDescription
_idQuestion ObjectId
promptQuestion text
typeQuestion type
difficultyDifficulty level
xpValueXP awarded on correct answer
explanationExplanation shown after answering
hintOptional hint available to the learner
conceptExplanationDeeper conceptual explanation
tagsSemicolon-delimited tag list
isAIGeneratedWhether the question was AI-generated
aiModelModel used for generation (if AI-generated)
isReviewedWhether the question has been approved
isActiveWhether the question is live
lessonNameName of the associated lesson
createdAtCreation timestamp
updatedAtLast-updated timestamp
curl -X GET https://your-sealearn-api.com/api/admin/export/questions \
  -H "Authorization: Bearer <admin-token>" \
  -o questions.csv

Shop Item Management

Admins can create, update, and delete ShopItem 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 by type then price.
type
string
Filter by item type. One of "frame" or "background". Omit or pass "all" for no filter.
rarity
string
Filter by rarity tier. One of "common", "rare", "epic", "legendary". Omit or pass "all" for no filter.
isActive
string
Filter by active status. "true" or "false". Omit or pass "all" for no filter.
search
string
Case-insensitive substring match against the item name.
curl -X GET "https://your-sealearn-api.com/api/admin/shop-items?type=frame&rarity=epic&isActive=true" \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "data": [ /* ShopItem objects */ ] }

POST /api/admin/shop-items

Creates a new shop item.
name
string
required
Display name for the item.
type
string
required
Item category. Must be "frame" or "background".
price
number
required
Cost in gems.
description
string
Short flavour text. Defaults to "".
rarity
string
Rarity tier. One of "common", "rare", "epic", "legendary". Defaults to "common".
isActive
boolean
Whether the item is visible in the public shop. Defaults to true.
cssValue
string
Raw CSS string used to render the item.
backgroundType
string
For type: "background" items — "gradient" or "svg". Leave null for a plain CSS background.
themeVariants
object
Adaptive gradient CSS values. Object with optional light, dark, and highContrast string keys. Only used when backgroundType is "gradient".
patternSvg
string
Full SVG string for overlay patterns. Only used when backgroundType is "svg".
patternOpacity
number
Overlay opacity between 0 and 1. Defaults to 0.25.
patternSize
string
CSS background-size string for tiling. Defaults to "40px 40px".
assetUrl
string
Optional URL to an external image asset.
curl -X POST https://your-sealearn-api.com/api/admin/shop-items \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ocean Waves Background",
    "type": "background",
    "price": 400,
    "rarity": "rare",
    "backgroundType": "gradient",
    "themeVariants": {
      "light": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
      "dark": "linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)",
      "highContrast": "linear-gradient(135deg, #000000 0%, #1a1a2e 100%)"
    }
  }'

Response 201 Created

{ "ok": true, "data": { /* new ShopItem object */ } }

PUT /api/admin/shop-items/:id

Updates an existing shop item. Only the fields provided in the body are changed.
id
string
required
MongoDB ObjectId of the shop item to update.
curl -X PUT https://your-sealearn-api.com/api/admin/shop-items/664a1f2b3c4d5e6f78901234 \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{ "price": 350, "isActive": false }'

Response 200 OK

{ "ok": true, "data": { /* updated ShopItem object */ } }

Error Responses

StatusCondition
404No item found with the given ID.

DELETE /api/admin/shop-items/:id

Permanently deletes a shop item.
id
string
required
MongoDB ObjectId of the shop item to delete.
curl -X DELETE https://your-sealearn-api.com/api/admin/shop-items/664a1f2b3c4d5e6f78901234 \
  -H "Authorization: Bearer <admin-token>"

Response 200 OK

{ "ok": true, "message": "Item eliminado" }

Error Responses

StatusCondition
404No item found with the given ID.

Build docs developers (and LLMs) love