JSON-API v1
Voedselbeoordelingen voor je app
Alles wat de website laat zien, is ook beschikbaar als JSON. Verzoeken hebben de API-sleutel van de server nodig – stuur die mee als X-API-Key-header (of Authorization: Bearer <sleutel>). Antwoorden worden nooit door tussenliggende caches opgeslagen (Cache-Control: no-store) en staan CORS toe vanaf elke origin.
Endpoints
| Endpoint | Wat het doet |
|---|---|
GET /api/v1 | Overzichtsdocument: actieve bronnen, endpoints, talen en versie van de classificatie. |
GET /api/v1/search?q=… | Zoeken op naam of categorie (eerst Dabas, dan Open Food Facts). Als q een barcode is, wordt het product direct opgezocht en meteen meegestuurd. |
GET /api/v1/product/{gtin} | Product met ingrediëntenlijst, voedingswaarden, het totaaloordeel healthy en de beoordelingen voor FODMAP, keto, GI en bewerkingsgraad. Accepteert EAN-8, UPC-A, EAN-13 en GTIN-14 (voorloopnullen worden genormaliseerd). |
Voorbeelden
# product op barcode
curl -H "X-API-Key: $API_KEY" "https://maxing.fitness/api/v1/product/3017624010701"
# vrij zoeken, teksten in het Nederlands
curl -G -H "X-API-Key: $API_KEY" --data-urlencode "q=havermout" \
"https://maxing.fitness/api/v1/search?lang=nl"Talen
Samenvattingen en redenen zijn standaard in het Engels. Voeg lang toe met een van deze codes om ze in een andere EU-taal te krijgen: bg, es, cs, da, de, et, el, en, fr, ga, hr, it, lv, lt, hu, mt, nl, pl, pt, ro, sk, sl, fi, sv. Beoordelingen, scores, regel-id’s en missing-sleutels zijn in elke taal hetzelfde.
Antwoordstructuur
{
"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": { … } }
}Beoordelingen
Elke beoordeling heeft een rating (green, yellow, red of unknown), een samenvatting van één regel (summary), leesbare redenen (reasons) en matches die verwijzen naar de ingrediënten (als index in ingredients) die de beoordeling veroorzaakten. missing noemt gegevens die de beoordeling zouden verbeteren. healthy is het totaaloordeel: groen voor producten met het Sleutelgat (Nyckelhålet), anders de Nutri-Score (van Open Food Facts, of geschat met het algoritme van 2023 – dan staan de punten in score), één stap lager voor ultrabewerkt voedsel. De vuistregels staan beschreven in de README; wijzigingen die voor clients van belang zijn, verhogen meta.classifierVersion (ook meegestuurd als header X-Classifier-Version).
Fouten
{ "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 vanaf een telefoon
Native apps kunnen scannen met elke barcodebibliotheek en GET /api/v1/product/{gtin} aanroepen met de cijfers zoals ze zijn: EAN-8, UPC-A (12 cijfers), EAN-13 en met nullen aangevulde GTIN-14 worden allemaal naar hetzelfde product genormaliseerd. UPC-E moet eerst worden omgezet naar UPC-A. De eigen scanner van de website doet precies dat in de browser.
Caching en limieten
Producten worden per GTIN 30 dagen in de cache bewaard en daarna opnieuw opgehaald uit de brondatabases; liggen die plat, dan wordt de bewaarde kopie geleverd. Open Food Facts staat per IP-adres zo’n 15 productopvragingen en 10 zoekopdrachten per minuut toe, dus veel opvragingen buiten de cache tegelijk kunnen 503 rate_limited opleveren – houd je dan aan Retry-After. Gegevens: Open Food Facts (ODbL) en Dabas.