Recetas
La Recipe API calcula datos de impacto ambiental para platos, comidas y menús completos. Cada receta devuelve valores de CO2, calificaciones nutricionales y si cumple los requisitos del Eaternity Award.
Para ejemplos completos de solicitud y respuesta, consultad los casos de uso Evaluación del impacto de recetas y Menús para mostrar el plan de menús y para los informes.
Visión general
Usad la Recipe API para:
- Calcular la huella de CO2 de platos individuales
- Procesar menús enteros en lote para el análisis ambiental
- Seguir la sostenibilidad de las recetas a lo largo del tiempo
- Obtener el Eaternity Award para recetas de bajo impacto
- Obtener calificaciones de calidad nutricional (escala A-E)
- Analizar la contribución ambiental de cada ingrediente
Unicidad del ID de receta
La API identifica una receta solo por su id. El kitchen-id y la date se guardan con la receta, pero no la convierten en una receta distinta.
Si enviáis una receta con un id que ya existe, la API sobrescribe la receta guardada, incluidos su kitchen-id y su date. La ración anterior desaparece entonces de esa cocina y de ese día.
La regla: usad un id nuevo cada vez que un plato se sirve en una cocina en un día.
Ejemplo 1: la cocina A y la cocina B sirven risotto de calabaza el 1 de abril. Enviad dos recetas con dos ids distintos, por ejemplo risotto-kitchen-a-2026-04-01 y risotto-kitchen-b-2026-04-01. Con un id compartido, la segunda solicitud movería el risotto a la cocina B, y la cocina A lo perdería en sus informes.
Ejemplo 2: la cocina A vuelve a servir el risotto el 2 de abril. Es una tercera receta con un tercer id, por ejemplo risotto-kitchen-a-2026-04-02. Reutilizar el id del 1 de abril movería la primera ración al 2 de abril, y el 1 de abril la perdería.
Una forma sencilla de obtener un id nuevo cada vez: combinad vuestro propio número de receta con la cocina y la fecha.
Las subrecetas son la excepción. Una subreceta, como una salsa, puede mantener el mismo id en todos los menús que la usan; ved Subrecetas. Para menús enviados por cocina y fecha, ved Menús para mostrar el plan de menús y para los informes.
Subrecetas
Las recetas pueden usar otras recetas como ingredientes mediante el campo de ingrediente type: "recipes". Así se componen los platos del menú de forma jerárquica a partir de subrecetas reutilizables.
Todas las recetas individuales pueden contener la misma subreceta (p. ej., risotto de calabaza) como ingrediente, con el mismo ID cada vez.
La desventaja de reutilizar el mismo ID para una subreceta es que no podréis cambiar su composición de forma individual sin afectar a todas las recetas que la usan. Usad IDs individuales para las subrecetas si necesitáis modificarlas por separado.
Las subrecetas se envían como transitorias: solo cuentan a través del menú que las usa. Ved Recetas transitorias.
Parámetros de consulta
Todos los endpoints de recetas aceptan los parámetros de consulta full-resource, indicators, nutrient-values, ingredients-declaration, return-uids y transient. Valores y valores por defecto: Parámetros de consulta. Para transient, ved también Recetas transitorias.
Ejemplos
# Get recipe with all indicators
curl "https://co2.eaternity.ch/api/kitchens/{kitchen_id}/recipes/{recipe_id}?indicators=true" \
-u YOUR_API_KEY:
# Preview: calculate a recipe without keeping it (transient)
curl -X POST "https://co2.eaternity.ch/api/kitchens/{kitchen_id}/recipes?transient=true" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{"recipe": {"titles": [{"language": "en", "value": "Test"}], "date": "2024-12-16", "ingredients": [...]}}'
# Get full response with internal UIDs
curl "https://co2.eaternity.ch/api/kitchens/{kitchen_id}/recipes/{recipe_id}?full-resource=true&return-uids=true" \
-u YOUR_API_KEY:
Parámetros específicos de lote
El endpoint /recipes/batch admite parámetros adicionales:
| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
priority | integer | 1 | Prioridad de cálculo: 0 (baja) o 1 (alta, se procesa primero). Usad 0 para trabajos en segundo plano. |
Cabeceras de la solicitud
| Cabecera | Obligatoria | Descripción |
|---|---|---|
Content-Type | Sí | Debe ser application/json |
Authorization | Sí | Basic Auth con la clave de API |
Propiedades de la receta
Los campos de cada línea de ingredients están en su propia página: Ingredientes.
Esquema de la solicitud
{
"recipe": {
"kitchen-id": "kitchen-restaurant-a",
"id": "recipe-001",
"titles": [{"language": "en", "value": "Grilled Salmon with Vegetables"}, {"language": "de", "value": "Gegrillter Lachs mit Gemüse"}],
"recipe-portions": 4,
"date": "2024-12-16",
"weight": 350,
"ingredients": [
{
"id": "salmon-filet",
"names": [{"language": "en", "value": "Salmon (farmed, fillet)"}],
"amount": 600,
"unit": "gram",
"origin": "Norway",
"transport": "air",
"production": "standard",
"conservation": "fresh",
"packaging": "plastic"
}
]
}
}
Respuesta:
{
"statuscode": 200,
"message": "",
"request-id": 0,
"recipe-id": "recipe-001",
"recipe": {
"food-unit": 1.06,
"final-weight-per-portion": 350.0,
"eaternity-award": false,
"co2-value": 743,
"rating": "B",
"co2-value-improvement-percentage": 10,
"co2-value-reduction-value": 81,
"id": "recipe-001",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "Grilled Salmon with Vegetables"}, {"language": "de", "value": "Gegrillter Lachs mit Gemüse"}],
"date": "2024-12-16",
"weight": 350.0,
"servings": 4,
"recipe-portions": 4,
"ingredients": []
}
}
Definiciones de las propiedades
Propiedades de la solicitud
| Propiedad | Tipo | Obligatoria | Descripción |
|---|---|---|---|
kitchen-id | String | Sí | El ID de la cocina a la que pertenece la receta |
id | String | Sí | Identificador único de la receta. Ved Unicidad del ID de receta para las reglas. |
titles | Array | Sí | Títulos de la receta como array de objetos de idioma: [{"language": "en", "value": "..."}] |
recipe-portions | Float | No | Número de raciones para las que se indican los ingredientes. Por defecto 1. |
date | ISO Date | Buena práctica | La fecha en que se sirve la receta (formato: yyyy-mm-dd). |
ingredients | Array | Sí | Lista de objetos de ingrediente (mínimo 1). Ved Ingredientes. |
weight | Integer | No | Peso final de la receta por ración en gramos. Se usa para tener en cuenta la evaporación y las pérdidas de cocción. Si no se indica, se usa la suma de los pesos de los ingredientes. Para modelar la pérdida de alimentos de ingredientes individuales, usad preferentemente el campo por ingrediente loss-in-percent-of-amount. |
author | String | No | Autor original de la receta |
location | String | No | Lugar donde se cocina la receta. Dirección o país (formato libre). Si falta, se usa la ubicación de la cocina. |
production-portions | Float | No | Cuántas raciones de la receta se planea producir |
sold-portions | Float | No | Cuántas raciones se vendieron (consumieron) realmente. El endpoint de forecast lo usa para predecir las ventas. |
instructions | Array | No | Instrucciones de cocción como array de objetos de idioma: [{"language": "en", "value": "..."}] |
menu-line-name | String | No | Nombre de la línea de menú (p. ej., "Fitness", "Garden Menu", "Vegan Menu") |
menu-line-id | Integer | No | Identificador numérico de la línea de menú |
transient | Boolean | No | Campo del elemento del lote, junto a request-id. true hace que la receta sea transitoria: se calcula y se devuelve, pero no se guarda ni cuenta por sí sola. |
Una receta sin date se calcula, pero falta en los informes basados en fechas. Incluid siempre la fecha en que se sirve la receta.
Propiedades de la respuesta
| Propiedad | Tipo | Descripción |
|---|---|---|
co2-value | Integer | Emisiones totales de CO2 de toda la receta por ración (gramos de CO2-eq) |
co2-value-improvement-percentage | Float | Comparación de la huella de CO2 de esta receta por unidad alimentaria con la media |
co2-value-reduction-value | Float | Gramos de CO2 ahorrados al servir esta receta en lugar de una receta media que aporte el mismo valor nutricional |
rating | String | Calificación ambiental (escala A-E, A es la mejor) |
eaternity-award | Boolean | true si la receta es respetuosa con el clima |
info-text | String | Notas sobre el valor de CO2 calculado, p. ej., observaciones cuando se estiman propiedades como el origen o el transporte |
final-weight-per-portion | Float | Peso final por ración después de la cocción (gramos) |
indicators.vita-score | Object | Calificación de calidad nutricional (A-E) y sus factores de riesgo (solo con indicators=true). Ved Vita Score. |
indicators | Object | Indicadores ambientales y nutricionales (solo con el parámetro indicators=true) |
nutrient-values-estimated-per-recipe-portion | Object | Valores de nutrientes agregados por ración, calculados sumando los nutrientes de todos los ingredientes y dividiendo por recipe-portions (con el parámetro nutrient-values=true) |
Recetas transitorias
transientUna receta transitoria se calcula y su resultado vuelve en la respuesta. Después no se guarda:
- Nunca cuenta por sí sola en los informes, ni siquiera con una
date. Sus ingredientes solo cuentan a través del menú que la usa. - No se puede recuperar más tarde. Un
GETresponde404, y no aparece en la lista de recetas de la cocina. - Un menú puede usarla como subreceta.
Dónde indicarlo
| Dónde | Se aplica a |
|---|---|
Campo del cuerpo "transient": true en un elemento del lote, junto a request-id | Esa receta |
Parámetro de consulta ?transient=true | Todas las recetas de la solicitud, incluidos los menús |
Poned el campo del cuerpo en el elemento del lote, no dentro de recipe. Dentro de recipe se ignora y la receta se guarda como una receta normal.
?transient=true en un lote de menús hace que también los menús sean transitorios, de modo que desaparecen de los informes. Para las subrecetas, usad el campo del cuerpo.
Cuándo usarlo
- Subrecetas como una salsa, una guarnición o una base: transitorias.
- Vistas previas y pruebas:
?transient=true. - Menús que deben contar en los informes: no transitorios.
Operaciones por lotes
Procesad varias recetas en una sola solicitud para un rendimiento óptimo.
Solicitud
POST /recipes/batch
Content-Type: application/json
Authorization: Basic {api_key}
Seguimiento con request ID
Cada receta de un lote puede incluir un campo entero request-id para ayudaros a localizar las recetas en la respuesta. Es especialmente útil cuando no usáis vuestros propios IDs de receta.
- Cada entrada necesita un
request-ido unidde receta - El
request-ides distinto delidde la receta y solo existe durante una única solicitud (no se guarda en el servidor)
Ejemplo de composición con subrecetas
En la siguiente solicitud, un plato del menú "Fitness Risotto" contiene una sola receta "Mushroom gravy on pumpkin risotto". Esta receta se compone a su vez de dos subrecetas: "pumpkin risotto" y "Mushroom gravy". Todas las recetas van incluidas en el lote.
El plato del menú no es transitorio ("transient": false), así que cuenta en los informes. Las subrecetas son transitorias ("transient": true): se calculan con el menú y solo cuentan a través de él. El indicador va en cada elemento del lote, junto a request-id.
[
{
"request-id": 0,
"transient": true,
"recipe": {
"id": "internal-recipe-id3",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "Mushroom gravy on pumpkin risotto"}],
"recipe-portions": 1,
"ingredients": [
{
"id": "internal-recipe-id1",
"type": "recipes",
"amount": 250,
"unit": "gram"
},
{
"id": "internal-recipe-id2",
"type": "recipes",
"amount": 50,
"unit": "gram"
}
]
}
},
{
"request-id": 1,
"transient": true,
"recipe": {
"id": "internal-recipe-id1",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "pumpkin risotto"}],
"recipe-portions": 100,
"ingredients": [
{
"id": "101",
"type": "conceptual-ingredients",
"names": [{"language": "en", "value": "Pumpkin"}],
"amount": 5000,
"unit": "gram",
"origin": "Italy",
"transport": "ground",
"conservation": "dried"
}
]
}
},
{
"request-id": 2,
"transient": true,
"recipe": {
"id": "internal-recipe-id2",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "Mushroom gravy"}],
"recipe-portions": 5,
"ingredients": [
{
"id": "104",
"type": "conceptual-ingredients",
"names": [{"language": "en", "value": "onions"}],
"amount": 78,
"unit": "gram"
}
]
}
},
{
"request-id": 3,
"transient": false,
"recipe": {
"id": "menu-id1-fitness-2016-11-28",
"kitchen-id": "kitchen-restaurant-a",
"menu-line-name": "Fitness",
"menu-line-id": 1,
"titles": [{"language": "en", "value": "Fitness Risotto"}],
"recipe-portions": 1,
"date": "2016-11-28",
"ingredients": [
{
"id": "internal-recipe-id3",
"type": "recipes",
"amount": 288,
"unit": "gram"
}
]
}
}
]
Respuesta, una entrada por receta en el orden de la solicitud:
[
{
"statuscode": 200,
"message": "",
"recipe-id": "internal-recipe-id3",
"request-id": 0,
"recipe": {
"food-unit": 1.36,
"final-weight-per-portion": 300.0,
"eaternity-award": false,
"co2-value": 2030,
"rating": "C",
"co2-value-improvement-percentage": -91,
"co2-value-reduction-value": -969,
"id": "internal-recipe-id3",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "Mushroom gravy on pumpkin risotto"}],
"servings": 1,
"recipe-portions": 1,
"ingredients": []
}
},
{
"statuscode": 200,
"message": "",
"recipe-id": "internal-recipe-id1",
"request-id": 1,
"recipe": {
"food-unit": 0.26,
"final-weight-per-portion": 50.0,
"eaternity-award": false,
"co2-value": 404,
"rating": "C",
"co2-value-improvement-percentage": -98,
"co2-value-reduction-value": -200,
"id": "internal-recipe-id1",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "pumpkin risotto"}],
"servings": 100,
"recipe-portions": 100,
"ingredients": []
}
},
{
"statuscode": 200,
"message": "",
"recipe-id": "internal-recipe-id2",
"request-id": 2,
"recipe": {
"food-unit": 0.02,
"final-weight-per-portion": 15.600000000000001,
"eaternity-award": true,
"co2-value": 3,
"rating": "A",
"co2-value-improvement-percentage": 74,
"co2-value-reduction-value": 9,
"id": "internal-recipe-id2",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "Mushroom gravy"}],
"servings": 5,
"recipe-portions": 5,
"ingredients": []
}
},
{
"statuscode": 200,
"message": "",
"recipe-id": "menu-id1-fitness-2016-11-28",
"request-id": 3,
"recipe": {
"food-unit": 1.31,
"final-weight-per-portion": 288.0,
"eaternity-award": false,
"co2-value": 1949,
"rating": "C",
"co2-value-improvement-percentage": -91,
"co2-value-reduction-value": -931,
"id": "menu-id1-fitness-2016-11-28",
"kitchen-id": "kitchen-restaurant-a",
"titles": [{"language": "en", "value": "Fitness Risotto"}],
"date": "2016-11-28",
"servings": 1,
"recipe-portions": 1,
"ingredients": [],
"menu-line-name": "Fitness",
"menu-line-id": 1
}
}
]
Eaternity Award
El Eaternity Award es una etiqueta para comidas respetuosas con el clima. Una receta recibe el Eaternity Award cuando obtiene una calificación de CO2 "A".
El campo eaternity-award es un booleano que se devuelve junto con la calificación de CO2:
true— la comida es respetuosa con el clima (equivale a una calificación de CO2 "A")false— la comida no cumple los requisitos
Sistema de calificación
Las recetas reciben una calificación ambiental de A (la mejor) a E (la peor). Umbrales: Escala de calificación.
Ingredientes
Cada línea de una receta es un objeto de ingrediente. Campos, valores permitidos, tipos y matching: Ingredientes.
Endpoints
📄️ Create or update a batch of recipes
Batch operations allow you to create, update or delete multiple recipes at once.
📄️ Delete a batch of recipes
Delete multiple recipes at once by providing a list of recipe IDs.
📄️ Create a recipe
Create a new recipe without specifying an ID (ID will be generated).
📄️ Get a recipe
Retrieve a recipe by its ID with calculated CO₂ values and indicators.
📄️ Update or create a recipe
Update an existing recipe or create a new one with the specified ID.
📄️ Delete a recipe
Delete a recipe by its ID.
📄️ Create a recipe in a kitchen
Create a new recipe associated with a specific kitchen.
📄️ Get all recipes in a kitchen
Returns a list of recipe IDs contained in this kitchen.
📄️ Get a recipe from a kitchen
Retrieve a specific recipe from a kitchen.
📄️ Create or update a recipe in a kitchen
Update or create a recipe with the specified ID in a specific kitchen.
📄️ Delete a recipe from a kitchen
Delete a specific recipe from a kitchen.