Skip to content
Recipe API

Before the Badge: A Typed Handoff for Food Composition and Nutrient Profiling

Fresh work on regional composition data, polyol energy calculations, and 42 front-of-pack models shows how nutrition APIs should validate the handoff from nutrient evidence to policy scores.

nutritionapi-designdata-modelingfood-datavalidation

Three fresh signals meet at one API boundary

Three developments this week expose a fault line inside nutrition products.

On August 30, the Saudi Press Agency announced the Saudi Food Composition Database, describing it as the Kingdom's first national database of its kind. The announcement says it covers local foods and traditional dishes and includes energy, carbohydrate, protein, fat, vitamin, mineral, and fibre data. It also explicitly invites developers to use the accessible data for tools that assess dietary patterns and nutritional status.

Two days earlier, an open Open Food Facts energy-computation fix documented a narrower but revealing defect. When a product supplied individual polyols such as isomalt without an aggregate polyols value, those grams could be treated as ordinary carbohydrate. The proposed fix sums available individual polyols and applies the appropriate energy factors. Its tests reproduce an inflated computed-energy result and a false data-quality warning.

Also on August 28, a Nature Food systematic review identified 42 nutrient profile models used for front-of-pack nutrition labelling. The models vary by label type, nutrients, food categories, thresholds, validation, and scope. All limited sugar, most limited sodium and saturated fat, but only nine had demonstrated convergent validity and three criterion validity, according to the review.

The synthesis is more useful than any item alone: a nutrition API needs a typed, eligibility-checked handoff from composition and calculation evidence into nutrient-profile evaluation. A numerically present field is not automatically a compatible model input.

Source map and the repeated angle to avoid

Evidence Freshness Contribution
Saudi Press Agency, database launch August 30, 2026 A new national reference spanning local foods, traditional dishes, major nutrients, and intended digital use
Open Food Facts, polyol energy pull request Opened August 28; updated August 29, 2026 A concrete derivation bug, false quality signal, calculation basis, and regression tests; still open at publication
Nature Food, systematic review and supplement August 28, 2026 Forty-two models plus differences in applicability, solid/liquid bases, thresholds, exclusions, and validation
Saudi Press Agency, National Nutrition Committee meeting August 26, 2026 Official process context: the committee reviewed outcomes from the national database initiative before launch

Recent Recipe API posts have already covered food-composition provenance, edition migration, and jurisdiction-specific rulebooks. Repeating “store the source version” or “select the right policy” would add little. The new angle is the interface between those systems: proving that each value has the meaning, basis, derivation, and completeness a selected model expects.

A flat nutrient map erases four different claims

Consider sugars_g: 8. It might be:

Value type What the number claims Typical limitation
Analysed A laboratory measured a defined sample Sampling, method, preparation state, and uncertainty matter
Declared A producer or package reported the value Rounding rules and market-specific label definitions apply
Calculated A formula combined other nutrient values Correctness depends on factors, component relationships, and basis
Imputed A proxy, average, or model filled a gap It may be useful for discovery but unsuitable for a policy claim

Those values can coexist without being interchangeable. A regional composition row may be the best estimate for a traditional dish in a meal planner. A packaged-food model may instead require the actual product's declared values. A clinical workflow may reject imputed sodium. A front-of-pack rule may distinguish total sugar from added sugar or apply only to products with added ingredients.

The data contract should therefore represent nutrient observations, not just nutrient names:

{
  "nutrient": "polyols",
  "value": 100,
  "unit": "g",
  "basis": {"amount": 100, "unit": "g", "state": "as_sold"},
  "evidenceType": "calculated",
  "derivation": {
    "method": "sum_components",
    "inputs": ["isomalt", "maltitol", "sorbitol", "erythritol"],
    "ruleVersion": "energy-eu-polyols-2026-08"
  },
  "completeness": "known_components_only",
  "sourceRecord": "product:4002590140940@2026-08-28"
}

This does not mean every response must be verbose. A compact nutrition summary can remain the default. The typed observations should be available to calculation, validation, audit, and policy endpoints.

The polyol case is an interface failure, not just a formula bug

The Open Food Facts proposal describes a sugar-free sweet containing isomalt but no aggregate polyol value. The old calculation path recognized an erythritol fallback, but not the other individually entered polyols. The result could count those grams at the regular carbohydrate rate rather than the general polyol rate. The proposed regression tests use an all-isomalt case where 100 grams should contribute 1,000 kilojoules and report that the prior calculation was off by 700 kilojoules.

Several API failures are compressed into that example:

  1. carbohydrates contains polyols, so summing both as independent nutrients double-counts mass.
  2. An absent aggregate does not mean all components are absent.
  3. Different polyols can have different energy treatment; erythritol remains separate in the proposal.
  4. A derived energy mismatch can be a calculation defect, not bad producer data.
  5. Any downstream threshold, ranking, or badge inherits the wrong derivation.

