Skip to main content

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

FieldTypeDescription
_idstringMongoDB ObjectId
nombrestringRecipe name. Max 200 chars.
descstringDescription. Max 1000 chars.
imgstringCover image URL
catstringOne of desayuno, almuerzo, cena, postres-snacks
saludstring[]Health/dietary tags (free-form strings)
ingredientesstring[]Ingredient list
pasosstring[]Step-by-step instructions
nutriobjectNutritional data (see below)
puntosPromnumberAverage star rating (0–5, one decimal place)
totalResenasnumberTotal review count
createdBystringObjectId of the admin who created the recipe
createdAtstringISO 8601 timestamp
updatedAtstringISO 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
KeyDescription
calCalories (kcal)
carbTotal carbohydrates (g)
carbNetosNet carbs (g)
grasTotal fat (g)
protProtein (g)
fiberDietary fiber (g)
Fats breakdown
KeyDescription
grasSatSaturated fat (g)
grasMonoinsMonounsaturated fat (g)
grasPoliinsPolyunsaturated fat (g)
grasTransTrans fat (g)
omega3Omega-3 (g)
omega6Omega-6 (g)
alaAlpha-linolenic acid (g)
dhaDHA (g)
epaEPA (g)
dpaDPA (g)
Sugars breakdown
KeyDescription
azucarTotal sugars (g)
sacarosaSucrose (g)
glucosaGlucose (g)
fructosaFructose (g)
lactosaLactose (g)
maltosaMaltose (g)
galactosaGalactose (g)
almidonStarch (g)
Minerals
KeyDescription
sodioSodium (mg)
colesterolCholesterol (mg)
calcioCalcium (mg)
hierroIron (mg)
potasioPotassium (mg)
magnesioMagnesium (mg)
fosforoPhosphorus (mg)
zincZinc (mg)
selenioSelenium (µg)
cobreCopper (mg)
manganesoManganese (mg)
fluorFluoride (mg)
Vitamins
KeyDescription
vitCVitamin C (mg)
vitAVitamin A (µg RAE)
vitAuiVitamin A (IU)
vitDVitamin D (µg)
vitDuiVitamin D (IU)
vitD2Vitamin D2 (µg)
vitD3Vitamin D3 (µg)
vitEVitamin E (mg)
vitKVitamin K (µg)
vitB6Vitamin B6 (mg)
vitB12Vitamin B12 (µg)
niacinaNiacin / B3 (mg)
riboflavinaRiboflavin / B2 (mg)
tiaminaThiamine / B1 (mg)
folatoFolate (µg DFE)
acidoPantPantothenic acid / B5 (mg)
retinolRetinol (µg)
betaCarotenoBeta-carotene (µg)
alfaCarotenoAlpha-carotene (µg)
licopenoLycopene (µg)
colinaCholine (mg)
cafeinaCaffeine (mg)
teobrominaTheobromine (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
ParamTypeDefaultDescription
pagenumber1Page number
limitnumber10Results per page
searchstring""Case-insensitive text search against nombre and desc
catstring""Filter by category: desayuno, almuerzo, cena, postres-snacks
saludstring""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
ParamDescription
idRecipe ObjectId
Response 200
{
  "success": true,
  "recipe": { }
}
Error responses
StatusCondition
404Recipe 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.
nombre
string
required
Recipe name. Max 200 characters.
desc
string
required
Description. Max 1000 characters.
cat
string
required
Category. One of: desayuno, almuerzo, cena, postres-snacks.
img
string
Cover image URL.
salud
string[]
Health/dietary tags, e.g. ["sin-gluten", "vegano"].
ingredientes
string[]
List of ingredient strings.
pasos
string[]
Step-by-step instruction strings.
nutri
object
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
StatusCondition
403Caller is not an admin
500Validation 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
ParamDescription
idRecipe ObjectId
Response 200
{
  "success": true,
  "message": "Receta actualizada correctamente",
  "recipe": { }
}
Error responses
StatusCondition
403Caller is not an admin
404Recipe not found
500Validation 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
ParamDescription
idRecipe ObjectId
Response 200
{
  "success": true,
  "message": "Receta eliminada correctamente"
}
Error responses
StatusCondition
403Caller is not an admin
404Recipe 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.
recipes
object[]
required
Array of recipe objects. Each must include at minimum nombre, desc, and cat.
mode
string
"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
StatusCondition
400recipes is not an array
400One 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.
ids
string[]
required
Array of recipe ObjectIds to delete. Must be a non-empty array.
Response 200
{
  "success": true,
  "message": "5 recetas eliminadas",
  "deleted": 5
}
Error responses
StatusCondition
400ids 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
ParamTypeDefaultDescription
pagenumber1Page number
limitnumber5Reviews per page
ordenstring"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
estrellas
number
required
Star rating from 1 to 5.
texto
string
Review text. Max 500 characters. Required when an imagen file is attached.
imagen
File
Optional image attachment. Goes through approval flow.
Response 201
{
  "success": true,
  "message": "¡Reseña publicada!",
  "puntosProm": 4.7,
  "totalResenas": 24,
  "resena": { }
}
Error responses
StatusCondition
400estrellas out of range 1–5
400Image attached but texto is empty
400User already has a review on this recipe
404Recipe not found

PUT /api/recipes/:id/resenas

Requires Authorization: Bearer <token>
Edits the authenticated user’s existing review for a recipe.
estrellas
number
required
Updated star rating (1–5).
texto
string
Updated review text. Max 500 characters.
Response 200
{
  "success": true,
  "message": "Reseña actualizada",
  "puntosProm": 4.6,
  "totalResenas": 24,
  "resena": { }
}
Error responses
StatusCondition
400estrellas out of range
404Recipe 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
ParamDescription
idRecipe ObjectId
resenaIdReview ObjectId
Response 200
{
  "success": true,
  "message": "Reseña eliminada",
  "puntosProm": 4.5,
  "totalResenas": 23
}
Error responses
StatusCondition
403Caller is not the author or an admin
404Recipe 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
ParamDescription
idRecipe ObjectId
resenaIdReview ObjectId
FieldTypeDescription
imagenFileImage 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
StatusCondition
400No file received
400Review already has an approved image
403Caller is not the review author
404Recipe 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
ParamDescription
idRecipe ObjectId
Response 200
{
  "success": true,
  "message": "Imagen eliminada correctamente"
}
Error responses
StatusCondition
400Review has no image to remove
404Recipe 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
ParamDescription
idRecipe ObjectId
resenaIdReview ObjectId
tipo
string
required
"like" or "dislike".
Response 200
{
  "success": true,
  "likes": 9,
  "dislikes": 1,
  "miVoto": "like"
}
miVoto is "like", "dislike", or null (vote removed). Error responses
StatusCondition
400tipo is not "like" or "dislike"
404Recipe 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
ParamDescription
idRecipe ObjectId
resenaIdReview ObjectId
texto
string
required
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
StatusCondition
400texto missing or empty
404Recipe 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
ParamDescription
idRecipe ObjectId
resenaIdReview ObjectId
respIdReply ObjectId
Response 200
{
  "success": true,
  "message": "Respuesta eliminada"
}
Error responses
StatusCondition
403Caller is not the reply author or an admin
404Recipe, review, or reply not found

Build docs developers (and LLMs) love