API JSON v1

Oceny żywności dla Twojej aplikacji

Wszystko, co pokazuje strona, jest dostępne także jako JSON. Zapytania wymagają klucza API serwera – wyślij go w nagłówku X-API-Key (albo Authorization: Bearer <klucz>). Odpowiedzi nigdy nie są buforowane przez pośredników (Cache-Control: no-store) i zezwalają na CORS z dowolnego źródła.

Endpointy

EndpointDo czego służy
GET /api/v1Dokument opisowy: włączone źródła danych, endpointy, języki i wersja klasyfikatora.
GET /api/v1/search?q=…Wyszukiwanie po nazwie lub kategorii (najpierw Dabas, potem Open Food Facts). Jeśli q jest kodem kreskowym, produkt jest wyszukiwany bezpośrednio i zwracany od razu w odpowiedzi.
GET /api/v1/product/{gtin}Produkt z listą składników, wartością odżywczą, ogólną oceną healthy oraz ocenami FODMAP, keto, IG i stopnia przetworzenia. Przyjmuje EAN-8, UPC-A, EAN-13 i GTIN-14 (zera wiodące są normalizowane).

Przykłady

# produkt po kodzie kreskowym
curl -H "X-API-Key: $API_KEY" "https://maxing.fitness/api/v1/product/3017624010701"

# wyszukiwanie pełnotekstowe, teksty po polsku
curl -G -H "X-API-Key: $API_KEY" --data-urlencode "q=płatki owsiane" \
  "https://maxing.fitness/api/v1/search?lang=pl"

Języki

Podsumowania i uzasadnienia są domyślnie po angielsku. Dodaj lang z jednym z tych kodów, aby otrzymać je w innym języku UE: bg, es, cs, da, de, et, el, en, fr, ga, hr, it, lv, lt, hu, mt, nl, pl, pt, ro, sk, sl, fi, sv. Oceny, wyniki punktowe, identyfikatory reguł i klucze missing są takie same w każdym języku.

Struktura odpowiedzi

{
  "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": { … } }
}

Oceny

Każda ocena ma pole rating o wartości green, yellow, red lub unknown, jednowierszowe podsumowanie (summary), czytelne uzasadnienia (reasons) oraz matches wskazujące składniki (jako indeksy w ingredients), które wpłynęły na wynik. missing wymienia dane, które pozwoliłyby uściślić ocenę. healthy to ogólna odpowiedź: zielona dla produktów ze znakiem Dziurka od klucza (Nyckelhålet), w pozostałych przypadkach wynik Nutri-Score (z Open Food Facts albo oszacowany algorytmem z 2023 r. – wtedy score zawiera jego punkty), o jeden stopień niżej dla żywności ultraprzetworzonej. Heurystyki opisano w README; zmiany istotne dla klientów zwiększają meta.classifierVersion (wysyłane też w nagłówku X-Classifier-Version).

Błędy

{ "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)

Kody kreskowe z telefonu

Aplikacje natywne mogą skanować dowolną biblioteką do kodów kreskowych i wywoływać GET /api/v1/product/{gtin} z samymi cyframi: EAN-8, UPC-A (12 cyfr), EAN-13 i GTIN-14 uzupełniony zerami są normalizowane do tego samego produktu. UPC-E trzeba najpierw rozwinąć do UPC-A. Skaner na stronie robi dokładnie to samo w przeglądarce.

Pamięć podręczna i limity zapytań

Produkty są przechowywane w pamięci podręcznej przez 30 dni dla każdego GTIN, a potem odświeżane z baz źródłowych; gdy bazy nie działają, zwracana jest nieaktualna kopia. Open Food Facts pozwala na ok. 15 odczytów produktów i ok. 10 wyszukiwań na minutę z jednego adresu IP, więc seria zapytań spoza pamięci podręcznej może zwrócić 503 rate_limited – respektuj Retry-After. Dane: Open Food Facts (ODbL) i Dabas.