Rezepte
Die Recipe API berechnet Umweltdaten für Gerichte, Mahlzeiten und ganze Menüs. Für jedes Rezept liefert sie CO2-Werte, Bewertungen der Ernährungsqualität und die Berechtigung für den Eaternity Award.
Vollständige Beispiele für Request und Response finden Sie in den Anwendungsfällen Umweltbewertung von Rezepten und Menüs für Menüplan-Anzeige und Reporting.
Überblick
Mit der Recipe API können Sie:
- den CO2-Fussabdruck einzelner Gerichte berechnen
- ganze Menüs im Batch für die Umweltanalyse verarbeiten
- die Nachhaltigkeit von Rezepten über die Zeit verfolgen
- den Eaternity Award für Rezepte mit geringer Umweltwirkung erhalten
- Bewertungen der Ernährungsqualität erhalten (Skala A–E)
- den Umweltbeitrag einzelner Zutaten analysieren
Eindeutigkeit der Rezept-ID
Die API kennt ein Rezept nur über seine id. Die kitchen-id und das date werden mit dem Rezept gespeichert, machen es aber nicht zu einem anderen Rezept.
Senden Sie ein Rezept mit einer id, die bereits existiert, überschreibt die API das gespeicherte Rezept, inklusive kitchen-id und date. Die frühere Ausgabe fehlt dann in dieser Küche und an diesem Tag.
Die Regel: Verwenden Sie jedes Mal eine neue id, wenn ein Gericht in einer Küche an einem Tag serviert wird.
Beispiel 1: Küche A und Küche B servieren beide am 1. April Kürbisrisotto. Senden Sie zwei Rezepte mit zwei verschiedenen IDs, zum Beispiel risotto-kitchen-a-2026-04-01 und risotto-kitchen-b-2026-04-01. Mit einer gemeinsamen ID würde der zweite Request das Risotto in Küche B verschieben, und Küche A würde es in ihren Berichten verlieren.
Beispiel 2: Küche A serviert das Risotto am 2. April erneut. Das ist ein drittes Rezept mit einer dritten ID, zum Beispiel risotto-kitchen-a-2026-04-02. Würden Sie die ID vom 1. April wiederverwenden, würde die erste Ausgabe auf den 2. April verschoben, und am 1. April würde sie fehlen.
Ein einfacher Weg zu einer neuen ID: Kombinieren Sie Ihre eigene Rezeptnummer mit der Küche und dem Datum.
Unterrezepte sind die Ausnahme. Ein Unterrezept wie eine Sauce darf in jedem Menü, das es verwendet, dieselbe ID behalten; siehe Unterrezepte. Zu Menüs, die pro Küche und Datum gesendet werden, siehe Menüs für Menüplan-Anzeige und Reporting.
Unterrezepte
Rezepte können über das Zutatenfeld type: "recipes" andere Rezepte als Zutaten referenzieren. So lassen sich Menüpositionen hierarchisch aus wiederverwendbaren Unterrezepten zusammensetzen.
Alle einzelnen Rezepte dürfen dasselbe Unterrezept (z. B. Kürbisrisotto) als Zutat enthalten, jedes Mal mit derselben ID.
Der Nachteil einer wiederverwendeten ID für ein Unterrezept: Sie können seine Zusammensetzung nicht einzeln ändern, ohne alle Rezepte zu beeinflussen, die es referenzieren. Verwenden Sie individuelle IDs für Unterrezepte, wenn Sie sie unabhängig ändern müssen.
Unterrezepte werden als transient gesendet: Sie zählen nur über das Menü, das sie verwendet. Siehe Transiente Rezepte.
Query-Parameter
Alle Rezept-Endpoints akzeptieren die Query-Parameter full-resource, indicators, nutrient-values, ingredients-declaration, return-uids und transient. Werte und Standardwerte: Query-Parameter. Zu transient siehe auch Transiente Rezepte.
Beispiele
# 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:
Batch-spezifische Parameter
Der Endpoint /recipes/batch unterstützt zusätzliche Parameter:
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
priority | integer | 1 | Berechnungspriorität: 0 (niedrig) oder 1 (hoch, wird zuerst verarbeitet). Verwenden Sie 0 für Hintergrundjobs. |
Request-Header
| Header | Erforderlich | Beschreibung |
|---|---|---|
Content-Type | Ja | Muss application/json sein |
Authorization | Ja | Basic Auth mit API-Schlüssel |
Rezepteigenschaften
Die Felder jeder Zeile in ingredients stehen auf einer eigenen Seite: Zutaten.
Request-Schema
{
"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": []
}
}
Definition der Eigenschaften
Request-Eigenschaften
| Eigenschaft | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
kitchen-id | String | Ja | Die ID der Küche, zu der das Rezept gehört |
id | String | Ja | Eindeutige Rezept-ID. Regeln siehe Eindeutigkeit der Rezept-ID. |
titles | Array | Ja | Rezepttitel als Array von Sprachobjekten: [{"language": "en", "value": "..."}] |
recipe-portions | Float | Nein | Anzahl Portionen, für die die Zutaten angegeben sind. Standard ist 1. |
date | ISO Date | Empfohlen | Das Datum, an dem das Rezept serviert wird (Format: yyyy-mm-dd). |
ingredients | Array | Ja | Liste von Zutatenobjekten (mindestens 1). Siehe Zutaten. |
weight | Integer | Nein | Endgewicht des Rezepts pro Portion in Gramm. Wird verwendet, um Verdunstungs- und Garverluste zu berücksichtigen. Ohne Angabe gilt die Summe der Zutatengewichte. Um Lebensmittelverluste einzelner Zutaten abzubilden, verwenden Sie besser das Feld loss-in-percent-of-amount pro Zutat. |
author | String | Nein | Ursprüngliche Autorin oder ursprünglicher Autor des Rezepts |
location | String | Nein | Ort, an dem das Rezept gekocht wird. Adresse oder Land (beliebiges Format). Ohne Angabe gilt der Standort der Küche. |
production-portions | Float | Nein | Wie viele Portionen des Rezepts produziert werden sollen |
sold-portions | Float | Nein | Wie viele Portionen tatsächlich verkauft (konsumiert) wurden. Wird vom Forecast-Endpoint zur Prognose der Verkäufe verwendet. |
instructions | Array | Nein | Kochanleitung als Array von Sprachobjekten: [{"language": "en", "value": "..."}] |
menu-line-name | String | Nein | Bezeichnung der Menülinie (z. B. "Fitness", "Garden Menu", "Vegan Menu") |
menu-line-id | Integer | Nein | Numerische Kennung der Menülinie |
transient | Boolean | Nein | Feld des Batch-Eintrags, neben request-id. true macht das Rezept transient: Es wird berechnet und zurückgegeben, aber nicht gespeichert und nicht eigenständig gezählt. |
Ein Rezept ohne date wird berechnet, fehlt aber in datumsbasierten Berichten. Geben Sie immer das Datum an, an dem das Rezept serviert wird.
Response-Eigenschaften
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
co2-value | Integer | Gesamte CO2-Emissionen des ganzen Rezepts pro Portion (Gramm CO2-eq) |
co2-value-improvement-percentage | Float | Vergleich des CO2-Fussabdrucks dieses Rezepts pro Food Unit mit dem Durchschnitt |
co2-value-reduction-value | Float | Gramm CO2, die eingespart werden, wenn dieses Rezept statt eines durchschnittlichen Rezepts mit demselben Nährwert serviert wird |
rating | String | Umweltbewertung (Skala A–E, A ist am besten) |
eaternity-award | Boolean | true, wenn das Rezept klimafreundlich ist |
info-text | String | Hinweise zum berechneten CO2-Wert, z. B. Anmerkungen, wenn Eigenschaften wie Herkunft oder Transport geschätzt wurden |
final-weight-per-portion | Float | Endgewicht pro Portion nach dem Kochen (Gramm) |
indicators.vita-score | Object | Bewertung der Ernährungsqualität (A–E) und ihre Risikofaktoren (nur wenn indicators=true gesetzt ist). Siehe Vita Score. |
indicators | Object | Umwelt- und Ernährungsindikatoren (nur wenn der Parameter indicators=true gesetzt ist) |
nutrient-values-estimated-per-recipe-portion | Object | Aggregierte Nährwerte pro Portion: Summe der Nährwerte aller Zutaten, geteilt durch recipe-portions (wenn der Parameter nutrient-values=true gesetzt ist) |
Transiente Rezepte
transient bedeutetEin transientes Rezept wird berechnet, und sein Ergebnis kommt in der Response zurück. Danach wird es nicht gespeichert:
- Es zählt in den Berichten nie eigenständig, auch nicht mit einem
date. Seine Zutaten zählen nur über das Menü, das es verwendet. - Es kann später nicht abgerufen werden. Ein
GETantwortet mit404, und es erscheint nicht in der Rezeptliste der Küche. - Ein Menü kann es als Unterrezept verwenden.
Wo Sie es setzen
| Wo | Gilt für |
|---|---|
Body-Feld "transient": true auf einem Batch-Eintrag, neben request-id | Dieses eine Rezept |
Query-Parameter ?transient=true | Jedes Rezept im Request, inklusive der Menüs |
Setzen Sie das Body-Feld auf den Batch-Eintrag, nicht in recipe. Innerhalb von recipe wird es ignoriert, und das Rezept wird als normales Rezept gespeichert.
?transient=true auf einem Menü-Batch macht auch die Menüs transient, sodass sie aus den Berichten fallen. Für Unterrezepte verwenden Sie das Body-Feld.
Wann Sie es verwenden
- Unterrezepte wie eine Sauce, eine Beilage oder eine Basis: transient.
- Vorschauen und Tests:
?transient=true. - Menüs, die in den Berichten zählen sollen: nicht transient.
Batch-Operationen
Verarbeiten Sie mehrere Rezepte in einem einzigen Request für optimale Performance.
Request
POST /recipes/batch
Content-Type: application/json
Authorization: Basic {api_key}
Nachverfolgung mit Request-ID
Jedes Rezept in einem Batch kann ein ganzzahliges Feld request-id enthalten, mit dem Sie Rezepte in der Response zuordnen können. Das ist besonders nützlich, wenn Sie keine eigenen Rezept-IDs verwenden.
- Pro Eintrag ist entweder eine
request-idoder eine Rezept-iderforderlich - Die
request-idunterscheidet sich von der Rezept-idund gilt nur für die Dauer eines einzelnen Requests (sie wird nicht auf dem Server gespeichert)
Beispiel für die Zusammensetzung aus Unterrezepten
Im folgenden Request enthält die Menüposition "Fitness Risotto" ein einzelnes Rezept "Mushroom gravy on pumpkin risotto". Dieses Rezept besteht wiederum aus zwei Unterrezepten: "pumpkin risotto" und "Mushroom gravy". Alle Rezepte sind im Batch enthalten.
Die Menüposition ist nicht transient ("transient": false) und zählt deshalb in den Berichten. Die Unterrezepte sind transient ("transient": true): Sie werden mit dem Menü berechnet und zählen nur über dieses. Das Flag steht auf jedem Batch-Eintrag, neben 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, ein Eintrag pro Rezept in der Reihenfolge des Requests:
[
{
"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
Der Eaternity Award ist ein Label für klimafreundliche Mahlzeiten. Ein Rezept erhält den Eaternity Award, wenn es eine CO2-Bewertung "A" erreicht.
Das Feld eaternity-award ist ein Boolean, der zusammen mit der CO2-Bewertung zurückgegeben wird:
true— die Mahlzeit ist klimafreundlich (entspricht einer CO2-Bewertung "A")false— die Mahlzeit erfüllt die Kriterien nicht
Bewertungssystem
Rezepte erhalten eine Umweltbewertung von A (am besten) bis E (am schlechtesten). Schwellenwerte: Bewertungsskala.
Zutaten
Jede Rezeptzeile ist ein Zutatenobjekt. Felder, erlaubte Werte, Typen und Matching: Zutaten.
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.