API Calculadora Mediterránea + EAT
Cálculo de calorías, EAT score, huella de carbono y MEDAS, y recomendaciones de compra. Autenticación: Authorization: Bearer <JWT del participante> o x-api-key para socios.
Base: /api/public · Especificación: openapi.json
post
/v1/calculateCalcular sin guardar (scope: calculate)get
/v1/assessments/{id}/resultsResultados guardados (scope: results:read)get
/v1/assessments/{id}/recommendationsPrioridades y estado por grupo (scope: recommendations:read)post
/v1/shopping-listsCrear lista de compras (scope: shopping:write)post
/v1/purchases/analyzeAnalizar una compra (scope: purchases:analyze)get
/v1/catalog/productsCatálogo de productos (público, CORS abierto)get
/v1/openapi.jsonEsta especificaciónVer JSON completo
{
"openapi": "3.1.0",
"info": {
"title": "API Calculadora Mediterránea + EAT",
"version": "1.0.0",
"description": "Cálculo de calorías, EAT score, huella de carbono y MEDAS, y recomendaciones de compra. Autenticación: Authorization: Bearer <JWT del participante> o x-api-key para socios."
},
"servers": [
{
"url": "/api/public"
}
],
"components": {
"securitySchemes": {
"bearer": {
"type": "http",
"scheme": "bearer"
},
"apiKey": {
"type": "apiKey",
"in": "header",
"name": "x-api-key"
}
},
"schemas": {
"Error": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
}
},
"PurchaseLine": {
"type": "object",
"required": [
"description",
"quantity"
],
"properties": {
"sku": {
"type": "string"
},
"description": {
"type": "string"
},
"quantity": {
"type": "number"
},
"unit_g": {
"type": "number"
},
"price_crc": {
"type": "number"
}
}
}
}
},
"security": [
{
"bearer": []
},
{
"apiKey": []
}
],
"paths": {
"/v1/calculate": {
"post": {
"summary": "Calcular sin guardar (scope: calculate)",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"per_day"
],
"properties": {
"per_day": {
"type": "object",
"additionalProperties": {
"type": "number"
},
"description": "Veces por día por código de alimento"
},
"cd_azucar": {
"type": "number",
"description": "Cucharaditas de azúcar al día"
},
"fat_type_code": {
"type": [
"integer",
"null"
],
"minimum": 0,
"maximum": 7
},
"medas": {
"type": "object",
"additionalProperties": {
"type": "number"
},
"description": "Respuestas MEDAS 1–14"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Variables con nombres SAS"
},
"400": {
"description": "Cuerpo inválido"
},
"401": {
"description": "No autenticado"
}
}
}
},
"/v1/assessments/{id}/results": {
"get": {
"summary": "Resultados guardados (scope: results:read)",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Resultado"
},
"404": {
"description": "Sin resultados"
}
}
}
},
"/v1/assessments/{id}/recommendations": {
"get": {
"summary": "Prioridades y estado por grupo (scope: recommendations:read)",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Prioridades"
}
}
}
},
"/v1/shopping-lists": {
"post": {
"summary": "Crear lista de compras (scope: shopping:write)",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"assessment_id",
"persons",
"days"
],
"properties": {
"assessment_id": {
"type": "string",
"format": "uuid"
},
"persons": {
"type": "integer"
},
"days": {
"type": "integer"
},
"budget_crc": {
"type": [
"number",
"null"
]
},
"retailer_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"mode": {
"type": "string",
"enum": [
"una_tienda",
"mejor_precio",
"tienda_preferida"
],
"description": "una_tienda: cadena con menor total; mejor_precio: lo más barato por gramo en cualquier cadena; tienda_preferida: usa retailer_id"
}
}
}
}
}
},
"responses": {
"201": {
"description": "Lista con productos (cadena y enlace), total por tienda, ahorro frente a la más cara y fecha de los precios"
}
}
}
},
"/v1/purchases/analyze": {
"post": {
"summary": "Analizar una compra (scope: purchases:analyze)",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"lines"
],
"properties": {
"retailer_id": {
"type": [
"string",
"null"
]
},
"lines": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PurchaseLine"
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "Puntaje mediterráneo de la compra, reparto por grupo y sustituciones"
}
}
}
},
"/v1/catalog/products": {
"get": {
"summary": "Catálogo de productos (público, CORS abierto)",
"security": [],
"parameters": [
{
"name": "rec_group",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "retailer_id",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Productos"
}
}
}
},
"/v1/openapi.json": {
"get": {
"summary": "Esta especificación",
"security": [],
"responses": {
"200": {
"description": "OpenAPI 3.1"
}
}
}
}
}
}