API Documentation
Build integrations with SHELF using our RESTful JSON API. Manage inventory, shopping lists, and storage locations programmatically.
Base URL
https://myshelf.life/api/v1
Authentifizierung
Alle API-Anfragen müssen einen gültigen API-Schlüssel im Authorization-Header enthalten.
Authorization: Bearer YOUR_API_KEY
Berechtigungsstufen
- Nur lesen: Kann Daten abrufen (GET-Anfragen)
- Lesen & Schreiben: Kann Daten abrufen und ändern (alle Anfragen)
Fehlerantworten
Bei Fehlern gibt die API einen JSON-Body mit Fehlerdetails zurück.
{"error": "Invalid or disabled API key", "code": "unauthorized"}
{"error": "This API key does not have write permissions", "code": "forbidden"}
{"error": "Resource not found", "code": "not_found"}
{"error": "Name can't be blank", "code": "unprocessable_entity", "details": {"name": ["can't be blank"]}}
Endpunkte
Lese-Endpunkte
/api/v1/locations
Gibt alle aktiven Lagerorte deines Haushalts zurück.
Beispielantwort
{
"locations": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Kühlschrank",
"icon": "🧊",
"location_type": "standard",
"is_default": true,
"items_count": 15,
"created_at": "2024-01-15T10:30:00Z"
}
]
}
/api/v1/inventory
Gibt alle Lagerorte mit ihren Artikeln zurück.
Beispielantwort
{
"locations": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Kühlschrank",
"icon": "🧊",
"location_type": "standard",
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440003",
"name": "Milch",
"quantity": 2.0,
"unit": "Liter",
"category": "dairy",
"icon": "🥛",
"expires_on": "2026-03-01",
"status": "ok",
"notes": "Bio",
"added_by": "Max",
"created_at": "2026-01-15T10:30:00Z"
}
]
}
]
}
/api/v1/shopping_list
Gibt die aktive Einkaufsliste mit allen nicht abgehakten Artikeln zurück.
Query Parameters
| Field | Type | Description |
|---|---|---|
| crossed_off | boolean | Auf true setzen, um statt der aktiven die abgehakten Artikel zu bekommen, zuletzt abgehakte zuerst. Standard false. active_count und crossed_off_count werden in beiden Fällen zurückgegeben. |
| limit | integer | Nur mit crossed_off=true. Wie viele abgehakte Artikel zurückkommen, Standard 50, Maximum 200. Abgehakte Artikel sammeln sich unbegrenzt an, daher ist diese Ansicht seitenweise. |
Headers
| X-Shelflife-Viewing: list | Optionale Kopfzeile X-Shelflife-Viewing: list. Apps, die die Liste gerade anzeigen, schicken sie bei jedem Abruf mit. Die Antwort enthält immer poll_after (Sekunden bis zum nächsten Abruf: 2, solange man selbst und noch jemand im Haushalt auf der Liste sind, sonst 5), active_shoppers und shoppers (wer außer einem selbst gerade draufschaut). |
Beispielantwort
{
"shopping_list": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Einkaufsliste",
"active_count": 5,
"crossed_off_count": 12,
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Milch",
"quantity": 2.0,
"unit": "Liter",
"category": "dairy",
"added_by": "Max",
"crossed_off": false,
"crossed_off_at": null,
"crossed_off_by": null,
"created_at": "2024-01-20T14:00:00Z"
}
]
},
"poll_after": 2,
"active_shoppers": 2,
"shoppers": [
{ "id": "550e8400-e29b-41d4-a716-446655440009", "name": "Sarah", "emoji": "🦝" }
]
}
/api/v1/household_actions
Gibt alle Haushaltsaktionen zurück, archivierte eingeschlossen (active: false), mit ihrem claimed_today-Status. Eine Reihenfolge überall: Kategorien nach position, darin die Aktionen nach position; die Position einer Aktion zählt über den ganzen Haushalt, archivierte zuletzt. category und category_emoji sind Name und Emoji der Kategorie, category_id und household_action_category beschreiben sie ganz.
Beispielantwort
{
"household_actions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Take out trash",
"emoji": "🗑️",
"points": 10,
"active": true,
"category": "Trash & Recycling",
"category_emoji": "🗑️",
"category_id": "440e8400-e29b-41d4-a716-446655440000",
"household_action_category": {
"id": "440e8400-e29b-41d4-a716-446655440000",
"name": "Trash & Recycling",
"emoji": "🗑️",
"position": 0
},
"position": 0,
"claimed_today": true,
"created_at": "2026-01-15T10:30:00Z"
}
]
}
/api/v1/household_action_categories
Gibt die Kategorien deiner Haushaltsaktionen in ihrer Reihenfolge zurück, mit der Zahl der aktiven Aktionen darin.
Beispielantwort
{
"household_action_categories": [
{
"id": "440e8400-e29b-41d4-a716-446655440000",
"name": "Trash & Recycling",
"emoji": "🗑️",
"position": 0,
"action_count": 4
}
]
}
/api/v1/bonus_points
Gibt die Bonuspunkte des API-Nutzers für die aktuelle Woche und insgesamt zurück, sowie das Haushalts-Ranking (ein Eintrag pro Haushaltsmitglied, sortiert nach Wochenpunkten). Rückgängig gemachte Aktivitäten werden nicht gezählt.
Beispielantwort
{
"week": {
"start": "2026-05-04",
"end": "2026-05-10",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Hendrik",
"score": 35
},
"standings": [
{ "user_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Hendrik", "score": 35, "rank": 1 },
{ "user_id": "660e8400-e29b-41d4-a716-446655440000", "name": "Partner", "score": 20, "rank": 2 }
]
},
"all_time": {
"user": { "score": 1250, "activity_count": 217 }
}
}
/api/v1/leaderboard
Gibt das vollständige Haushalts-Ranking zurück. Anders als bonus_points (nur Bonus-Aktionen) zählt hier der komplette Wochen-Score — hinzugefügte Artikel, Einkaufsliste, Races und Bonus-Aktionen — dieselbe Wertung wie bei den Championships. Mit period=all_time wird die Gesamtwertung (Championship-Siege) zurückgegeben. Gleichstände teilen sich einen Rang.
Query Parameters
| Field | Type | Description |
|---|---|---|
| period | string | Optional. "weekly" (Standard) für die aktuelle Woche oder "all_time" für die Championship-Siege. |
Beispielantwort
{
"period": "weekly",
"week": { "start": "2026-05-04", "end": "2026-05-10" },
"user": {
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Hendrik",
"score": 42,
"rank": 1,
"breakdown": { "add_item": 25, "cross_off_shopping": 6, "custom_actions": 11 }
},
"standings": [
{ "user_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Hendrik", "score": 42, "rank": 1, "breakdown": { } },
{ "user_id": "660e8400-e29b-41d4-a716-446655440000", "name": "Partner", "score": 42, "rank": 1, "breakdown": { } }
]
}
/api/v1/bonus_points/activities
Gibt die letzten Bonus-Aktionen des Haushalts zurück (custom_action-Aktivitäten). Neueste zuerst.
Query Parameters
| Field | Type | Description |
|---|---|---|
| limit | integer | Optional. Maximale Anzahl zurückgegebener Aktivitäten (Standard 50, Maximum 200). |
| since | iso8601 | Optional. ISO8601-Zeitstempel; gibt nur Aktivitäten zurück, die ab dieser Zeit erstellt wurden. |
| user_id | uuid | Optional. UUID eines Haushaltsmitglieds zum Filtern. |
| include_undone | boolean | Optional. "false" angeben, um rückgängig gemachte Aktivitäten auszuschließen (Standard: true). |
Beispielantwort
{
"activities": [
{
"id": "770e8400-e29b-41d4-a716-446655440000",
"household_action": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Coffee in bed",
"emoji": "☕",
"points": 10
},
"user": { "id": "660e8400-e29b-41d4-a716-446655440000", "name": "Hendrik" },
"points": 10,
"created_at": "2026-05-09T08:30:00Z",
"undone_at": null
}
],
"count": 1
}
Schreib-Endpunkte
Erforderliche Berechtigung: Lesen & Schreiben
/api/v1/inventory/items
Fügt einen neuen Artikel zu deinem Vorrat hinzu. Kategorie und Icon werden automatisch basierend auf dem Artikelnamen zugewiesen.
Anfrage-Body
| Field | Type | Description |
|---|---|---|
| name | string | Erforderlich. Der Artikelname. |
| location_id | uuid | Erforderlich. UUID des Lagerorts. |
| quantity | number | Optional. Numerische Menge (Standard: 1). |
| unit | string | Optional. Maßeinheit. |
| expires_on | date | Optional. Ablaufdatum (JJJJ-MM-TT). |
| notes | string | Optional. Zusätzliche Notizen. |
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/inventory/items" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"item": {"name": "Eggs", "location_id": "LOCATION_UUID", "quantity": 6, "expires_on": "2026-03-15"}}'
Beispielantwort (201)
{
"item": {
"id": "550e8400-e29b-41d4-a716-446655440010",
"name": "Eggs",
"quantity": "6.0",
"unit": null,
"category": "dairy",
"icon": "🥚",
"expires_on": "2026-03-15",
"status": "ok",
"notes": null,
"added_by": "Max",
"created_at": "2026-02-15T10:30:00Z"
}
}
/api/v1/shopping_list/items
Fügt einen neuen Artikel zur Einkaufsliste hinzu. Die Kategorie wird automatisch zugewiesen.
Anfrage-Body
| Field | Type | Description |
|---|---|---|
| name | string | Erforderlich. Der Artikelname. |
| quantity | number | Optional. Numerische Menge. |
| unit | string | Optional. Maßeinheit (z.B. "Liter", "g", "Stück"). |
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/shopping_list/items" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"item": {"name": "Milch", "quantity": 2, "unit": "Liter"}}'
Beispielantwort (201)
{
"item": {
"id": "550e8400-e29b-41d4-a716-446655440010",
"name": "Milch",
"quantity": "2.0",
"unit": "Liter",
"category": "dairy",
"added_by": "Max",
"created_at": "2026-02-15T10:30:00Z"
}
}
/api/v1/shopping_list/items/:id
Aktualisiert Menge und/oder Einheit eines aktiven Einkaufslisten-Artikels. Abgehakte Artikel können nicht aktualisiert werden (422).
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/shopping_list/items/ITEM_ID" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"item": {"quantity": 500, "unit": "ml"}}'
Beispielantwort (200)
{
"item": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Milch",
"quantity": "500.0",
"unit": "ml",
"category": "dairy",
"added_by": "Max",
"created_at": "2026-01-20T14:00:00Z"
}
}
/api/v1/shopping_list/items/:id/cross_off
Hakt einen Artikel ab, genau wie das Antippen in der App: Er verschwindet aus der aktiven Liste und zählt für den Wochen-Score. Idempotent: ein bereits abgehakter Artikel gibt 200 zurück, ohne doppelt zu zählen.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/shopping_list/items/ITEM_ID/cross_off" \
-H "Authorization: Bearer YOUR_API_KEY"
Beispielantwort (200)
{
"item": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Milch",
"quantity": "2.0",
"unit": "Liter",
"category": "dairy",
"added_by": "Max",
"crossed_off": true,
"crossed_off_at": "2026-01-20T15:12:00Z",
"crossed_off_by": "Max",
"created_at": "2026-01-20T14:00:00Z"
}
}
/api/v1/shopping_list/items/:id/uncross
Setzt einen abgehakten Artikel zurück auf die aktive Liste. Idempotent.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/shopping_list/items/ITEM_ID/uncross" \
-H "Authorization: Bearer YOUR_API_KEY"
/api/v1/shopping_list/items/:id
Löscht einen Einkaufslisten-Artikel endgültig. Anders als bei Vorratsartikeln gibt es kein Archiv, der Datensatz ist weg. Für "gekauft" nimm cross_off, für Artikel die nie auf die Liste gehörten DELETE. Gibt den gelöschten Artikel zurück.
Beispielanfrage
curl -X DELETE "https://myshelf.life/api/v1/shopping_list/items/ITEM_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
/api/v1/inventory/items/:id
Aktualisiert einen aktiven Vorratsartikel. Du kannst Menge, Einheit, Lagerort oder Ablaufdatum ändern. Archivierte Artikel geben 404 zurück.
Anfrage-Body
| Field | Type | Description |
|---|---|---|
| quantity | number | Neuer Mengenwert |
| unit | string | Neue Maßeinheit |
| location_id | uuid | UUID des neuen Lagerorts |
| expires_on | date | Neues Ablaufdatum (JJJJ-MM-TT) |
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/inventory/items/ITEM_ID" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"item": {"quantity": 500, "unit": "ml", "location_id": "LOCATION_UUID", "expires_on": "2026-03-15"}}'
Beispielantwort (200)
{
"item": {
"id": "550e8400-e29b-41d4-a716-446655440003",
"name": "Milch",
"quantity": "500.0",
"unit": "ml",
"category": "dairy",
"icon": "🥛",
"expires_on": "2026-03-15",
"status": "ok",
"notes": "Bio",
"added_by": "Max",
"created_at": "2026-01-15T10:30:00Z"
}
}
/api/v1/household_actions/:id/log
Protokolliert eine Haushaltsaktion, um Punkte zu verdienen. Gibt 422 zurück, wenn die Aktion inaktiv ist.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/household_actions/ACTION_ID/log" \
-H "Authorization: Bearer YOUR_API_KEY"
Beispielantwort (201)
{
"household_action": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Take out trash",
"emoji": "🗑️",
"points": 10,
"active": true,
"category": "Trash & Recycling",
"category_emoji": "🗑️",
"category_id": "440e8400-e29b-41d4-a716-446655440000",
"household_action_category": { "id": "440e8400-e29b-41d4-a716-446655440000", "name": "Trash & Recycling", "emoji": "🗑️", "position": 0 },
"position": 0,
"claimed_today": true,
"created_at": "2026-01-15T10:30:00Z"
},
"activity": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"activity_type": "custom_action",
"points": 10,
"created_at": "2026-03-07T14:00:00Z"
}
}
/api/v1/household_actions/:id/toggle
Schaltet eine Haushaltsaktion zwischen aktiv und archiviert um. Gibt 422 zurück, wenn eine aktive Aktion schon so heißt.
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/household_actions/ACTION_ID/toggle" \
-H "Authorization: Bearer YOUR_API_KEY"
Beispielantwort (200)
{
"household_action": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Take out trash",
"emoji": "🗑️",
"points": 10,
"active": false,
"category": "Trash & Recycling",
"category_emoji": "🗑️",
"category_id": "440e8400-e29b-41d4-a716-446655440000",
"household_action_category": { "id": "440e8400-e29b-41d4-a716-446655440000", "name": "Trash & Recycling", "emoji": "🗑️", "position": 0 },
"position": 0,
"claimed_today": false,
"created_at": "2026-01-15T10:30:00Z"
}
}
/api/v1/household_actions
Legt eine Haushaltsaktion am Ende ihrer Kategorie an. name und category_id sind Pflicht, points 1 bis 100 (Standard 10), emoji sonst ✅. Mit einer eigenen UUID als id wird ein zweiter Versuch ungefährlich: Er gibt die vorhandene Aktion mit 200 zurück. Gibt 422 mit code unknown_category zurück, wenn die Kategorie nicht zu deinem Haushalt gehört.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/household_actions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"household_action": {"name": "Tidy the kids room", "emoji": "🧸", "points": 30, "category_id": "CATEGORY_ID"}}'
Beispielantwort (201)
{
"household_action": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Tidy the kids room",
"emoji": "🧸",
"points": 30,
"active": true,
"category_id": "CATEGORY_ID",
"position": 4,
...
}
}
/api/v1/household_actions/:id
Ändert name, emoji, points, category_id oder active (false archiviert, true holt zurück). In einer neuen Kategorie steht die Aktion am Ende. Neue Punkte gelten nur für künftige Einträge; die anderen im Haushalt bekommen eine Mitteilung.
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/household_actions/ACTION_ID" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"household_action": {"points": 40}}'
/api/v1/household_actions/:id
Archiviert eine Haushaltsaktion, statt sie zu löschen. Eingetragenes behält Name und Punkte, und mit active: true kommt die Aktion zurück. Idempotent.
Beispielanfrage
curl -X DELETE "https://myshelf.life/api/v1/household_actions/ACTION_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
/api/v1/household_actions/reorder
Setzt die Reihenfolge der Aktionen aus einer Liste von ids. Sie gilt innerhalb der Kategorien, deren eigene Reihenfolge bleibt. Nicht genannte folgen hinter den genannten ihrer Kategorie. Gibt die ganze Liste zurück.
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/household_actions/reorder" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ids": ["ACTION_ID_1", "ACTION_ID_2", "ACTION_ID_3"]}'
/api/v1/household_action_categories
Legt eine Kategorie am Ende an. Eine eigene id macht einen zweiten Versuch ungefährlich; eine vorhandene id oder ein vorhandener Name gibt die vorhandene Kategorie mit 200 zurück.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/household_action_categories" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"household_action_category": {"name": "Kids", "emoji": "🧸"}}'
/api/v1/household_action_categories/:id
Benennt eine Kategorie um oder ändert ihr Emoji.
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/household_action_categories/CATEGORY_ID" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"household_action_category": {"name": "Children"}}'
/api/v1/household_action_categories/:id
Entfernt eine Kategorie. Ihre Aktionen, archivierte eingeschlossen, wandern ans Ende von move_to_id oder nach „Sonstiges“ (wird bei Bedarf angelegt). „Sonstiges“ selbst lässt sich mit Aktionen nur mit move_to_id entfernen (422, code move_target_required).
Beispielanfrage
curl -X DELETE "https://myshelf.life/api/v1/household_action_categories/CATEGORY_ID" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"move_to_id": "OTHER_CATEGORY_ID"}'
Beispielantwort (200)
{
"household_action_category": { "id": "CATEGORY_ID", "name": "Kids", "emoji": "🧸", "position": 3, "action_count": 2 },
"moved_to": { "id": "OTHER_CATEGORY_ID", "name": "Other", "emoji": "📋", "position": 6, "action_count": 5 },
"moved_action_ids": ["550e8400-e29b-41d4-a716-446655440001", "550e8400-e29b-41d4-a716-446655440002"]
}
/api/v1/household_action_categories/reorder
Setzt die Reihenfolge der Kategorien aus einer Liste von ids; nicht genannte folgen. Die Positionen der Aktionen ziehen mit.
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/household_action_categories/reorder" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ids": ["CATEGORY_ID_1", "CATEGORY_ID_2"]}'
/api/v1/activities/:id/undo
Markiert eine zuvor protokollierte Bonus-Aktivität als rückgängig gemacht und entfernt deren Punkte aus den Summen. Jedes Haushaltsmitglied kann jede Haushaltsaktivität rückgängig machen. Gibt 422 zurück, wenn die Aktivität bereits rückgängig gemacht wurde, 404, wenn die Aktivität nicht zu deinem Haushalt gehört oder keine Bonus-Aktion ist.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/activities/ACTIVITY_ID/undo" \
-H "Authorization: Bearer YOUR_API_KEY"
Beispielantwort (200)
{
"activity": {
"id": "770e8400-e29b-41d4-a716-446655440000",
"household_action": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Coffee in bed",
"emoji": "☕",
"points": 10
},
"user": { "id": "660e8400-e29b-41d4-a716-446655440000", "name": "Hendrik" },
"points": 10,
"created_at": "2026-05-09T08:30:00Z",
"undone_at": "2026-05-09T08:32:14Z"
}
}
/api/v1/activities/:id/redo
Stellt eine zuvor rückgängig gemachte Bonus-Aktivität wieder her und fügt deren Punkte wieder hinzu. Gibt 422 zurück, wenn die Aktivität nicht rückgängig gemacht wurde.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/activities/ACTIVITY_ID/redo" \
-H "Authorization: Bearer YOUR_API_KEY"
Beispielantwort (200)
{
"activity": {
"id": "770e8400-e29b-41d4-a716-446655440000",
"household_action": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Coffee in bed",
"emoji": "☕",
"points": 10
},
"user": { "id": "660e8400-e29b-41d4-a716-446655440000", "name": "Hendrik" },
"points": 10,
"created_at": "2026-05-09T08:30:00Z",
"undone_at": null
}
}
/api/v1/inventory/items/:id
Archiviert (soft-delete) einen Vorratsartikel. Bereits archivierte Artikel geben 404 zurück. Der Artikel kann über die Web-Oberfläche aus dem Archiv wiederhergestellt werden.
Beispielanfrage
curl -X DELETE "https://myshelf.life/api/v1/inventory/items/ITEM_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
Beispielantwort (200)
{
"item": {
"id": "550e8400-e29b-41d4-a716-446655440003",
"name": "Milch",
"quantity": "2.0",
"unit": "Liter",
"category": "dairy",
"icon": "🥛",
"expires_on": "2026-03-01",
"status": "ok",
"notes": "Bio",
"added_by": "Max",
"created_at": "2026-01-15T10:30:00Z"
}
}
Meal Plans
Plan meals per day (recipe = title, description, ingredients). Each ingredient may reference an inventory item via item_id, or is matched by name against your active inventory, so responses show what a meal would consume and whether it is in stock. Marking a plan cooked deducts the consumed quantities (and archives an item once it reaches zero). Ideal for agent control.
/api/v1/meal_plans
List meal plans in a date range. Each ingredient is resolved against current inventory (in-stock status + matched item). Requires a Read key.
Query Parameters
| Field | Type | Description |
|---|---|---|
| from | date | Start date (YYYY-MM-DD). Defaults to today. Pass an earlier date to browse history. |
| to | date | End date (YYYY-MM-DD). Defaults to from + 6 days. |
Beispielantwort
{
"from": "2026-06-04",
"to": "2026-06-10",
"meal_plans": [
{
"id": "…",
"date": "2026-06-04",
"title": "Pasta Pomodoro",
"description": "Schnelle Tomaten-Pasta",
"cooked_at": null,
"in_stock_count": 1,
"total_ingredients": 2,
"ingredients": [
{ "name": "Pasta", "quantity": 500, "unit": "g", "item_id": "…", "in_stock": true, "available_quantity": "2.0", "location": "Vorratskammer" },
{ "name": "Basilikum", "quantity": 1, "unit": null, "item_id": null, "in_stock": false }
]
}
]
}
/api/v1/meal_plans
Create a meal plan for a day. Requires a Read & Write key.
Anfrage-Body
| Field | Type | Description |
|---|---|---|
| date | string | Day the meal is planned for, YYYY-MM-DD (required) |
| title | string | Recipe title (required) |
| description | string | Short description (optional) |
| ingredients | array | [{ name, quantity, unit, item_id }] — item_id optional; if omitted it is matched to inventory by name on save (optional) |
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/meal_plans" \
-H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"meal_plan": {"date": "2026-06-04", "title": "Pasta Pomodoro", "ingredients": [{"name": "Pasta", "quantity": 500, "unit": "g"}, {"name": "Tomaten", "quantity": 1, "unit": "Dose"}]}}'
Example Response (201 Created)
{
"meal_plan": {
"id": "…",
"date": "2026-06-04",
"title": "Pasta Pomodoro",
"description": null,
"cooked_at": null,
"in_stock_count": 1,
"total_ingredients": 2,
"ingredients": [
{ "name": "Pasta", "quantity": 500, "unit": "g", "item_id": "…", "in_stock": true, "available_quantity": "2.0", "location": "Vorratskammer" },
{ "name": "Tomaten", "quantity": 1, "unit": "Dose", "item_id": null, "in_stock": false }
]
}
}
/api/v1/meal_plans/:id
Edit the recipe or move it to another day. Send only the fields you want to change. Requires a Read & Write key.
Anfrage-Body
| Field | Type | Description |
|---|---|---|
| date | string | Move to this day, YYYY-MM-DD (optional) |
| title | string | New recipe title (optional) |
| description | string | New description (optional) |
| ingredients | array | Replace the ingredient list, same shape as POST (optional) |
Beispielanfrage
curl -X PATCH "https://myshelf.life/api/v1/meal_plans/MEAL_PLAN_ID" \
-H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"meal_plan": {"date": "2026-06-05"}}'
Example Response (200 OK)
{ "meal_plan": { "id": "…", "date": "2026-06-05", "title": "Pasta Pomodoro", "cooked_at": null, "ingredients": [ … ] } }
/api/v1/meal_plans/:id/cook
Mark the plan cooked and deduct the consumed inventory: each matched item is decremented by the recipe amount and archived once it reaches zero. Returns a consumed log. Requires a Read & Write key.
Beispielanfrage
curl -X POST "https://myshelf.life/api/v1/meal_plans/MEAL_PLAN_ID/cook" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response (200 OK)
{
"meal_plan": { "id": "…", "cooked_at": "2026-06-04T18:30:00Z", "…": "…" },
"consumed": [
{ "item_id": "…", "name": "Pasta", "action": "decremented", "used": 500, "remaining": "1500.0" },
{ "item_id": "…", "name": "Tomaten", "action": "archived", "used": 1, "remaining": 0 }
]
}
/api/v1/meal_plans/:id
Soft-delete (archive) a meal plan. Requires a Read & Write key.
Beispielanfrage
curl -X DELETE "https://myshelf.life/api/v1/meal_plans/MEAL_PLAN_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response (200 OK)
{ "meal_plan": { "id": "…", "date": "2026-06-04", "title": "Pasta Pomodoro", "…": "…" } }
Beispiel mit curl
Hier ist ein Beispiel, wie du die API mit curl aufrufen kannst:
# Read shopping list
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://myshelf.life/api/v1/shopping_list
# Add item to shopping list
curl -X POST "https://myshelf.life/api/v1/shopping_list/items" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"item": {"name": "Milch", "quantity": 2, "unit": "Liter"}}'