4.3 KiB
Recipe Bundle format (version 3)
A Recipe Bundle is a .zip file. The Excel converter (tools/excel-import) writes one, the app's "Rezepte importieren" reads it, and "Sammlung exportieren" writes the same format.
bundle.json
photos/<recipe-id>-1.jpg
photos/<recipe-id>-2.jpg
Photos are JPEG, at most 1600 px on the long side.
"Als Datei teilen" sends one Recipe as a Recipe Bundle named <Recipe name>.cookit, without Favourite, Review Flag and (if the cook says so) Notes. Opened in CookIt, a bundle with exactly one Recipe shows that Recipe's preview and saves it as a new copy; a bundle with several is imported as usual. A Recipe Code (QR) carries the same Recipe JSON without Photos – see docs/adr/0005.
bundle.json
{
"format": "cookit.recipe-bundle", // reject anything else
"version": 2, // reject versions newer than the app understands; 1 = no "units", 3 = has "plan"
"units": [ // the cook's own units (version 2); built-in ones are never listed
{ "key": "own-5c1e…", "label": "Würfel", "direct": true }
],
"createdAt": "2026-10-20T14:00:00Z",
"recipes": [
{
"id": "3f0c…", // UUID; a Recipe with this id already in the collection is skipped on import
"name": "Focaccia",
"course": "Brot", // Course name, or null; unknown names are added to the Course list
"tags": ["Langosch", "Airfryer"],
"servings": 4, // number (may be fractional, e.g. 3.5) or null
"prepMinutes": 30, // or null
"cookMinutes": 20, // or null
"calories": { "kcal": 775, "basis": "perServing" }, // basis: "perServing" | "wholeRecipe"; or null
"ingredientGroups": [
{
"name": null, // null = unnamed group (a visual break in the list)
"lines": [
{
"amount": 2, // number or null
"amountMax": 3, // number or null; set for ranges like "2-3"
"unit": "tablespoon", // built-in unit key (see below), an own unit's key from "units", or null
"name": "Kakaopulver",
"remark": null // e.g. "optional", or a note from the original
}
]
}
],
"stepSections": [
{ "title": "Vorteig", "steps": ["Verrühre die Zutaten …", "…"] } // title null = no heading
],
"photos": ["photos/3f0c…-1.jpg"], // paths inside the zip; the first is the main Photo
"sources": ["https://sallys-blog.de/…"],
"notes": "22x22 cm eckige Form", // or null
"favourite": false,
"reviewReasons": ["Portionen fehlen."] // empty = no Review Flag
}
],
"plan": { // version 3 only: a week of the Week Plan ("Wochenplan teilen")
"weekStart": "2026-10-19",
"meals": ["Mittag", "Abend"], // the sender's Meals the entries use, in order
"entries": [
{ "day": "2026-10-19", "meal": "Abend", "recipe": "3f0c…", "note": null }, // "recipe": an id in "recipes"
{ "day": "2026-10-21", "meal": "Mittag", "recipe": null, "note": "Essen gehen" }
]
}
}
A bundle is written with the lowest version its content needs: 2 normally, 3 only when it carries a plan. On receiving a plan, CookIt shows the week and, on "Übernehmen", reuses Recipes it already has (same id, else same name), adds the others with their id, matches Meals by name (creating missing ones) and adds the entries next to what is planned that week.
Unit keys
| key | German | key | German |
|---|---|---|---|
gram |
Gramm | bunch |
Bund |
kilogram |
Kilogramm | handful |
Handvoll |
milliliter |
Milliliter | cup |
Tasse |
liter |
Liter | can |
Dose |
tablespoon |
Esslöffel | jar |
Glas |
teaspoon |
Teelöffel | tub |
Becher |
pinch |
Prise | bag |
Beutel |
knifeTip |
Messerspitze | carton |
Karton |
pack |
Packung | head |
Kopf |
piece |
Stück | grain |
Korn |
slice |
Scheibe | small |
klein |
clove |
Zehe | medium |
mittel |
sprig |
Zweig | large |
groß |
some |
etwas |
These keys are built in. A fresh app offers gram to pack directly and the rest under "Weitere Einheiten"; the cook can change that and add their own units (see units above and docs/adr/0003).