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 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.
401 Unauthorized.
Data Models
ShopItem
Each item in the shop is represented by aShopItem document.
MongoDB ObjectId that uniquely identifies the item.
Display name of the cosmetic item (e.g.,
"Golden Halo Frame").Short flavour text shown in the shop listing. Defaults to an empty string.
Category of the cosmetic. One of
"frame" (avatar border) or "background" (profile card background).Cost in gems required to purchase the item.
Visual tier of the item. One of
"common", "rare", "epic", or "legendary".When
false the item is hidden from the public shop listing but still accessible via admin endpoints.Optional URL pointing to an external image asset for this item.
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.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.Adaptive gradient colours keyed by theme. Only relevant when
backgroundType is "gradient".CSS
background value for the light theme.CSS
background value for the dark theme.CSS
background value for the high-contrast theme.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".Opacity of the SVG overlay (0–1). Defaults to
0.25.CSS
background-size value for the tiling pattern, e.g. "40px 40px". Defaults to "40px 40px".ISO 8601 timestamp of when the item was first created.
ISO 8601 timestamp of the last update.
UserInventory
AUserInventory document is created for each item a user purchases, and tracks whether it is currently equipped.
MongoDB ObjectId for this inventory entry.
ObjectId referencing the owning
User document.ObjectId referencing the purchased
ShopItem. Populated with the full ShopItem object in inventory responses.true if this item is currently active on the user’s profile. At most one frame and one background can be equipped simultaneously.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.
Response 200 OK
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 bypurchasedAt 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.
Response 200 OK
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 newUserInventory entry is created.
MongoDB ObjectId of the
ShopItem to purchase.Response 201 Created
Confirmation message.
The user’s gem balance after the purchase has been deducted.
The newly created
UserInventory document.Error Responses
| Status | Condition |
|---|---|
400 | The user already owns this item: { "message": "Ya tienes este item" } |
400 | The user has fewer gems than the item’s price: { "message": "No tienes suficientes gemas" } |
404 | No active item found with the given itemId. |
PUT /api/shop/equip/:itemId
Equips a previously purchased item. The server looks up the item’stype ("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.
MongoDB ObjectId of the
ShopItem to equip. The item must already be in the user’s inventory.Response 200 OK
Confirmation message.
The full populated
ShopItem that is now equipped.Error Responses
| Status | Condition |
|---|---|
404 | The 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 hasisEquipped: 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.
The slot to clear. Must be either
"frame" or "background".Response 200 OK
Error Responses
| Status | Condition |
|---|---|
400 | type is not "frame" or "background". |