Documentation Index
Fetch the complete documentation index at: https://mintlify.com/JuanSebasSV/healtyhelp/llms.txt
Use this file to discover all available pages before exploring further.
Recipes API
Base path: /api/recipes
Public read endpoints require no authentication. Admin write endpoints require Authorization: Bearer <token> from an account with role: "admin". Review endpoints require any authenticated user token.
The Recipe Object
{
"_id": "64b2a3c4d5e6f7a8b9c0d1e2",
"nombre": "Ensalada Mediterránea",
"desc": "Fresca ensalada con tomates cherry, aceitunas y queso feta.",
"img": "https://res.cloudinary.com/demo/image/upload/v1/recipes/ensalada.jpg",
"cat": "almuerzo",
"salud": ["sin-gluten", "vegano"],
"ingredientes": [
"200g tomates cherry",
"50g aceitunas negras",
"80g queso feta",
"2 cucharadas aceite de oliva"
],
"pasos": [
"Lava y corta los tomates.",
"Mezcla todos los ingredientes en un bol.",
"Aliña con aceite de oliva y sal."
],
"nutri": {
"cal": 320,
"carb": 12,
"gras": 24,
"prot": 10,
"fiber": 3,
"sodio": 480,
"azucar": 6,
"vitC": 22
},
"puntosProm": 4.7,
"totalResenas": 23,
"createdBy": "64a1f2c3d4e5f6a7b8c9d0e1",
"createdAt": "2024-03-01T10:00:00.000Z",
"updatedAt": "2024-04-15T08:30:00.000Z"
}
Core recipe fields
| Field | Type | Description |
|---|
_id | string | MongoDB ObjectId |
nombre | string | Recipe name. Max 200 chars. |
desc | string | Description. Max 1000 chars. |
img | string | Cover image URL |
cat | string | One of desayuno, almuerzo, cena, postres-snacks |
salud | string[] | Health/dietary tags (free-form strings) |
ingredientes | string[] | Ingredient list |
pasos | string[] | Step-by-step instructions |
nutri | object | Nutritional data (see below) |
puntosProm | number | Average star rating (0–5, one decimal place) |
totalResenas | number | Total review count |
createdBy | string | ObjectId of the admin who created the recipe |
createdAt | string | ISO 8601 timestamp |
updatedAt | string | ISO 8601 timestamp |
Nutritional schema (nutri)
All nutri values are numbers defaulting to 0. Units follow USDA conventions (kcal for energy, grams for macros, mg for minerals and most vitamins, µg where noted).
Macronutrients & energy
| Key | Description |
|---|
cal | Calories (kcal) |
carb | Total carbohydrates (g) |
carbNetos | Net carbs (g) |
gras | Total fat (g) |
prot | Protein (g) |
fiber | Dietary fiber (g) |
Fats breakdown
| Key | Description |
|---|
grasSat | Saturated fat (g) |
grasMonoins | Monounsaturated fat (g) |
grasPoliins | Polyunsaturated fat (g) |
grasTrans | Trans fat (g) |
omega3 | Omega-3 (g) |
omega6 | Omega-6 (g) |
ala | Alpha-linolenic acid (g) |
dha | DHA (g) |
epa | EPA (g) |
dpa | DPA (g) |
Sugars breakdown
| Key | Description |
|---|
azucar | Total sugars (g) |
sacarosa | Sucrose (g) |
glucosa | Glucose (g) |
fructosa | Fructose (g) |
lactosa | Lactose (g) |
maltosa | Maltose (g) |
galactosa | Galactose (g) |
almidon | Starch (g) |
Minerals
| Key | Description |
|---|
sodio | Sodium (mg) |
colesterol | Cholesterol (mg) |
calcio | Calcium (mg) |
hierro | Iron (mg) |
potasio | Potassium (mg) |
magnesio | Magnesium (mg) |
fosforo | Phosphorus (mg) |
zinc | Zinc (mg) |
selenio | Selenium (µg) |
cobre | Copper (mg) |
manganeso | Manganese (mg) |
fluor | Fluoride (mg) |
Vitamins
| Key | Description |
|---|
vitC | Vitamin C (mg) |
vitA | Vitamin A (µg RAE) |
vitAui | Vitamin A (IU) |
vitD | Vitamin D (µg) |
vitDui | Vitamin D (IU) |
vitD2 | Vitamin D2 (µg) |
vitD3 | Vitamin D3 (µg) |
vitE | Vitamin E (mg) |
vitK | Vitamin K (µg) |
vitB6 | Vitamin B6 (mg) |
vitB12 | Vitamin B12 (µg) |
niacina | Niacin / B3 (mg) |
riboflavina | Riboflavin / B2 (mg) |
tiamina | Thiamine / B1 (mg) |
folato | Folate (µg DFE) |
acidoPant | Pantothenic acid / B5 (mg) |
retinol | Retinol (µg) |
betaCaroteno | Beta-carotene (µg) |
alfaCaroteno | Alpha-carotene (µg) |
licopeno | Lycopene (µg) |
colina | Choline (mg) |
cafeina | Caffeine (mg) |
teobromina | Theobromine (mg) |
Amino acids (alanina, arginina, acidoAsp, cistina, acidoGlu, glicina, histidina, hidroxiprol, isoleucina, leucina, lisina, metionina, fenilalanina, prolina, serina, treonina, triptofano, tirosina, valina) — all in grams.
GET /api/recipes
Returns a paginated list of recipes. Reviews (resenas) are excluded from list results.
Query parameters
| Param | Type | Default | Description |
|---|
page | number | 1 | Page number |
limit | number | 10 | Results per page |
search | string | "" | Case-insensitive text search against nombre and desc |
cat | string | "" | Filter by category: desayuno, almuerzo, cena, postres-snacks |
salud | string | "" | Filter by health tag (exact match) |
Response 200
{
"success": true,
"recipes": [ ],
"pagination": {
"total": 84,
"page": 1,
"pages": 9
}
}
GET /api/recipes/:id
Returns the full recipe document including all resenas (reviews).
Path parameter
| Param | Description |
|---|
id | Recipe ObjectId |
Response 200
{
"success": true,
"recipe": { }
}
Error responses
| Status | Condition |
|---|
404 | Recipe not found |
POST /api/recipes
Requires Authorization: Bearer <token> with role: "admin"
Creates a new recipe. Fields resenas, puntosProm, and totalResenas are stripped from the request body if supplied — they are managed by the server.
Recipe name. Max 200 characters.
Description. Max 1000 characters.
Category. One of: desayuno, almuerzo, cena, postres-snacks.
Health/dietary tags, e.g. ["sin-gluten", "vegano"].
List of ingredient strings.
Step-by-step instruction strings.
Nutritional data object. All keys optional; unmapped keys default to 0. See nutritional schema for all fields.
Response 201
{
"success": true,
"message": "Receta creada correctamente",
"recipe": { }
}
Error responses
| Status | Condition |
|---|
403 | Caller is not an admin |
500 | Validation or save error |
PUT /api/recipes/:id
Requires Authorization: Bearer <token> with role: "admin"
Updates an existing recipe. Accepts the same body fields as POST /api/recipes. Fields resenas, puntosProm, and totalResenas are stripped.
Path parameter
| Param | Description |
|---|
id | Recipe ObjectId |
Response 200
{
"success": true,
"message": "Receta actualizada correctamente",
"recipe": { }
}
Error responses
| Status | Condition |
|---|
403 | Caller is not an admin |
404 | Recipe not found |
500 | Validation or save error |
DELETE /api/recipes/:id
Requires Authorization: Bearer <token> with role: "admin"
Deletes a recipe and removes any orphaned notifications linked to it.
Path parameter
| Param | Description |
|---|
id | Recipe ObjectId |
Response 200
{
"success": true,
"message": "Receta eliminada correctamente"
}
Error responses
| Status | Condition |
|---|
403 | Caller is not an admin |
404 | Recipe not found |
POST /api/recipes/import
Requires Authorization: Bearer <token> with role: "admin"
Bulk-imports an array of recipes. Pass mode: "replace" to delete all existing recipes before inserting.
Array of recipe objects. Each must include at minimum nombre, desc, and cat.
"replace" — delete all existing recipes first. Omit or any other value to append.
Response 200
{
"success": true,
"message": "12 recetas importadas",
"result": {
"created": 12
}
}
In replace mode result also contains "deleted": <count>.
Error responses
| Status | Condition |
|---|
400 | recipes is not an array |
400 | One or more recipes missing required fields — details array returned |
GET /api/recipes/export/all
Requires Authorization: Bearer <token> with role: "admin"
Exports all recipes as JSON (reviews excluded).
Response 200
{
"success": true,
"count": 84,
"recipes": [ ]
}
GET /api/recipes/stats/summary
Requires Authorization: Bearer <token> with role: "admin"
Returns aggregate statistics.
Response 200
{
"success": true,
"stats": {
"total": 84,
"byCategory": [
{ "_id": "almuerzo", "count": 30 },
{ "_id": "desayuno", "count": 22 }
],
"byHealth": [
{ "_id": "vegano", "count": 18 },
{ "_id": "sin-gluten", "count": 14 }
]
}
}
POST /api/recipes/delete-multiple
Requires Authorization: Bearer <token> with role: "admin"
Deletes several recipes by ID in a single request.
Array of recipe ObjectIds to delete. Must be a non-empty array.
Response 200
{
"success": true,
"message": "5 recetas eliminadas",
"deleted": 5
}
Error responses
| Status | Condition |
|---|
400 | ids is not a non-empty array |
GET /api/recipes/:id/resenas
Returns paginated reviews for a recipe. Calling without authentication returns reviews with miVoto: null.
Query parameters
| Param | Type | Default | Description |
|---|
page | number | 1 | Page number |
limit | number | 5 | Reviews per page |
orden | string | "reciente" | "reciente" (newest first) or "relevancia" (net-likes descending) |
Response 200
{
"success": true,
"puntosProm": 4.7,
"totalResenas": 23,
"resenas": [
{
"_id": "64c3b4d5e6f7a8b9c0d1e2f3",
"userId": "64a1f2c3d4e5f6a7b8c9d0e1",
"userName": "María García",
"estrellas": 5,
"texto": "¡Deliciosa y muy fácil de preparar!",
"createdAt": "2024-04-10T14:00:00.000Z",
"updatedAt": "2024-04-10T14:00:00.000Z",
"likes": 8,
"dislikes": 1,
"imagen": { "url": "https://res.cloudinary.com/...", "estado": "aprobada" },
"miVoto": "like",
"respuestas": [
{
"_id": "64d4c5d6e7f8a9b0c1d2e3f4",
"userId": "64a1f2c3d4e5f6a7b8c9d0e2",
"userName": "Chef Admin",
"texto": "Gracias por tu reseña!",
"createdAt": "2024-04-11T09:00:00.000Z"
}
]
}
],
"pagination": {
"total": 23,
"page": 1,
"pages": 5
}
}
Review images follow an approval flow. A pending image shows { url: null, estado: "pendiente" } only to the review’s author; it is invisible to other users until approved.
POST /api/recipes/:id/resenas
Requires Authorization: Bearer <token>
Creates a review for a recipe. One review per user per recipe. Accepts an optional image upload via multipart form; if an image is included, texto becomes required. Uploaded images start in estado: "pendiente" (moderation queue, ~3 days).
Request Content-Type: multipart/form-data
Review text. Max 500 characters. Required when an imagen file is attached.
Optional image attachment. Goes through approval flow.
Response 201
{
"success": true,
"message": "¡Reseña publicada!",
"puntosProm": 4.7,
"totalResenas": 24,
"resena": { }
}
Error responses
| Status | Condition |
|---|
400 | estrellas out of range 1–5 |
400 | Image attached but texto is empty |
400 | User already has a review on this recipe |
404 | Recipe not found |
PUT /api/recipes/:id/resenas
Requires Authorization: Bearer <token>
Edits the authenticated user’s existing review for a recipe.
Updated star rating (1–5).
Updated review text. Max 500 characters.
Response 200
{
"success": true,
"message": "Reseña actualizada",
"puntosProm": 4.6,
"totalResenas": 24,
"resena": { }
}
Error responses
| Status | Condition |
|---|
400 | estrellas out of range |
404 | Recipe or review not found |
DELETE /api/recipes/:id/resenas/:resenaId
Requires Authorization: Bearer <token>
Deletes a review. The authenticated user may only delete their own reviews; admins may delete any review. If the review has a Cloudinary image it is also deleted.
Path parameters
| Param | Description |
|---|
id | Recipe ObjectId |
resenaId | Review ObjectId |
Response 200
{
"success": true,
"message": "Reseña eliminada",
"puntosProm": 4.5,
"totalResenas": 23
}
Error responses
| Status | Condition |
|---|
403 | Caller is not the author or an admin |
404 | Recipe or review not found |
POST /api/recipes/:id/resenas/:resenaId/imagen
Requires Authorization: Bearer <token>
Uploads or replaces the image attached to the authenticated user’s existing review. The image enters the moderation queue with estado: "pendiente". An already-approved image (estado: "aprobada") cannot be replaced.
Request Content-Type: multipart/form-data
Path parameters
| Param | Description |
|---|
id | Recipe ObjectId |
resenaId | Review ObjectId |
| Field | Type | Description |
|---|
imagen | File | Image file to attach to the review |
Response 200
{
"success": true,
"message": "Imagen subida. Pendiente de aprobación (≈3 días).",
"imagen": { "url": null, "estado": "pendiente" }
}
Error responses
| Status | Condition |
|---|
400 | No file received |
400 | Review already has an approved image |
403 | Caller is not the review author |
404 | Recipe or review not found |
DELETE /api/recipes/:id/resenas/imagen
Requires Authorization: Bearer <token>
Removes the image from the authenticated user’s own review on a recipe. The image is deleted from Cloudinary and the imagen field is cleared.
Path parameter
| Param | Description |
|---|
id | Recipe ObjectId |
Response 200
{
"success": true,
"message": "Imagen eliminada correctamente"
}
Error responses
| Status | Condition |
|---|
400 | Review has no image to remove |
404 | Recipe not found or user has no review on it |
POST /api/recipes/:id/resenas/:resenaId/voto
Requires Authorization: Bearer <token>
Toggles a like or dislike on a review. Voting the same tipo again removes the vote. Switching tipo removes the previous vote and adds the new one.
Path parameters
| Param | Description |
|---|
id | Recipe ObjectId |
resenaId | Review ObjectId |
Response 200
{
"success": true,
"likes": 9,
"dislikes": 1,
"miVoto": "like"
}
miVoto is "like", "dislike", or null (vote removed).
Error responses
| Status | Condition |
|---|
400 | tipo is not "like" or "dislike" |
404 | Recipe or review not found |
POST /api/recipes/:id/resenas/:resenaId/respuestas
Requires Authorization: Bearer <token>
Adds a reply to a review. The original review’s author receives an in-app notification.
Path parameters
| Param | Description |
|---|
id | Recipe ObjectId |
resenaId | Review ObjectId |
Reply text. Max 500 characters.
Response 201
{
"success": true,
"respuesta": {
"_id": "64d4c5d6e7f8a9b0c1d2e3f4",
"userId": "64a1f2c3d4e5f6a7b8c9d0e1",
"userName": "María García",
"texto": "¡Muchas gracias!",
"createdAt": "2024-04-11T09:00:00.000Z"
}
}
Error responses
| Status | Condition |
|---|
400 | texto missing or empty |
404 | Recipe or review not found |
DELETE /api/recipes/:id/resenas/:resenaId/respuestas/:respId
Requires Authorization: Bearer <token>
Deletes a reply. Users may only delete their own replies; admins may delete any.
Path parameters
| Param | Description |
|---|
id | Recipe ObjectId |
resenaId | Review ObjectId |
respId | Reply ObjectId |
Response 200
{
"success": true,
"message": "Respuesta eliminada"
}
Error responses
| Status | Condition |
|---|
403 | Caller is not the reply author or an admin |
404 | Recipe, review, or reply not found |