The Products API manages everything sold at the Spartans Gym front desk: supplements, drinks, snacks, accessories, and branded merchandise. Each product tracks its current stock against a configurable reorder threshold, and every response includes a computedDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/azahel79/Spartans-gym/llms.txt
Use this file to discover all available pages before exploring further.
status field that tells you at a glance whether a product is fully stocked, running low, or sold out. Product images are stored on Cloudinary — the API handles uploads, replacements, and deletions automatically. All endpoints require a valid Bearer token; write operations are restricted to admin users.
The Product Object
Auto-incremented integer identifier for the product.
Display name of the product.
Retail price in MXN (
Decimal(10,2) in the database, returned as a JavaScript number).Product category. One of
Suplementos, Bebidas, Snacks, Merchandising, or Accesorios.Stock-Keeping Unit — a unique identifier string for the product. Enforced as unique at the database level.
Current quantity on hand.
Reorder threshold. When
stock falls to or below this value the computed status changes to "Stock Bajo". Defaults to 5 on creation.Cloudinary URL for the product image, or
null if no image has been uploaded.Computed field (not stored in the database). Derived from
stock and reorder at query time:| Condition | Status |
|---|---|
stock <= 0 | "Agotado" |
stock <= reorder | "Stock Bajo" |
stock > reorder | "En Stock" |
ISO 8601 datetime when the product was created.
ISO 8601 datetime when the product was last modified.
Endpoints
List Products
Requires a valid Bearer token. Accessible to all roles (
admin and recepcionista).status field is computed on every item in the response. All query parameters are optional.
Filter by category. Accepted values:
Suplementos, Bebidas, Snacks, Merchandising, Accesorios. Pass Todos or omit to return all categories.Case-insensitive substring match against the product
name.200 OK
| Status | Description |
|---|---|
401 | Missing or invalid Bearer token. |
403 | Insufficient role. |
500 | Internal server error. |
Get Product by ID
Requires a valid Bearer token. Accessible to all roles.
status.
The numeric ID of the product.
200 OK
Returns a single Product object (including computed status) inside data.
Error Responses
| Status | Description |
|---|---|
401 | Missing or invalid Bearer token. |
403 | Insufficient role. |
404 | No product found with the given ID. |
500 | Internal server error. |
Create Product
This endpoint uses
multipart/form-data, not application/json, because it accepts an optional image file upload. Set your request’s Content-Type to multipart/form-data (most HTTP clients and <form> elements do this automatically when a file field is included).image file is included, it is uploaded to Cloudinary and the returned URL is stored in image. The sku must be unique — a 400 is returned if a product with that SKU already exists.
Product display name.
Retail price in MXN. Sent as a form string; the server parses it with
parseFloat.Category. One of
Suplementos, Bebidas, Snacks, Merchandising, Accesorios.Unique SKU string. Returns
400 if already in use.Initial stock quantity. Defaults to
0 if omitted.Reorder threshold. Defaults to
5 if omitted.Optional product image. Must be a valid image file; uploaded to Cloudinary on success. Returns
400 if the upload fails.201 Created
| Status | Description |
|---|---|
400 | Missing required fields, duplicate SKU, or Cloudinary upload failure. |
401 | Missing or invalid Bearer token. |
403 | User is not an admin. |
500 | Internal server error. |
Update Product
Like
POST /api/products, this endpoint also uses multipart/form-data to support image file replacement. Supply only the fields you wish to change.- No image changes: omit both
imageandremoveImage— the existing image URL is preserved. - Remove image: include
removeImage=truein the form data. The existing Cloudinary asset is deleted andimageis set tonull. - Replace image: include a new
imagefile. The existing Cloudinary asset is deleted before the new one is uploaded.
Numeric ID of the product to update.
Updated product name.
Updated retail price in MXN.
Updated category.
Updated SKU. Returns
400 if a different product already uses this value.Updated stock quantity.
Updated reorder threshold.
Pass
"true" to delete the existing Cloudinary image and set image to null. Ignored if a new image file is also provided (replacement takes priority).New image file. Replaces the existing image: the old Cloudinary asset is deleted first, then the new file is uploaded.
200 OK
Returns the full updated Product object (including computed status) inside data.
Error Responses
| Status | Description |
|---|---|
400 | Duplicate SKU or Cloudinary upload failure. |
401 | Missing or invalid Bearer token. |
403 | User is not an admin. |
404 | No product found with the given ID. |
500 | Internal server error. |
Delete Product
Permanently deletes a product and its associated Cloudinary image (if any).Numeric ID of the product to delete.
200 OK
| Status | Description |
|---|---|
401 | Missing or invalid Bearer token. |
403 | User is not an admin. |
404 | No product found with the given ID. |
500 | Internal server error. |
Adjust Stock
Sets the absolute stock level for a product. This is not an increment/decrement operation — the value you provide becomes the newstock. Use this for inventory corrections, physical counts, or manual adjustments. An optional reason string is logged server-side for audit purposes but is not persisted to the database.
Numeric ID of the product to adjust.
New absolute stock value. Must be a non-negative integer. Setting this to
0 will result in a computed status of "Agotado".Optional human-readable reason for the adjustment (e.g.
"Inventario físico julio 2025"). Logged to server output for audit trails but not stored in the database.200 OK
| Status | Description |
|---|---|
400 | stock field is missing from the request body. |
401 | Missing or invalid Bearer token. |
403 | User is not an admin. |
404 | No product found with the given ID. |
500 | Internal server error. |