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 Shop API lets authenticated users browse available cosmetic items, spend their earned gems to purchase avatar frames and profile backgrounds, and manage which items are active on their profile. Every endpoint in this group requires a valid JWT issued by the Auth API — requests without a token will be rejected with 401 Unauthorized.

Data Models

ShopItem

Each item in the shop is represented by a ShopItem document.
_id
string
MongoDB ObjectId that uniquely identifies the item.
name
string
Display name of the cosmetic item (e.g., "Golden Halo Frame").
description
string
Short flavour text shown in the shop listing. Defaults to an empty string.
type
string
Category of the cosmetic. One of "frame" (avatar border) or "background" (profile card background).
price
number
Cost in gems required to purchase the item.
rarity
string
Visual tier of the item. One of "common", "rare", "epic", or "legendary".
isActive
boolean
When false the item is hidden from the public shop listing but still accessible via admin endpoints.
assetUrl
string | null
Optional URL pointing to an external image asset for this item.
cssValue
string | null
Raw CSS string used to render the item. For frames this is a multi-layer box-shadow value; for backgrounds it acts as a direct CSS background fallback.
backgroundType
string | null
Only present on type: "background" items. Determines the render strategy: "gradient" (uses themeVariants) or "svg" (uses patternSvg as an overlay). null means the item uses cssValue directly.
themeVariants
object | null
Adaptive gradient colours keyed by theme. Only relevant when backgroundType is "gradient".
themeVariants.light
string | null
CSS background value for the light theme.
themeVariants.dark
string | null
CSS background value for the dark theme.
themeVariants.highContrast
string | null
CSS background value for the high-contrast theme.
patternSvg
string | null
Full SVG string rendered as a tiling overlay. Uses currentColor for strokes so the frontend can substitute the active theme colour before converting to a data URI. Only relevant when backgroundType is "svg".
patternOpacity
number
Opacity of the SVG overlay (0–1). Defaults to 0.25.
patternSize
string
CSS background-size value for the tiling pattern, e.g. "40px 40px". Defaults to "40px 40px".
createdAt
string
ISO 8601 timestamp of when the item was first created.
updatedAt
string
ISO 8601 timestamp of the last update.

UserInventory

A UserInventory document is created for each item a user purchases, and tracks whether it is currently equipped.
_id
string
MongoDB ObjectId for this inventory entry.
userId
string
ObjectId referencing the owning User document.
itemId
string | ShopItem
ObjectId referencing the purchased ShopItem. Populated with the full ShopItem object in inventory responses.
isEquipped
boolean
true if this item is currently active on the user’s profile. At most one frame and one background can be equipped simultaneously.
purchasedAt
string
ISO 8601 timestamp of when the item was purchased. Defaults to the time of document creation.

Endpoints

GET /api/shop/items

Returns every active shop item (isActive: true), sorted by price ascending. Each item in the response is annotated with an owned boolean that reflects whether the authenticated user has already purchased it.
curl -X GET https://your-sealearn-api.com/api/shop/items \
  -H "Authorization: Bearer <token>"

Response 200 OK

[
  {
    "_id": "664a1f...",
    "name": "Coral Frame",
    "description": "A warm coral border for your avatar.",
    "type": "frame",
    "price": 150,
    "rarity": "common",
    "isActive": true,
    "cssValue": "0 0 0 4px #FF6B6B, 0 0 0 7px #FFE66D",
    "assetUrl": null,
    "backgroundType": null,
    "themeVariants": null,
    "patternSvg": null,
    "patternOpacity": 0.25,
    "patternSize": "40px 40px",
    "owned": false,
    "createdAt": "2024-05-19T10:00:00.000Z",
    "updatedAt": "2024-05-19T10:00:00.000Z"
  }
]
[].owned
boolean
true when the authenticated user has this item in their inventory; false otherwise.

GET /api/shop/inventory

Returns the full inventory of the authenticated user — all items they have purchased — sorted by purchasedAt descending. Each entry has the referenced ShopItem populated in full, so no additional request is needed to display item details. The isEquipped field on each entry tells the client which frame and background are currently active.
curl -X GET https://your-sealearn-api.com/api/shop/inventory \
  -H "Authorization: Bearer <token>"

Response 200 OK

[
  {
    "_id": "665b2a...",
    "userId": "663c0e...",
    "itemId": {
      "_id": "664a1f...",
      "name": "Coral Frame",
      "type": "frame",
      "price": 150,
      "rarity": "common",
      "cssValue": "0 0 0 4px #FF6B6B, 0 0 0 7px #FFE66D"
    },
    "isEquipped": true,
    "purchasedAt": "2024-05-20T08:30:00.000Z",
    "createdAt": "2024-05-20T08:30:00.000Z",
    "updatedAt": "2024-05-20T09:00:00.000Z"
  }
]

POST /api/shop/buy/:itemId

Purchases a shop item on behalf of the authenticated user. The server verifies that the item is active, that the user does not already own it, and that the user has enough gems. On success, the gem cost is deducted from the user’s balance and a new UserInventory entry is created.
itemId
string
required
MongoDB ObjectId of the ShopItem to purchase.
curl -X POST https://your-sealearn-api.com/api/shop/buy/664a1f2b3c4d5e6f78901234 \
  -H "Authorization: Bearer <token>"

Response 201 Created

{
  "message": "Item comprado exitosamente",
  "gemsRemaining": 350,
  "inventoryEntry": {
    "_id": "665b2a...",
    "userId": "663c0e...",
    "itemId": "664a1f...",
    "isEquipped": false,
    "purchasedAt": "2024-05-21T14:00:00.000Z"
  }
}
message
string
Confirmation message.
gemsRemaining
number
The user’s gem balance after the purchase has been deducted.
inventoryEntry
object
The newly created UserInventory document.

Error Responses

StatusCondition
400The user already owns this item: { "message": "Ya tienes este item" }
400The user has fewer gems than the item’s price: { "message": "No tienes suficientes gemas" }
404No active item found with the given itemId.

PUT /api/shop/equip/:itemId

Equips a previously purchased item. The server looks up the item’s type ("frame" or "background") and automatically unequips any other item of the same type that the user currently has active. It then sets isEquipped: true on the chosen inventory entry and updates the corresponding activeFrame or activeBackground field on the User document.
itemId
string
required
MongoDB ObjectId of the ShopItem to equip. The item must already be in the user’s inventory.
curl -X PUT https://your-sealearn-api.com/api/shop/equip/664a1f2b3c4d5e6f78901234 \
  -H "Authorization: Bearer <token>"

Response 200 OK

{
  "message": "Item equipado",
  "item": {
    "_id": "664a1f...",
    "name": "Coral Frame",
    "type": "frame",
    "cssValue": "0 0 0 4px #FF6B6B, 0 0 0 7px #FFE66D"
  }
}
message
string
Confirmation message.
item
object
The full populated ShopItem that is now equipped.

Error Responses

StatusCondition
404The item does not exist in the user’s inventory.

PUT /api/shop/unequip/:type

Unequips the currently active item in a given slot. Any inventory entry of the matching type that has isEquipped: true is set to false, and the corresponding activeFrame or activeBackground reference on the User document is cleared to null. If nothing is equipped in that slot, the request still succeeds.
type
string
required
The slot to clear. Must be either "frame" or "background".
curl -X PUT https://your-sealearn-api.com/api/shop/unequip/frame \
  -H "Authorization: Bearer <token>"

Response 200 OK

{
  "message": "Item desequipado"
}

Error Responses

StatusCondition
400type is not "frame" or "background".

Build docs developers (and LLMs) love