A quality system should retain both the declared energy and computed energy, then explain the comparison. It should not overwrite one with the other or attach an unexplained invalid_nutrition flag. Useful states include matches_within_tolerance, mismatch, not_computable, and derivation_incomplete, with the calculation rule and inputs attached.

A national database expands coverage, not automatic eligibility

The Saudi launch is important for recipe products because local dishes are often badly represented by foreign generic tables. Better national reference coverage can improve ingredient matching, menu analysis, meal planning, research exports, and culturally relevant search.

But a composition value and a front-of-pack model input answer different questions. The former estimates what a food contains under a defined record and preparation state. The latter classifies a subject under an algorithm with applicability rules.

The Nature review's supplementary material makes this concrete. Models distinguish solids from liquids, apply to different packaged-food classes, and contain exclusions for categories such as unprocessed foods, culinary ingredients, supplements, small packages, or protected traditional products. It also lists a Saudi traffic-light model alongside models from other jurisdictions. Feeding every Saudi composition record into that model would still be wrong: a traditional dish reference row is not necessarily a packaged product subject to front-of-pack labelling.

Keep at least these identities separate:

  • food_reference_id: a composition record;
  • recipe_revision_id: ingredients, quantities, yield, and preparation;
  • product_id: a market-specific packaged item;
  • nutrition_observation_set_id: the values and evidence being evaluated;
  • profile_model_id: algorithm, version, jurisdiction, and intended purpose.

Put an eligibility gate before scoring

A dependable profile service should decide whether it can evaluate before it computes a colour, warning, endorsement, or score.

{
  "subject": {"type": "packaged_product", "id": "sku_8472", "market": "SA"},
  "observationSet": "nutrition_set_921@3",
  "model": "sa-traffic-light@effective-version",
  "eligibility": {
    "status": "unknown",
    "checks": [
      {"name": "subject_type", "status": "pass"},
      {"name": "solid_or_liquid", "status": "pass", "value": "solid"},
      {"name": "required_basis", "status": "pass", "value": "per_100_g"},
      {"name": "sugar_definition", "status": "unknown", "reason": "only total sugar is available"},
      {"name": "category_exclusion", "status": "pass"}
    ]
  },
  "result": null
}

The exact checks vary by model. Common gates include:

  • correct subject type and market;
  • effective date and model version;
  • solid, liquid, or prepared state;
  • per-100-gram, per-100-millilitre, or per-serving basis;
  • compatible sugar, sodium, salt, fat, and energy definitions;
  • required food category and exclusions;
  • minimum nutrient completeness;
  • acceptable evidence types;
  • valid unit conversions and component hierarchies.

Return not_applicable when the model excludes the subject and unknown when evidence is insufficient. Neither should be coerced to pass.

Operational failure modes to test

Aggregate plus components. Test records with polyols and individual polyols together. Define whether the aggregate wins, components validate it, or disagreement blocks calculation.

Missing versus zero. A missing saturated-fat value cannot safely become zero merely because a scoring function expects a number.

Salt versus sodium. Record the conversion rule and avoid applying it twice when both fields are present.

As sold versus prepared. Powder, concentrate, and prepared beverage can cross different thresholds. The state must travel with the value.

Recipe versus product. A meal-planning estimate may be useful but ineligible for a packaged-product label claim.

Profile cascades. Recompute dependent scores when a nutrient derivation changes, but preserve the old input manifest so historical results remain explainable.

False data-quality alerts. Separate source inconsistency from calculation-engine failure. A warning should identify which comparison and rule generated it.

Release checklist for builders and buyers

Before connecting composition data to a nutrient-profile endpoint, ask:

  • Does each nutrient retain unit, basis, preparation state, evidence type, and source?
  • Can the system represent aggregate nutrients and their components without double-counting?
  • Are declared, analysed, calculated, and imputed values distinguishable?
  • Does every calculated value expose its inputs and rule version?
  • Can a profile model specify accepted nutrient definitions and evidence types?
  • Is applicability checked before thresholds run?
  • Are unknown and not_applicable first-class outcomes?
  • Can a national reference food, recipe, and packaged SKU remain separate subjects?
  • Do regression fixtures cover missing aggregates, partial components, and conflicting totals?
  • Can one derivation change trigger targeted re-evaluation of affected scores and badges?

The Saudi database creates valuable new regional evidence. The polyol fix shows how easily evidence can be mistranslated inside a calculation. The systematic review shows how many different algorithms may consume the result. The robust product is the boundary between them: typed nutrient observations, explicit derivations, model eligibility, and an input manifest that lets a developer explain every badge before displaying it.

Sources

Start Building

One consistent schema on every response. Get a free key and ship in minutes.