Unwanted Ingredients Need More Than a Boolean Filter
Open Food Facts' new unwanted-ingredients attribute and USDA ingredient additions show why recipe APIs should model avoidance, ingredient identity, and statistics as versioned data rather than simple exclude keywords.
Why this trend matters now
Personalization is usually described as adding more preferences: favorite cuisines, target calories, protein goals, budget, cooking time, preferred stores. The harder half is exclusion. A meal planner must also know what a user does not want: pork, alcohol, ultra-processed additives, palm oil, artificial sweeteners, allergens, disliked vegetables, non-vegan processing aids, or ingredients that conflict with a medical or cultural constraint.
Two Open Food Facts changes merged on July 7, 2026 make this worth treating as a product-infrastructure problem, not a UI checkbox. First, Open Food Facts enabled the unwanted_ingredients attribute for Open Products Facts and Open Products Facts France by adding the ingredients_analysis attribute group to those configurations. The pull request notes that /api/v3.4/attribute_groups now returns the ingredients_analysis group with the unwanted_ingredients attribute for those product domains. Second, the project continued adding USDA ingredients to its taxonomy, expanding the reference vocabulary available for ingredient recognition and matching.
A third same-day change points to the analytics side of the problem: Open Food Facts added JSON generation for product statistics so clients can reuse product-completeness time series without parsing HTML. That is not specifically an unwanted-ingredients feature, but it is the same architectural direction: food-data systems are exposing machine-readable metadata about coverage, completeness, and derived attributes.
For recipe, nutrition, grocery, and food-AI products, the lesson is clear. Avoidance should not be implemented as WHERE ingredient_text NOT LIKE '%pork%'. It needs stable ingredient entities, rule provenance, versioned taxonomies, confidence, explainability, and enough statistics to know where the system is blind.
The product failure mode: exclusion feels binary, data is not
Users experience avoidance as a yes/no outcome: "Do not show me recipes with sesame." Developers experience it as messy data:
- recipe ingredients are free text;
- product ingredients may include additives, processing aids, sub-ingredients, and translations;
- the same concept may appear as a commodity, brand term, E-number, compound ingredient, or regional name;
- substitutions can introduce a blocked ingredient after the original recipe passed;
- missing ingredient data is different from a clean negative result;
- some rules are personal dislike, some are health constraints, and some are legal or religious requirements.
That means the most dangerous response shape is a bare boolean:
{
"containsUnwantedIngredients": false
}
It hides whether the system found no blocked ingredients, lacked enough ingredient data, failed to normalize the ingredient phrase, used an outdated vocabulary, or applied a rule that does not match the user's actual constraint. In consumer recipe search, that may produce a bad recommendation. In allergy-adjacent workflows, it can produce a safety issue.
A better recipe API treats unwanted ingredients as a derived, explainable analysis over structured ingredient data.
A practical schema sketch
The exact names will differ by product, but the model should separate user intent, ingredient identity, evidence, and decision output.
{
"recipeId": "r_123",
"ingredientAnalysis": {
"taxonomyVersion": "ingredients-2026-07-07",
"analyzedAt": "2026-07-07T14:30:00Z",
"coverage": {
"ingredientLines": 12,
"normalizedLines": 11,
"unresolvedLines": 1
},
"unwantedIngredients": {
"status": "match",
"severity": "exclude",
"matches": [
{
"userRuleId": "avoid_sesame",
"matchedEntityId": "ingredient:sesame-seeds",
"matchedName": "sesame seeds",
"sourceLine": "2 tbsp toasted sesame seeds",
"matchType": "direct",
"confidence": 0.99,
"evidence": "normalized_ingredient"
}
],
"unknowns": [
{
"sourceLine": "1 tbsp house seasoning blend",
"reason": "compound_ingredient_without_subingredients"
}
]
}
}
}
The important part is not the JSON shape. It is the contract: the API distinguishes match, no_match, unknown, and not_analyzed; it returns evidence; it exposes taxonomy version; and it allows clients to decide whether unknowns should block recommendations.
Decision framework for recipe and grocery APIs
| Question | Weak implementation | Production-grade implementation |
|---|---|---|
| What is the user avoiding? | A list of strings | User rules mapped to ingredient entities, categories, additives, and aliases |
| What data was analyzed? | Raw recipe text | Normalized ingredient lines, product ingredients, substitutions, and grocery SKUs |
| What does a pass mean? | No keyword matched | No matched rule within analyzed coverage, with unknowns reported separately |
| How is a match explained? | Hidden filter logic | Source line, matched entity, match type, confidence, and rule ID |
| How is drift handled? | Static denylist | Versioned taxonomy, changelog, reanalysis queue, and backwards-compatible responses |
| How are analytics handled? | Aggregate recipe counts only | Coverage and failure-rate statistics by cuisine, locale, supplier, and ingestion source |
This framework matters because unwanted-ingredient features quickly cross product boundaries. A recipe app may start with "hide recipes with mushrooms." Then it adds grocery checkout, where the actual product substitution contains mushroom powder. Then it adds nutrition coaching, where a clinician wants stricter treatment of unresolved compound ingredients. Then it adds AI recipe generation, where the model must be constrained before generation and audited after generation.
API implications
1. Model avoidance as rules, not tags
A tag such as sesame-free is convenient for browsing, but it is too blunt for API consumers. Store the user's avoidance intent as rules that can target multiple entity types:
- ingredient entity: sesame seeds;
- ingredient category: tree nuts;
- additive: a specific E-number or additive class;
- processing or label claim: alcohol, animal-derived, contains palm oil;
- product property: brand, store department, certification, or country-specific label.
Rules should have reason and strictness fields. A dislike can tolerate uncertain results; an allergy or medical restriction often cannot. The same data can support both experiences if the decision layer understands strictness.
2. Return uncertainty as a first-class result
The correct answer is often not true or false; it is unknown. Unknowns occur when a recipe has vague ingredient lines such as "seasoning mix," when a grocery product lacks ingredients, when OCR confidence is low, or when the parser recognizes a compound ingredient but not its sub-ingredients.
APIs should expose this directly:
{
"status": "unknown",
"reason": "insufficient_ingredient_detail",
"blockingUnknowns": true
}
That lets a consumer app choose different UX for different contexts: show a warning for casual search, hide the item for strict meal plans, or request a human review for enterprise nutrition workflows.
3. Keep taxonomy and analysis versions visible
The July 7 USDA ingredient additions are a reminder that ingredient vocabularies are living systems. If a taxonomy update adds a new synonym or ingredient node, yesterday's "safe" recipe may need to be rechecked. API responses should include a taxonomy version or release date, and platforms should maintain a queue for reanalysis after material taxonomy changes.
For downstream customers, version visibility prevents confusing diffs. If a recipe starts failing a filter, the customer can see whether the ingredient text changed, the user rule changed, or the taxonomy changed.
4. Separate recipe-level and purchasable-product analysis
Recipe ingredients and grocery products have related but different failure modes. A recipe line may say "soy sauce"; the purchasable product may include wheat. A recipe line may pass, but a store substitution may not. If a meal-planning API powers shopping lists, it should analyze avoidance at three levels:
- canonical recipe ingredient;
- selected grocery product or SKU;
- substitution candidate.
The response should not collapse those into one answer. A useful API can say: "The recipe ingredient is acceptable, the selected product conflicts, and two alternative SKUs are compatible."
5. Publish coverage metrics, not just features
The Open Food Facts move toward JSON product statistics is relevant because personalization quality depends on coverage. A vendor that claims unwanted-ingredient filtering should be able to report operational metrics: normalized ingredient coverage, unresolved compound-ingredient rate, locale coverage, product ingredient availability, and reanalysis lag after taxonomy updates.
These metrics help technical buyers evaluate whether an API will work for their catalog, not just whether it supports a checkbox in a demo.
Checklist for adding unwanted-ingredient support
Before shipping an exclusion feature, ask:
- Can every user rule be traced to one or more stable ingredient, additive, category, or label identifiers?
- Does the API distinguish direct matches, category matches, inferred matches, and unknowns?
- Are raw ingredient lines preserved for audit and customer support?
- Is every derived result tied to parser, model, and taxonomy versions?
- Can strict users block unknowns while casual users merely see warnings?
- Are grocery substitutions rechecked independently from the recipe?
- Do analytics show coverage and false-positive review rates by source and locale?
- Is there a reprocessing plan when the ingredient taxonomy changes?
If the answer to any of these is no, the product may still be useful, but the API contract should avoid overclaiming safety or completeness.
Where Recipe API fits
For builders, the opportunity is not to copy Open Food Facts' exact attributes. It is to design recipe data so these attributes can exist. Recipe API customers need normalized ingredient entities, serving-aware quantities, nutrition context, grocery mappings, and reliable search filters. Unwanted-ingredient handling sits on top of all of those layers.
A robust Recipe API integration should let a product manager ask, "Can we hide recipes that contain this user's avoided ingredients?" and let an engineer answer, "Yes, with explainable matches, versioned data, and a clear unknown state." That is much stronger than returning a recipe list that silently lost or included items because a keyword happened to match.
The near-term trend is small but important: food-data platforms are exposing more machine-readable ingredient analysis, vocabulary expansion, and statistics. The practical response is to make avoidance explainable before personalization, grocery checkout, and AI generation all depend on it.
Sources
- Open Food Facts pull request, "feat: enable unwanted ingredients attribute for OPF and OPFF," merged July 7, 2026: https://github.com/openfoodfacts/openfoodfacts-server/pull/13933
- Open Food Facts commit, "chore: Add USDA ingredients - part 7," merged July 7, 2026: https://github.com/openfoodfacts/openfoodfacts-server/commit/26108395553ce3c5f3c6635c73542973befaecdd
- Open Food Facts pull request, "feat: generate JSON files for product statistics," merged July 7, 2026: https://github.com/openfoodfacts/openfoodfacts-server/pull/13929
Start Building
One consistent schema on every response. Get a free key and ship in minutes.