Cold, Frozen, or Ambient? Model Storage State as a Computed Food Claim
Fresh Open Food Facts and Ecobalyse integration work shows why recipe and grocery APIs should separate inferred storage class from product instructions, observed handling, lifecycle stage, and environmental-calculation inputs.
A three-value field opens a larger modeling problem
On August 13, Open Food Facts merged a new storage_conditions field with three controlled values: ambient, refrigerated, and frozen. The field is computed from inherited product-category properties and was added for environmental-impact calculations through the French Ecobalyse API. Open Food Facts Server 2.102.0 included it in the release published the following day.
The implementation is deliberately practical. Canned foods inherit ambient storage, frozen foods inherit frozen storage, and refrigerated foods inherit refrigerated storage. Tests also preserve a distinct result when no category supplies a value. The pull request is equally clear that coverage is only a starting point: many apparently frozen categories still needed suitable properties or parents.
A related Ecobalyse integration change merged on August 12. It added API-token handling, updated external Ecobalyse identifiers, and introduced the three-value storage taxonomy before the computed field landed. Together, the changes show storage moving from descriptive catalog text into a machine-consumed calculation input.
This blog has already covered ingredient form, external-ID crosswalks, sustainability provenance, and missing-value fallbacks. The repeated angle to avoid is simply saying “version another taxonomy field.” The more useful thesis is this: storage state should be a scoped, evidence-backed claim that may differ across a generic food, packaged SKU, retail offer, recipe input, and user storage event; category inheritance is a useful fallback, but not a universal fact about the food.
Source map
Fresh primary evidence from the last seven days:
| Source | Date | Contribution |
|---|---|---|
| Open Food Facts storage-conditions pull request | 2026-08-13 | Adds computed ambient, refrigerated, and frozen tags; derives them from category properties; identifies incomplete taxonomy coverage and explicit produce defaults. |
| Open Food Facts Ecobalyse integration fix | 2026-08-12 | Adds the initial storage taxonomy, authenticated API integration, and corrected external ingredient identifiers. |
| Open Food Facts Server 2.102.0 release | 2026-08-14 | Publishes the storage field and Ecobalyse fixes together as a released server contract. |
Older background context is limited to the Ecobalyse service itself and earlier Recipe API articles about environmental evidence. The new information surplus here is the lifecycle model: environmental calculators, grocery fulfillment, pantry tools, and meal planners can all use “frozen,” but they do not necessarily mean the same assertion.
Storage is not an ingredient property
A bag of peas can be sold frozen, canned, or fresh. Garlic can be ambient as a bulb, refrigerated as prepared paste, or frozen after chopping. A shelf-stable carton may require refrigeration after opening. A frozen product becomes a thawed recipe input without changing its underlying food identity.
Putting storage: "frozen" on a canonical ingredient therefore creates the same category error as putting one grocery SKU or nutrition record on every form of garlic. The condition usually belongs to a more specific object and stage:
| Scope | Question answered | Example evidence |
|---|---|---|
| Generic ingredient | What fallback is typical for this food form? | Reviewed taxonomy policy |
| Packaged product | What does the unopened package require? | Manufacturer or label instruction |
| Retail offer | How is this specific offer fulfilled? | Frozen-aisle catalog or warehouse data |
| Recipe ingredient | In what state should the cook receive or use it? | “Frozen peas” or “butter, softened” |
| User inventory event | Where is this item now? | Scan, manual entry, or device observation |
| Calculation scenario | Which storage assumption did a model consume? | Environmental-method input record |
These rows can disagree without any one of them being wrong. The API should preserve the disagreement rather than overwrite all scopes with the strongest-looking value.
Category inheritance is a fallback with boundaries
The fresh Open Food Facts work exposes both the power and the risk of inheritance. One property on frozen foods can cover many descendants. One property on canned foods can classify shelf-stable products without editing every can. That is efficient, queryable, and suitable for bootstrapping an environmental calculation.
But the taxonomy diff also documents exceptions. Fresh fruit is defaulted to ambient while noting that storage varies by store, home, country, season, and variety. Fresh vegetables default to refrigerated, with overrides for potatoes, onions, and fresh tomatoes. Frozen onions and frozen potatoes then need more specific overrides so an ambient ancestor does not win.
Those examples imply four API rules:
- Return the category path and property that supplied an inherited value.
- Prefer more specific reviewed evidence over a broad ancestor.
- Preserve
unknownwhen no applicable rule exists; never translate missing into ambient. - Detect conflicting category paths instead of relying on array order.
A category name containing “frozen” is not enough. “Frozen” may describe a manufacturing process, a recipe preparation, or a commercial storage state. The same pull request corrects wording about Eisbock being partially frozen during production; that does not make finished beer a frozen retail product. String rules will eventually confuse process with handling.
Represent claims, not one mutable scalar
A compact public response can still expose one selected state, but the internal model should keep candidate claims and the policy that selected among them.
{
"subject": { "type": "product", "id": "gtin:example" },
"storageAssessment": {
"selectedState": "refrigerated",
"lifecycleStage": "unopened_retail",
"selectionPolicy": "storage-policy-2026-08",
"claims": [
{
"state": "refrigerated",
"claimType": "category_inference",
"appliesAt": "unopened_retail",
"derivedFrom": {
"categoryId": "food:refrigerated-foods",
"taxonomyVersion": "2026-08-13"
},
"confidence": "reviewed_fallback"
}
],
"status": "inferred",
"computedAt": "2026-08-14T00:00:00Z"
}
}
A richer record should support at least these claim types:
declared_instruction: package or supplier says how the item must be stored;observed_condition: retailer, warehouse, user, or sensor reports current handling;category_inference: a taxonomy supplies a default;recipe_requirement: source text specifies frozen, chilled, softened, or room-temperature use;scenario_assumption: a calculator requires a modeled state;transition_event: opened, frozen, thawed, cooked, delivered, or moved.
state, claimType, and lifecycleStage solve different problems. A category inference can be perfectly valid for an environmental scenario while remaining insufficient for a consumer safety instruction. A recipe requirement can guide preparation while saying nothing about how a grocery order must travel.
Keep calculation inputs reproducible
Ecobalyse is the immediate reason the new field exists, which makes reproducibility important. If a category edit changes a product from unknown to refrigerated, an environmental result may change even though the ingredients and package did not. An API returning only the final score cannot explain that movement.
Store the selected storage claim with every calculation:
{
"calculationId": "impact_784",
"method": "ecobalyse",
"inputStorageState": "refrigerated",
"storageClaimId": "storage_claim_312",
"storageSelectionPolicy": "storage-policy-2026-08",
"externalMappingsVersion": "2026-08-12",
"status": "estimated_with_category_fallback"
}
The external-mapping version matters too. The August 12 integration changed Ecobalyse IDs for ingredients such as sugar and added a garlic mapping across many expected outputs. Authentication changed at the integration boundary as well. A robust adapter pins input mappings, storage assumptions, endpoint or method version, and response time. That lets operators distinguish taxonomy drift from external-ID correction, API behavior, or an actual product edit.
Do not reuse the environmental result as a fulfillment instruction. “Modeled as refrigerated” is not equivalent to “ship at this temperature,” just as an ingredient proxy is not a product label.
Product behavior should use the right claim
Grocery substitution: replacing canned peas with frozen peas is not only an ingredient substitution. It can change package size, fulfillment availability, cold-chain requirements, freezer capacity, preparation steps, and environmental inputs. Re-run the affected rules after the SKU is selected.
Meal planning: a recipe calling for frozen berries may accept fresh berries, but the substitution can change thawing time, texture, quantity loss, and shopping behavior. Preserve the recipe’s requested state separately from the chosen product’s retail state.
Pantry and leftovers: category defaults are poor evidence for opened products and cooked leftovers. These objects need event history and applicable guidance, not inheritance from the original retail category.
Search and recommendations: filter=freezer_items should specify whether it means products sold frozen, recipes requiring frozen inputs, or items currently recorded in the user’s freezer. One ambiguous filter can produce three different result sets.
Food AI: generated recipes should not invent storage claims from culinary plausibility. Treat “use frozen spinach” as a generated recipe requirement, not evidence that a matched grocery SKU is sold or safely stored frozen.
Validation checklist
Before making storage state queryable or feeding it into a calculation, verify that the API can:
- distinguish declared, observed, inferred, recipe-required, and scenario-assumed states;
- attach storage to a food form, SKU, offer, inventory item, or calculation rather than only an ingredient ID;
- identify lifecycle stage, including unopened, opened, prepared, and thawed contexts;
- return the category and taxonomy version behind inherited values;
- preserve unknown separately from ambient;
- resolve specific overrides ahead of broad ancestor defaults;
- report conflicts when multiple categories imply different states;
- keep manufacturing processes separate from retail storage conditions;
- pin the selected claim to environmental and cost calculations;
- re-evaluate substitutions, carts, and cached scores when storage evidence changes;
- prevent model assumptions from being displayed as package or safety instructions;
- expose enough detail for a buyer to test canned, chilled, frozen, fresh-produce, and after-opening cases.
A three-value vocabulary is a useful interoperability layer. The mistake would be treating those values as timeless facts about foods. For recipe and grocery APIs, storage becomes dependable only when the service says whose state, at which stage, according to what evidence, selected for which decision.
Sources
- Open Food Facts, feat: new storage_conditions tags field based on categories, needed for Ecobalyse, merged August 13, 2026.
- Open Food Facts, fix: Ecobalyse integration, update a few IDs, add token header, merged August 12, 2026.
- Open Food Facts Server, release 2.102.0, released August 14, 2026.
- Ecobalyse, official environmental-impact calculation service, background context.
Start Building
One consistent schema on every response. Get a free key and ship in minutes.