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 Users API covers the full lifecycle of a Sealearn account: creating a user, authenticating them, reading their profile, and updating settings like username, display name, and favorite subjects. All write operations that affect a specific user’s account require a valid JWT token in the Authorization: Bearer <token> header. Refer to the Authentication API for how to obtain a token. User documents include gamification fields (XP, level, gems, hearts, streaks, league), cosmetic preferences, duel statistics, and computed virtual fields that the server calculates on the fly.

Endpoints

POST /api/users/register

Creates a new user account. After registration a verification email is dispatched — no JWT token is returned at this stage. The user must verify their email before they can log in via POST /api/users/login.
Both username and email must be globally unique. The username is stored in lowercase and must match ^[a-zA-Z0-9_]{3,20}$.

Request body

username
string
required
Unique username. 3–20 characters; letters, digits, and underscores only (^[a-zA-Z0-9_]{3,20}$). Stored in lowercase.
email
string
required
Valid email address. Must be unique across all accounts. Stored in lowercase.
password
string
required
Minimum 6 characters. Hashed with bcrypt (cost factor 12) before storage; never returned in any response.

Responses

StatusMeaning
201Account created; verification email sent.
400Email or username already in use, or validation failed.
201 Created
ok
boolean
true on success.
message
string
"Usuario registrado. Revisa tu correo para verificar la cuenta.".
data
object
Partial user document — no token is included.
curl -X POST https://api.sealearn.app/api/users/register \
  -H "Content-Type: application/json" \
  -d '{
    "username": "piranha42",
    "email": "piranha42@example.com",
    "password": "s3cur3P@ss"
  }'

POST /api/users/login

Authenticates a user with their email and password. Returns a 7-day JWT token alongside the full user document (including populated achievements, favorite subjects, and live streak data).
Login is blocked for accounts whose email has not yet been verified. The API returns 403 in that case. Use POST /api/auth/resend-verification to resend the verification email.

Request body

email
string
required
The email address used during registration.
password
string
required
The account password.

Responses

StatusMeaning
200Authentication successful; token and user data returned.
401Incorrect email or password.
403Account email not yet verified.
500Internal server error.
200 OK
ok
boolean
true on success.
token
string
Signed JWT valid for 7 days. Include this value in the Authorization: Bearer <token> header for authenticated requests.
data
object
Full user document. See User object reference for all fields.
curl -X POST https://api.sealearn.app/api/users/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "piranha42@example.com",
    "password": "s3cur3P@ss"
  }'

GET /api/users/me

Returns the complete profile of the currently authenticated user, including populated achievements and favorite subjects, a live heart-refill check, and computed streak data. Use this endpoint to bootstrap the client UI after login or on page load. Requires authentication.

Responses

StatusMeaning
200User document returned.
401Missing, expired, or invalid token.
404User referenced by token no longer exists.
500Internal server error.
200 OK
ok
boolean
true on success.
data
object
Full user document with virtual fields and live streak object. See User object reference.
curl https://api.sealearn.app/api/users/me \
  -H "Authorization: Bearer <token>"

GET /api/users/check-username/:username

Checks whether a given username is available and matches the required format. Useful for real-time validation in registration or username-change forms.

Path parameters

username
string
required
The username to check. Must satisfy ^[a-zA-Z0-9_]{3,20}$; otherwise available is false with a reason of "Formato inválido" without querying the database.

Responses

StatusMeaning
200Check completed (see available).
500Internal server error.
200 OK
ok
boolean
true on success.
available
boolean
true if the username is free and format-valid, false otherwise.
reason
string
Only present when available is false due to format validation: "Formato inválido".
curl https://api.sealearn.app/api/users/check-username/piranha42

PUT /api/users/username

Changes the authenticated user’s username. Usernames can only be changed once every 30 days — the cooldown is tracked via the usernameChangedAt field. The new username is lowercased before storage. Requires authentication.

Request body

username
string
required
The desired new username. Must match ^[a-zA-Z0-9_]{3,20}$ and be globally unique.

Responses

StatusMeaning
200Username updated successfully.
400Missing or invalid format, cooldown still active, or username already taken.
401Missing, expired, or invalid token.
500Internal server error.
200 OK
ok
boolean
true on success.
data
object
If the cooldown has not elapsed, the API returns 400 with a message such as "Podés cambiar el username en 14 días". The exact number of days remaining is calculated dynamically from usernameChangedAt.
curl -X PUT https://api.sealearn.app/api/users/username \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "username": "sharkbait99" }'

PUT /api/users/display-name

Updates the authenticated user’s display name — the name shown in the UI, distinct from the @username. Display names can be changed at any time without a cooldown. Requires authentication.

Request body

displayName
string
required
The new display name. Maximum 30 characters. Leading and trailing whitespace is trimmed. Cannot be blank.

Responses

