JSON-API v1
Lebensmittel-Bewertungen für deine App
Alles, was die Website zeigt, gibt es auch als JSON. Anfragen brauchen den API-Schlüssel des Servers – schick ihn als X-API-Key-Header (oder Authorization: Bearer <Schlüssel>). Antworten werden nie von zwischengeschalteten Caches gespeichert (Cache-Control: no-store) und erlauben CORS von jedem Origin.
Endpunkte
| Endpunkt | Funktion |
|---|---|
GET /api/v1 | Übersichtsdokument: aktive Datenquellen, Endpunkte, Sprachen und Version des Klassifikators. |
GET /api/v1/search?q=… | Suche nach Namen oder Kategorie (zuerst Dabas, dann Open Food Facts). Ist q ein Barcode, wird das Produkt direkt nachgeschlagen und gleich mitgeliefert. |
GET /api/v1/product/{gtin} | Produkt mit Zutatenliste, Nährwertangaben, der Gesamtbewertung healthy und den Bewertungen für FODMAP, Keto, GI und Verarbeitungsgrad. Akzeptiert EAN-8, UPC-A, EAN-13 und GTIN-14 (führende Nullen werden normalisiert). |
Beispiele
# Produkt per Barcode
curl -H "X-API-Key: $API_KEY" "https://maxing.fitness/api/v1/product/3017624010701"
# Freitextsuche, Texte auf Deutsch
curl -G -H "X-API-Key: $API_KEY" --data-urlencode "q=Haferflocken" \
"https://maxing.fitness/api/v1/search?lang=de"Sprachen
Zusammenfassungen und Begründungen sind standardmäßig auf Englisch. Mit lang und einem dieser Codes bekommst du sie in einer anderen EU-Sprache: bg, es, cs, da, de, et, el, en, fr, ga, hr, it, lv, lt, hu, mt, nl, pl, pt, ro, sk, sl, fi, sv. Einstufungen, Punktzahlen, Regel-IDs und missing-Schlüssel sind in jeder Sprache gleich.
Antwortformat
{
"ok": true,
"data": {
"product": { "gtin": "3017624010701", "name": "Nutella", "brand": "Ferrero", "ingredientsText": "…",
"nutrition": { "basis": "100g", "carbs": 57.5, "sugars": 56.3, … },
"novaGroup": 4, "images": { "front": "…" }, "sources": [ { "name": "off", … } ] },
"verdicts": {
"healthy": { "rating": "red", "summary": "Nutri-Score E, ultra-processed, high in sugar and saturated fat", … },
"fodmap": { "rating": "yellow", "summary": "…", "reasons": ["…"], "matches": [ … ] },
"keto": { "rating": "red", … },
"glycemic": { "rating": "yellow", … },
"processed": { "rating": "red", … }
},
"ingredients": [ { "text": "socker", "depth": 0, "section": "main" }, … ],
"traces": ["nötter"],
"labels": [],
"cache": { "status": "hit", "fetchedAt": "2026-08-26T18:00:00.000Z", "partial": false }
},
"meta": { "classifierVersion": 2, "cache": "hit", "sources": ["off"], "attribution": { … } }
}Bewertungen
Jede Bewertung hat ein rating (green, yellow, red oder unknown), eine einzeilige Zusammenfassung (summary), lesbare Begründungen (reasons) und matches, die auf die auslösenden Zutaten verweisen (als Index in ingredients). missing listet Daten auf, die die Bewertung verbessern würden. healthy ist die Gesamtantwort: grün für Produkte mit dem Schlüsselloch (Nyckelhålet), sonst der Nutri-Score (von Open Food Facts oder mit dem Algorithmus von 2023 geschätzt – dann enthält score dessen Punkte), eine Stufe schlechter bei hochverarbeiteten Lebensmitteln. Die Heuristiken sind in der README beschrieben; Änderungen, die Clients betreffen, erhöhen meta.classifierVersion (wird auch als Header X-Classifier-Version gesendet).
Fehler
{ "ok": false, "error": { "code": "unauthorized", "message": "…" } }
400 invalid_gtin · 401 unauthorized · 404 product_not_found / not_found
503 api_not_configured · 503 upstream_unavailable / rate_limited (with Retry-After)Barcodes vom Smartphone
Native Apps können mit einer beliebigen Barcode-Bibliothek scannen und GET /api/v1/product/{gtin} mit den unveränderten Ziffern aufrufen: EAN-8, UPC-A (12 Ziffern), EAN-13 und mit Nullen aufgefüllte GTIN-14 werden alle auf dasselbe Produkt normalisiert. UPC-E muss vorher zu UPC-A erweitert werden. Der Scanner der Website macht im Browser genau dasselbe.
Caching und Anfragelimits
Produkte werden pro GTIN 30 Tage zwischengespeichert und danach aus den Quelldatenbanken aktualisiert; sind die Datenbanken nicht erreichbar, wird die gespeicherte Kopie ausgeliefert. Open Food Facts erlaubt pro IP etwa 15 Produktabfragen und 10 Suchen pro Minute; viele nicht gespeicherte Abfragen auf einmal können daher mit 503 rate_limited beantwortet werden – halte dich dann an Retry-After. Daten: Open Food Facts (ODbL) und Dabas.