Skip to content
Recipe API

External Food IDs Are Crosswalks, Not Ingredient Properties

Fresh Open Food Facts taxonomy changes show why nutrition, grocery, and recipe APIs should model external food identifiers as typed, versioned mapping assertions rather than permanent fields on one canonical ingredient.

ingredientsnutritiongroceryapi-designdata-modeling

One garlic, several incompatible meanings

A normalized ingredient record often accumulates external IDs like this:

{
  "id": "ingredient:garlic",
  "usdaId": "...",
  "ciqualId": "11000",
  "gpcId": "10006003",
  "wikidataId": "Q23400"
}

It looks useful: resolve garlic once, then join nutrition, commerce, taxonomy, and knowledge-graph data through a few fields. Fresh Open Food Facts changes show why that model is too optimistic.

On August 11, a garlic taxonomy change moved a Global Product Classification mapping from the broad “Garlics” concept to “Fresh garlics.” At the same time, the broad garlic entry retained an Agribalyse proxy and gained a Ciqual proxy, while the fresh-garlic child kept exact Ciqual and Agribalyse food codes. The edit encodes a real distinction: a merchandising classification for fresh commercial garlic does not necessarily belong on every garlic-derived food, while a generic ingredient may still use a nutrition or environmental proxy.

On August 12, a wasabi and horseradish change documented another boundary. Its taxonomy comments distinguish a Wikidata item about the wasabi plant from an item about wasabi as a culinary ingredient. The same change adds horseradish oil under both horseradish and vegetable oil, and expands a wasabi-paste category. A botanical identity, recipe ingredient, processed oil, and purchasable condiment are related, but they are not interchangeable records.

Also on August 12, the nineteenth installment of Open Food Facts’ USDA ingredient work changed hundreds of taxonomy lines and updated expected outputs across ingredient parsing, allergens, environmental scoring, and recipe tests. That is useful evidence of blast radius: adding or correcting reference mappings is not isolated metadata maintenance. It can change the structured outputs consumed by several product surfaces.

The thesis: external food IDs should be represented as typed, versioned crosswalk assertions with entity scope, match relation, food state, intended use, and evidence. Storing them as permanent scalar properties on one universal ingredient invites false joins precisely because nutrition, grocery, recipe, botanical, and knowledge-graph datasets partition food differently.

Source map and the angle this article avoids

Fresh primary evidence from the last seven days:

Source Date Contribution
Open Food Facts garlic and garlic-paste taxonomy change 2026-08-11 Moves the GPC classification to fresh garlic, adds a Ciqual proxy to broad garlic, and keeps exact food-table codes on the fresh-food child.
Open Food Facts wasabi and horseradish taxonomy change 2026-08-12 Distinguishes plant and culinary Wikidata concepts while adding processed forms and category translations.
Open Food Facts USDA ingredient integration, part 19 2026-08-12 Shows the scale and downstream test impact of maintaining food-reference mappings.

Older posts on this blog have already argued that taxonomies drift, reference datasets need provenance, ingredient form matters, and metadata extensions need contracts. The repeated angle to avoid is merely saying “version your taxonomy.” The narrower problem here is join semantics: even with stable internal IDs and perfect version history, which external record is valid for which computation?

Every external dataset partitions food for a purpose

A recipe platform wants one stable ingredient identity because users expect “garlic” to work across search, grocery lists, and substitutions. External systems do not owe it the same boundaries.

  • A food-composition table distinguishes records when preparation, edible portion, or measured nutrient values differ.
  • A grocery classification may distinguish fresh produce, shelf-stable paste, frozen chopped garlic, and powder because package and merchandising behavior differ.
  • A botanical knowledge graph may identify a plant species rather than an edible ingredient or commercial product.
  • An environmental dataset may offer a broad proxy suitable for estimation but not an exact food match.
  • A recipe taxonomy may preserve culinary equivalence while still separating forms that cook, scale, or substitute differently.

This means “same ingredient” is not a universal relation. It is shorthand for a relation under a use case.

Consider a recipe line containing 2 tsp garlic paste. Mapping it to the broad garlic entity can improve search recall. Mapping it to fresh garlic for grocery fulfillment may return bulbs instead of a jar. Applying fresh-garlic nutrition without accounting for oil, salt, acid, or other paste ingredients can distort sodium and calories. Mapping it directly to the garlic plant’s knowledge-graph item can attach botanical facts while missing the culinary product concept.

A scalar external ID cannot express those boundaries. At best, clients guess from field names. At worst, the first successful join becomes an apparently authoritative fact everywhere.

Model a crosswalk as an assertion

A crosswalk should be its own object, not an incidental column on ingredient. A practical shape might look like this:

{
  "mappingId": "map_garlic_ciqual_11000_2026_08",
  "sourceEntity": {
    "system": "recipe-api",
    "id": "ingredient:garlic",
    "state": "unspecified"
  },
  "targetEntity": {
    "system": "ciqual",
    "id": "11000",
    "label": "Garlic, fresh"
  },
  "relation": "proxy_for",
  "scope": {
    "allowedUses": ["nutrition_estimate"],
    "disallowedUses": ["exact_label_claim", "grocery_sku_match"],
    "market": null,
    "preparationState": "fresh"
  },
  "evidence": {
    "source": "reviewed_taxonomy_mapping",
    "sourceUrl": "https://github.com/openfoodfacts/openfoodfacts-server/pull/14252",
    "confidence": "reviewed"
  },
  "validity": {
    "taxonomyVersion": "2026-08-11",
    "validFrom": "2026-08-11",
    "validTo": null,
    "supersedes": null
  }
}

