Recettes
La Recipe API calcule l'empreinte environnementale de plats, de repas et de menus complets. Chaque recette renvoie des valeurs de CO2, des notations nutritionnelles et l'éligibilité à l'Eaternity Award.
Pour des exemples complets de request et de response, voir les use cases Évaluation de l'empreinte d'une recette et Menus pour l'affichage du plan de menus et les rapports.
Aperçu
Utilisez la Recipe API pour :
- Calculer l'empreinte CO2 de plats individuels
- Traiter des menus entiers par lot pour une analyse environnementale
- Suivre la durabilité des recettes dans le temps
- Obtenir l'Eaternity Award pour les recettes à faible empreinte
- Obtenir des notations de qualité nutritionnelle (échelle A-E)
- Analyser la contribution environnementale de chaque ingrédient
Unicité de l'ID de recette
L'API identifie une recette uniquement par son id. Le kitchen-id et la date sont enregistrés avec la recette, mais ils n'en font pas une autre recette.
Si vous envoyez une recette avec un id qui existe déjà, l'API écrase la recette enregistrée, y compris son kitchen-id et sa date. Le service précédent disparaît alors de cette cuisine et de ce jour.
La règle : utilisez un nouvel id chaque fois qu'un plat est servi dans une cuisine un jour donné.
Exemple 1 : la cuisine A et la cuisine B servent toutes deux un risotto au potiron le 1er avril. Envoyez deux recettes avec deux ids différents, par exemple risotto-kitchen-a-2026-04-01 et risotto-kitchen-b-2026-04-01. Avec un id commun, la deuxième request déplacerait le risotto vers la cuisine B, et la cuisine A le perdrait dans ses rapports.
Exemple 2 : la cuisine A sert de nouveau le risotto le 2 avril. C'est une troisième recette avec un troisième id, par exemple risotto-kitchen-a-2026-04-02. Réutiliser l'id du 1er avril déplacerait le premier service au 2 avril, et le 1er avril le perdrait.
Une manière simple d'obtenir un nouvel id à chaque fois : combinez votre propre numéro de recette avec la cuisine et la date.
Les sous-recettes font exception. Une sous-recette comme une sauce peut garder le même id dans chaque menu qui l'utilise ; voir Sous-recettes. Pour les menus envoyés par cuisine et par date, voir Menus pour l'affichage du plan de menus et les rapports.
Sous-recettes
Une recette peut utiliser d'autres recettes comme ingrédients grâce au champ d'ingrédient type: "recipes". Cela permet de composer des plats du menu de manière hiérarchique à partir de sous-recettes réutilisables.
Toutes les recettes individuelles peuvent contenir la même sous-recette (par exemple un risotto au potiron) comme ingrédient, avec le même ID à chaque fois.
L'inconvénient de réutiliser le même ID pour une sous-recette : vous ne pouvez pas modifier sa composition individuellement sans affecter toutes les recettes qui y font référence. Utilisez des IDs individuels pour les sous-recettes si vous devez les modifier indépendamment.
Les sous-recettes sont envoyées comme transitoires : elles comptent uniquement à travers le menu qui les utilise. Voir Recettes transitoires.
Paramètres de requête
Tous les endpoints de recettes acceptent les paramètres de requête full-resource, indicators, nutrient-values, ingredients-declaration, return-uids et transient. Valeurs et valeurs par défaut : Paramètres de requête. Pour transient, voir aussi Recettes transitoires.
Exemples
# 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:
Paramètres propres au lot
L'endpoint /recipes/batch accepte des paramètres supplémentaires :
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
priority | integer | 1 | Priorité de calcul : 0 (basse) ou 1 (haute, traitée en premier). Utilisez 0 pour les tâches en arrière-plan. |
En-têtes de requête
| En-tête | Obligatoire | Description |
|---|---|---|
Content-Type | Oui | Doit être application/json |
Authorization | Oui | Basic Auth avec la clé API |
Propriétés de la recette
Les champs de chaque ligne de ingredients sont décrits sur une page dédiée : Ingrédients.
Schéma de la request
{
"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"
}
]
}
}
Response :
{
"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": []
}
}
Définition des propriétés
Propriétés de la request
| Propriété | Type | Obligatoire | Description |
|---|---|---|---|
kitchen-id | String | Oui | ID de la cuisine à laquelle appartient la recette |
id | String | Oui | Identifiant unique de la recette. Règles : Unicité de l'ID de recette. |
titles | Array | Oui | Titres de la recette, sous forme de tableau d'objets de langue : [{"language": "en", "value": "..."}] |
recipe-portions | Float | Non | Nombre de portions pour lesquelles les ingrédients sont indiqués. Par défaut 1. |
date | ISO Date | Bonne pratique | Date à laquelle la recette est servie (format : yyyy-mm-dd). |
ingredients | Array | Oui | Liste d'objets ingrédient (au moins 1). Voir Ingrédients. |
weight | Integer | Non | Poids final de la recette par portion, en grammes. Sert à tenir compte de l'évaporation et des pertes à la cuisson. S'il n'est pas fourni, il correspond par défaut à la somme des poids des ingrédients. Pour modéliser la perte d'ingrédients individuels, utilisez plutôt le champ par ingrédient loss-in-percent-of-amount. |
author | String | Non | Auteur original de la recette |
location | String | Non | Lieu où la recette est cuisinée. Adresse ou pays (format libre). À défaut, la localisation de la cuisine est utilisée. |
production-portions | Float | Non | Nombre de portions de la recette dont la production est prévue |
sold-portions | Float | Non | Nombre de portions effectivement vendues (consommées). Utilisé par l'endpoint Forecast pour prévoir les ventes. |
instructions | Array | Non | Instructions de préparation, sous forme de tableau d'objets de langue : [{"language": "en", "value": "..."}] |
menu-line-name | String | Non | Désignation de la ligne de menu (par exemple « Fitness », « Garden Menu », « Vegan Menu ») |
menu-line-id | Integer | Non | Identifiant numérique de la ligne de menu |
transient | Boolean | Non | Champ de l'élément du lot, à côté de request-id. true rend la recette transitoire : calculée et renvoyée, non conservée, non comptée seule. |
Une recette sans date est calculée, mais elle manque dans les rapports basés sur la date. Indiquez toujours la date à laquelle la recette est servie.
Propriétés de la response
| Propriété | Type | Description |
|---|---|---|
co2-value | Integer | Émissions totales de CO2 de la recette entière par portion (grammes CO2-eq) |
co2-value-improvement-percentage | Float | Comparaison de l'empreinte CO2 de cette recette par food unit avec la moyenne |
co2-value-reduction-value | Float | Grammes de CO2 économisés en servant cette recette au lieu d'une recette moyenne de même valeur nutritionnelle |
rating | String | Notation environnementale (échelle A-E, A est la meilleure) |
eaternity-award | Boolean | true si la recette est respectueuse du climat |
info-text | String | Remarques sur la valeur de CO2 calculée, par exemple lorsque des propriétés comme l'origine ou le transport sont estimées |
final-weight-per-portion | Float | Poids final par portion après cuisson (grammes) |
indicators.vita-score | Object | Notation de la qualité nutritionnelle (A-E) et ses facteurs de risque (uniquement avec indicators=true). Voir Vita Score. |
indicators | Object | Indicateurs environnementaux et nutritionnels (uniquement avec le paramètre indicators=true) |
nutrient-values-estimated-per-recipe-portion | Object | Valeurs nutritionnelles agrégées par portion : somme des nutriments de tous les ingrédients divisée par recipe-portions (avec le paramètre nutrient-values=true) |
Recettes transitoires
transientUne recette transitoire est calculée, et son résultat est renvoyé dans la response. Ensuite, elle n'est pas conservée :
- Elle ne compte jamais seule dans les rapports, même avec une
date. Ses ingrédients comptent uniquement à travers le menu qui l'utilise. - Elle ne peut pas être récupérée plus tard. Un
GETrépond404, et elle n'apparaît pas dans la liste des recettes de la cuisine. - Un menu peut l'utiliser comme sous-recette.
Où l'activer
| Où | S'applique à |
|---|---|
Champ du body "transient": true sur un élément du lot, à côté de request-id | Cette seule recette |
Paramètre de requête ?transient=true | Toutes les recettes de la request, menus compris |
Placez le champ du body sur l'élément du lot, pas dans recipe. Dans recipe, il est ignoré et la recette est enregistrée comme une recette normale.
?transient=true sur un lot de menus rend aussi les menus transitoires : ils disparaissent alors des rapports. Pour les sous-recettes, utilisez le champ du body.
Quand l'utiliser
- Sous-recettes comme une sauce, un accompagnement ou une base : transitoires.
- Aperçus et tests :
?transient=true. - Menus qui doivent compter dans les rapports : non transitoires.
Opérations par lot
Traitez plusieurs recettes en une seule request pour de meilleures performances.
Request
POST /recipes/batch
Content-Type: application/json
Authorization: Basic {api_key}
Suivi par request-id
Chaque recette d'un lot peut inclure un champ entier request-id pour vous aider à retrouver les recettes dans la response. C'est particulièrement utile si vous n'utilisez pas vos propres IDs de recette.
- Chaque entrée nécessite soit un
request-id, soit unidde recette - Le
request-idest différent de l'idde la recette et ne vit que le temps d'une seule request (il n'est pas enregistré sur le serveur)
Exemple de composition avec sous-recettes
Dans la request suivante, un plat du menu « Fitness Risotto » contient une seule recette « Mushroom gravy on pumpkin risotto ». Cette recette se compose à son tour de deux sous-recettes : « pumpkin risotto » et « Mushroom gravy ». Toutes les recettes sont incluses dans le lot.
Le plat du menu n'est pas transitoire ("transient": false) : il compte donc dans les rapports. Les sous-recettes sont transitoires ("transient": true) : elles sont calculées avec le menu et comptent uniquement à travers lui. Le flag se trouve sur chaque élément du lot, à côté de 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"
}
]
}
}
]
Response, une entrée par recette dans l'ordre de la request :
[
{
"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
L'Eaternity Award est un label pour les repas respectueux du climat. Une recette obtient l'Eaternity Award lorsqu'elle atteint une notation CO2 « A ».
Le champ eaternity-award est un booléen renvoyé avec la notation CO2 :
true— le repas est respectueux du climat (équivaut à une notation CO2 « A »)false— le repas ne remplit pas les conditions
Système de notation
Les recettes reçoivent une notation environnementale de A (la meilleure) à E (la moins bonne). Seuils : Échelle de notation.
Ingrédients
Chaque ligne d'une recette est un objet ingrédient. Champs, valeurs autorisées, types et correspondance : Ingrédients.
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.