StatusMeaning
200Display name updated.
400Display name missing, blank, or exceeds 30 characters.
401Missing, expired, or invalid token.
500Internal server error.
200 OK
ok
boolean
true on success.
data
object
curl -X PUT https://api.sealearn.app/api/users/display-name \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "displayName": "The Great Piranha" }'

POST /api/users/toggle-favorite

Adds or removes a subject from the authenticated user’s favoriteSubjects array. If the subject is already in the array it is removed; if it is absent it is added. Returns the updated full user document with populated subjects. Requires authentication.

Request body

subjectId
string
required
MongoDB ObjectId of the subject to toggle.

Responses

StatusMeaning
200Favorite subjects list updated.
401Missing, expired, or invalid token.
500Internal server error.
200 OK
ok
boolean
true on success.
data
object
Full updated user document with favoriteSubjects populated. See User object reference.
curl -X POST https://api.sealearn.app/api/users/toggle-favorite \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "subjectId": "665f4e2b3a9c2d001f8e4abc" }'

GET /api/users/verify-email

Validates an email verification token and marks the account as verified. This endpoint is typically reached by clicking the link in the registration email rather than being called programmatically. On success or failure it redirects the browser to the appropriate frontend route — it does not return a JSON body.

Query parameters

token
string
required
The 64-character hex verification token included in the registration email.

Behavior

ConditionRedirect target
Token is valid and not expiredFRONTEND_URL/login?verified=true
token query param is missingFRONTEND_URL/verify-email?error=missing_token
Token not found or expiredFRONTEND_URL/verify-email?error=invalid_or_expired
Server errorFRONTEND_URL/verify-email?error=server_error
# Typically followed from an email link, but can be tested with curl:
curl -L "https://api.sealearn.app/api/users/verify-email?token=<64-char-hex-token>"

POST /api/users/resend-verification

Generates a fresh 24-hour verification token and resends the verification email. Use this when the user’s original verification link has expired.

Request body

email
string
required
The email address of the unverified account.

Responses

StatusMeaning
200Verification email resent successfully.
400Email not provided, or the account is already verified.
404No account found for this email address.
500Internal server error.
200 OK
ok
boolean
true on success.
message
string
"Correo de verificación reenviado".
curl -X POST https://api.sealearn.app/api/users/resend-verification \
  -H "Content-Type: application/json" \
  -d '{ "email": "piranha42@example.com" }'

User object reference

The following describes the shape of the data object returned by the login, /me, and toggle-favorite endpoints. Virtual fields (xpForNextLevel, xpProgress, currentStreak) are computed server-side and included automatically because the schema is configured with toJSON: { virtuals: true }.
_id
string
MongoDB ObjectId that uniquely identifies the user.
username
string
Unique login handle. Lowercase alphanumeric + underscore, 3–20 characters.
displayName
string
Human-readable display name shown in the UI. Defaults to username at account creation. Max 30 characters.
email
string
Lowercase email address. Not returned in unauthenticated contexts.
role
string
Account permission level. One of "student", "admin", or "superadmin". New accounts default to "student".
avatar
string | null
URL or identifier of the user’s avatar image. null if no avatar has been set.
banner
string | null
URL or identifier of the user’s profile banner. null if not set.
xp
number
Total experience points accumulated across all completed lessons and activities. Always ≥ 0.
level
number
Current level, derived from xp. Level-up thresholds follow the formula floor(100 × 1.5^(level−1)). Always ≥ 1.
gems
number
In-app currency used to purchase cosmetic items (frames, backgrounds) and refill hearts in the shop. Always ≥ 0.
hearts
object
Life system. One heart is consumed per wrong answer; a refill of 1 heart occurs automatically every 30 minutes when below the maximum.
streak
object
Daily activity streak information resolved at query time against the Streak collection.
league
string
Current league tier. One of "bronze", "silver", "gold", "sapphire", "emerald", "diamond", "master", "champion", or "heroic". Defaults to "bronze".
dailyGoal
number
User-configured daily XP target. Allowed values: 10, 20, 30, 50. Defaults to 10.
achievements
array
Array of populated Achievement documents earned by the user. Empty array until the first achievement is unlocked.
activeFrame
string (ObjectId) | null
Reference to the ShopItem currently equipped as the profile picture frame. null if no frame is active.
activeBackground
string (ObjectId) | null
Reference to the ShopItem currently equipped as the profile background. null if no background is active.
favoriteSubjects
array
Array of populated Subject documents the user has marked as favorites. Managed via POST /api/users/toggle-favorite.
duelsStats
object
Aggregated duel performance statistics.
xpForNextLevel
number
Virtual. XP required to reach the next level, calculated as floor(100 × 1.5^(level−1)).
xpProgress
number
Virtual. Percentage of XP progress toward the next level, 0–100. Calculated from the XP accumulated since the start of the current level relative to the XP needed to complete it.
currentStreak
number
Virtual. Active streak count based on the embedded streak.lastActivityDate. Returns streak.current if the last activity was today or yesterday; returns 0 if the streak has lapsed.

Build docs developers (and LLMs) love