All posts
ai guide

AI Product Analysis: Summaries Your Users Can Actually Read

Turn raw label data into a plain-language summary with good points, watch-outs, allergens, diet compatibility and processing level — for catalog products or your own data.

updated October 13, 2026 FoodBase Team 5 min read

The problem with raw nutrition data

Your API response says sugars_g: 56.3. Your user wants to know: is this a lot? Bridging that gap — turning numbers and ingredient lists into something a person can act on — is usually where nutrition apps either invest heavily or give up.

The analysis endpoints do that step for you: one call returns a short, factual, plain-language analysis generated strictly from the product’s data. The verdicts — what is high, what is a good point, which allergens, which diets — come from fixed, published thresholds applied in code; the AI writes the two-sentence summary and reads the ingredient list where a judgement is needed. No invented numbers, no health claims, and “unknown” rather than a guess.

Analyzing a catalog product

POST /v1/analyze/product takes a food_id or barcode (one of the two), costs 4 credits, and answers in any of 6 languages:

curl -X POST "https://foodbase.dev/v1/analyze/product" \
  -H "X-API-Key: food_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"barcode": "3017620422003", "lang": "en"}'
{
  "food_id": "…",
  "lang": "en",
  "cached": false,
  "analysis": {
    "summary": "Nutella is a hazelnut and cocoa chocolate spread from Ferrero, made mainly with sugar and palm oil. It is energy-dense and high in fat, saturated fat and sugars (56.3 g per 100 g), while being low in salt.",
    "highlights": ["Low salt (0.11 g per 100 g)"],
    "warnings": [
      "High in fat (30.9 g per 100 g)",
      "High in saturated fat (10.6 g per 100 g)",
      "High in sugars (56.3 g per 100 g)",
      "Contains palm oil"
    ],
    "allergens": { "contains": ["soy", "milk", "nuts"], "may_contain": [], "text": "Contains: soy, milk, nuts." },
    "diets": { "vegan": "no", "vegetarian": "yes", "gluten_free": "yes", "lactose_free": "no" },
    "diets_detail": {
      "vegan": { "value": "no", "basis": "allergen_tag" },
      "gluten_free": { "value": "yes", "basis": "label_claim" }
    },
    "processing_level": "ultra_processed",
    "processing_basis": "nova",
    "per_serving": "Per serving (15 g): 81 kcal · 4.6 g fat · 1.6 g saturated fat · 8.4 g sugars · 0.02 g salt · 0.9 g protein"
  },
  "disclaimer": "AI-generated from the product's label data…"
}

(Shortened: the response also carries nutrient_levels, the full diets_detail, nova_group and flags.) A few things worth knowing about the shape:

  • highlights are good points only, warnings are watch-outs only — and a topic never appears in both. A good point means the product meets the condition of an EU nutrition claim (low salt is at most 0.3 g per 100 g; source of protein is at least 12% of energy). A watch-out is a UK FSA “high” level, a large portion that crosses the FSA per-portion limit, or caffeine, sweeteners, alcohol or palm oil in the ingredients.
  • allergens are listed separately: the EU-14 allergens the label declares, as contains and may contain, with a localized sentence. status: "not_stated" means the record has no allergen data — check the package.
  • diets_detail says where each answer came from: a label claim, a declared allergen, or the ingredient list. Gluten-free and lactose-free are yes only with a label claim; a list without gluten ingredients gives no_known_source, because an uncertified product can still be contaminated. diets keeps the simple yes / no / unknown view — render unknown as a question mark, not a quiet omission.
  • processing_level comes from the product’s recorded NOVA group; only when there is none is it judged from the ingredients (processing_basis: "model").
  • disclaimer ships with every response. Show it — the analysis is informational, not medical advice.

Analyses are cached per product and language, so the first caller pays the generation latency and everyone after gets an instant answer — at the same 4-credit price. cached: true tells you which case you hit.

You can see this endpoint rendered on any product page — the “AI analysis” panel is exactly this response.

Analyzing your own product data

What about products that aren’t in the catalog — private-label goods, new launches, internal SKUs? POST /v1/analyze/custom (also 4 credits) accepts the product data in the request body and runs the same analysis:

curl -X POST "https://foodbase.dev/v1/analyze/custom" \
  -H "X-API-Key: food_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Protein bar cocoa",
    "brand": "MyBrand",
    "ingredients": "Oats, whey protein, cocoa, honey",
    "nutrients": { "energy_kcal": 380, "proteins_g": 30, "sugars_g": 18 }
  }'

Two rules keep the output honest:

  • A bare name is rejected (422). You must provide ingredients and/or at least one per-100g nutrient value — otherwise the model would have nothing factual to analyze.
  • Implausible values are rejected, not silently fixed. Nutrient fields have per-100g caps (energy ≤ 900 kcal, grams ≤ 100, sodium ≤ 10000 mg), and unknown nutrient keys are an error rather than being ignored.

The nutrients object takes the standard macros plus a curated set of vitamins and minerals (vitamin C, D, B12, folate, E, calcium, iron, potassium, magnesium, zinc) — give it more and the good points get sharper: supply calcium and iron values and you’ll get back things like “Source of calcium (150 mg per 100 g)” whenever a value reaches the EU threshold (15% of the reference intake per 100 g; twice that for “high in”).

The response mirrors the catalog analysis, with an input_hash instead of a food_id — identical input hashes identically, so repeat analyses of the same data are cache hits. There’s an optional barcode field too: it isn’t analyzed, it flags the product as one you’d like to see added to the catalog.

Prefer a form to a JSON body? The playground has this exact endpoint as a type-it-in form.

Practical integration notes

  • Language: pass lang (en, fr, es, de, it, bg) and the whole analysis — summary, good points, watch-outs, allergens — comes back in that language. The verdicts are identical in every language by construction. Each language caches separately.
  • Credits: 4 credits per call, including cache hits. Failures (bad request, provider error, unknown product) refund automatically — you only pay for answers.
  • Idempotency: there is none — a double-submit is two charges. Disable your button while a request is in flight.
  • Rendering: the response is designed to map straight onto UI — summary paragraph, good-points list, watch-out list, an allergen line, four diet badges with their basis, a processing-level tag. That’s precisely how the product pages here render it.
  • Broken label text? If the product’s own ingredient list is garbled (missing spaces, broken characters, ALL CAPS), POST /v1/correct/product repairs it for everyone and the analysis regenerates from the fixed text.

Try it

Grab a free API key (20 AI credits included), open the docs, or poke at the live panels on any product page.

Build it with FoodBase

6.1M products, 40+ nutrients and AI food analysis — free to start, no credit card.