The exact vocabulary can vary, but five fields should survive any implementation:

  1. Source and target entity types. An ingredient-to-reference-food edge is different from a product-to-category edge.
  2. Relation. Use values such as exact_match, narrower_than, broader_than, proxy_for, derived_from, and not_equivalent.
  3. State and scope. Record fresh, dried, cooked, paste, oil, powder, or unknown, plus the allowed downstream uses.
  4. Evidence and review state. Preserve who or what made the mapping and whether it was reviewed.
  5. Validity. Make corrections appendable and reproducible instead of silently replacing yesterday’s join.

not_equivalent is especially valuable. The wasabi example shows that two IDs may be close enough to confuse but refer to different entity types. A negative assertion can stop a future enrichment job from reintroducing a known-bad mapping.

Exact, proxy, and category matches require different behavior

A useful API should not collapse all successful crosswalks into matched: true.

Mapping relation Appropriate use Unsafe shortcut
exact_match Reproducible lookup when food form, basis, and entity type agree Assuming exactness survives a source-version change
proxy_for Approximate nutrition or environmental estimates with disclosure Presenting the result as measured for the recipe ingredient
broader_than Search expansion and fallback discovery Using a family-level record for allergens or precise nutrients
narrower_than Candidate matching and subtype navigation Generalizing subtype properties to every parent member
derived_from Lineage, substitution review, and ingredient explanation Treating processed derivatives as nutritionally or commercially identical
related_only Knowledge panels and semantic discovery Joining operational data such as prices or nutrient values

The garlic change demonstrates why intended use belongs on the edge. A GPC mapping can support product classification and retail workflows. A Ciqual mapping can support nutrition lookup. A Wikidata mapping can support multilingual knowledge and entity links. Returning all three as equivalent externalIds lets a client accidentally use a merchandising category as a nutrition record or a botanical entity as a purchasable food.

For Recipe API consumers, a safer endpoint would allow purpose-aware resolution:

GET /v1/ingredients/garlic/crosswalks?purpose=nutrition&state=fresh
GET /v1/ingredients/garlic/crosswalks?purpose=grocery&form=paste

The response should rank candidate mappings, not manufacture certainty when no exact edge exists.

Corrections must trigger bounded recomputation

Crosswalk maintenance has operational consequences. The USDA taxonomy change updated fixtures for ingredient parsing, allergens, environmental scoring, and recipe outputs. A platform that changes a mapping should know which derived records depend on it.

Do not invalidate every garlic recipe after every alias edit. Build a dependency index keyed by mapping ID and use case. A changed nutrition proxy should enqueue nutrition recomputation for records that actually used that edge. Moving a grocery category should reindex product matches and facets, not rewrite historic nutrient totals. Correcting a knowledge-graph link may refresh descriptions without touching carts.

Store the selected mapping on every derived result:

{
  "nutrientEstimateId": "nut_784",
  "ingredientId": "ingredient:garlic",
  "mappingId": "map_garlic_ciqual_11000_2026_08",
  "mappingRelation": "proxy_for",
  "computedAt": "2026-08-12T12:00:00Z"
}

That field makes impact analysis possible. It also lets support explain why nutrition changed even though the recipe text did not.

Edge cases worth testing

Composite products. Garlic paste may contain ingredients beyond garlic. A category match should not substitute for an ingredient-level composition record.

Common names across entity types. Wasabi can refer to the plant, root ingredient, paste category, flavor, or commercial product. Require target entity type in every mapping.

One-to-many mappings. A generic recipe ingredient may legitimately have several candidate nutrition records split by preparation or geography. The crosswalk service should return candidates and selection rationale.

Many-to-one mappings. Several culinary aliases may resolve to one ingredient for search while retaining distinct grocery forms. Do not let deduplication erase form state.

Source retirement and reuse. External IDs can be deprecated, merged, or reinterpreted. Preserve source version and validity windows.

Proxy chains. Ingredient A may map to category B, which maps to reference food C. Return the complete path and cap chain length; otherwise uncertainty disappears at each hop.

Crosswalk validation checklist

Before using external food IDs in production, verify that the system can:

  • distinguish recipe ingredients, reference foods, plants, categories, commercial products, and package SKUs;
  • represent exact, proxy, broader, narrower, derived, related, and explicitly non-equivalent relationships;
  • attach preparation state, market, and intended use to each mapping;
  • keep original source IDs and labels when a target is deprecated;
  • show the mapping selected for every nutrition, sustainability, grocery, or search result;
  • recompute only the derived outputs that consumed a changed edge;
  • prevent search-oriented mappings from becoming safety or nutrition assertions;
  • return multiple candidates when one universal mapping would be false precision;
  • expose mapping version, evidence, review status, and confidence;
  • test plant-versus-food, fresh-versus-processed, and generic-versus-branded boundaries.

A recipe API still benefits from stable canonical ingredient IDs. The mistake is expecting those IDs to flatten every external dataset into the same ontology. This week’s taxonomy work shows the more durable design: keep the internal ingredient stable, but make every outbound join an explicit, purpose-bound assertion. That is what lets nutrition estimates, grocery matches, recipe search, and food knowledge improve independently without quietly borrowing one another’s meaning.

Sources

Start Building

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