Keep one record for every claim you make about a product. Each record ties the claim to the exact variant it belongs to, gives the value and unit, says the condition and scope it holds under, and says whether it affirms something or rules something out. It names the document the claim came from, says when you last checked it, and lists every place the claim has been copied, with a note on whether each copy still matches. If you don’t know a value, the record says “unknown” and gives the reason.

This is our proposed format for your own files. It isn’t an industry protocol, no platform reads it, and we haven’t measured any effect on picks or rank. What it does is let you catch the wrong copies, and the examples below are real catalog records where copies went wrong.

Why a product claim needs a contract

A spec sheet says one thing. By the time it reaches a shopper it has been copied into your description, your admin fields, a feed, a catalog record and an assistant’s summary. Our product-data guide walks through that chain. This page is about the record that keeps all those copies honest.

Here is what went wrong in the copies we saw. In a Shopify agent-catalog search on October 26, 2026:

What the description said What Shopify’s generated list said What broke
Runtime “up to 32 hours” “Up to 36 hours” The value changed
Hood insulation “rated to -30°C” “Insulation: [material] rated to -30°C” The scope was dropped
“Depth: 2.4lbs” “Depth 2.4 in” The unit changed, and probably the attribute too
A “4-inch mist outlet” “Mist Output: 4 inches (10.16 cm)” A size became a performance figure

The first three are in our published receipts. The fourth is new on this page and explained in how we checked. Shopify says these generated lists, and the description too, are marked Inferred: generated or enriched by Shopify and possibly inaccurate. We can’t see what Shopify generated them from, so none of this proves an error in Shopify’s process. It proves that “it’s on my page” and “that’s what the catalog sent” are different claims.

Each of these breaks maps to one field in a claim record: the value, the scope, the unit, or the attribute itself. If you keep those fields, plus where each copy lives, you can check any copy in a minute.

The proposed claim record

One claim per record. A claim is one checkable statement: “runtime is up to 32 hours on a full 4 L tank”, not “long-lasting and quiet”. Here is a filled-in example for one humidifier variant. Square brackets mark what only the merchant knows. The published copies are what we actually saw in the catalog.

{
  "claim_id": "humidifier-4l-white/runtime-max",
  "product_id": "[your product ID]",
  "variant_id": "[your variant ID for 4 L, white]",
  "applies_to": "variant",
  "attribute": "runtime_per_fill",
  "polarity": "affirms",
  "value": 32,
  "unit": "h",
  "qualifier": "up_to",
  "conditions": {
    "mist_setting": null,
    "tank": "full 4 L tank"
  },
  "condition_status": "incomplete",
  "condition_note": "mist setting not stated in the source",
  "scope": "whole unit",
  "state": "stated",
  "evidence": {
    "type": "[own_test | manufacturer_test | manufacturer_spec | seller_statement]",
    "document": "[spec sheet or test report title]",
    "locator": "[page, table or section]",
    "issued": "[document date]"
  },
  "checked_at": "[date someone confirmed the source]",
  "published_copies": [
    {
      "surface": "product description",
      "text": "up to 32 hours",
      "matches": true,
      "seen": "2026-10-26"
    },
    {
      "surface": "Shopify generated spec list (Inferred)",
      "text": "Runtime: Up to 36 hours",
      "matches": false,
      "seen": "2026-10-26"
    }
  ],
  "open_issue": "generated copy says 36 h; source says 32 h",
  "recheck": "on any product, listing or feed change"
}

What each part is for:

Field What it holds Why it’s there
product_id, variant_id, applies_to The exact item the claim describes Catalogs evaluate a specific variant, and offers from several sellers can sit under one product. A claim on the wrong variant travels with the wrong offer
attribute, value, unit, qualifier One measurable statement: “up to 32 h” Catches unit swaps (2.4 lb into 2.4 in) and attribute swaps (outlet size into mist output)
conditions, condition_status Setting, distance, temperature, load “32 hours” on low and “32 hours” on high are different products for the shopper
scope Which part of the product the claim covers “Hood insulation rated to -30°C” isn’t “suit rated to -30°C”
polarity affirms or excludes “No filter to replace” and “not for rooms over 400 sq ft” are claims too
state stated, unknown, conflicting or not_applicable Keeps “we checked and the source is silent” apart from “nobody looked”
evidence Type, document, locator and date Lets anyone trace the claim to something they can open
checked_at, recheck When it was confirmed, and what triggers another look A claim with no date is a claim nobody can vouch for today
published_copies Every place the claim appears, its exact text, and whether it matches This is the part that catches drift

Two design choices matter more than the rest.

State describes the source, while matches describes the copies. If your spec sheet and your test report disagree, the claim’s state is conflicting, and you fix that at the source. If your source says 32 hours and a catalog copy says 36, the claim is still stated. The copy is wrong, and you fix the copy, or the field the copy was generated from.

Unknown is a value with a reason, never a blank. Here is the same variant’s room coverage, which its description didn’t state:

{
  "claim_id": "humidifier-4l-white/room-coverage",
  "variant_id": "[your variant ID for 4 L, white]",
  "attribute": "room_coverage",
  "polarity": "affirms",
  "value": null,
  "unit": "sq_ft",
  "state": "unknown",
  "unknown_reason": "[not tested | manufacturer does not state | varies by setting]",
  "published_copies": []
}

Blanks get misread everywhere. Across all 162 searches in that snapshot, a product-level rating was absent on 440 of 1,620 returned listings. 106 of those had a rating on the first variant, and 334 had neither. No rating anywhere had a count of zero. A blank there meant unknown, not zero reviews. Your own record shouldn’t make a reader guess which kind of blank they’re looking at.

Rank your evidence, but don’t count generated text as evidence

The evidence.type field carries most of the weight when two copies disagree. Here is the order we propose, strongest first:

Evidence type What it is When two values disagree
own_test You measured it and kept the method Usually wins, if the method matches the claim’s condition
manufacturer_test A test report with a method and conditions Strong. Copy the conditions across
manufacturer_spec A spec sheet value with no method Usable. Mark the condition as incomplete
seller_statement Your own copy, with no document behind it Weak. Find the source or mark it unknown
Generated or enriched text A platform’s summary of your data Not evidence. Trace it back to a source, or correct the field it came from

This ranking is a proposal for settling your own disagreements. It isn’t how any assistant weighs sources. Nobody publishes those weights.

Worked case: one real catalog record

Position 5 in our search for “humidifier for dry winter air large room quiet top fill” was a 4 L humidifier at USD 39.99. It was one of the listings in our simulation’s shelf: the 28 dB competitor with 310 ratings. Its record had a description and Shopify-generated spec, feature and selling-point lists. Here are its main claims, one row per claim record, filled from the outside. We don’t have the merchant’s documents, so every evidence field is unknown to us.

Claim Description Generated lists Record verdict
Runtime “up to 32 hours” Spec: “Up to 36 hours”. Features: “up to 36 hours” Copies disagree. Setting not stated anywhere
Noise “brings noise down to 28dB” “Noise Level: 28 dB” Copies match. Setting, distance and method unknown
Tank “4L tank” “Water Tank Capacity: 4 liters” Copies match. Needs no condition
Mist outlet “4-inch mist outlet design” “Mist Output: 4 inches (10.16 cm) with 30° tilting” Attribute changed. Mist output is normally a rate, such as mL/h
Dimensions Not stated “102 cm (L) x 10.16 cm (H) x 11.02 cm (W)” Generated only. Source unknown to us
Room coverage Not stated Not stated Unknown
Fill style “Easy Top Fill Design” “Easy top-fill design” Copies match

If you owned this product, the record tells you what to do, in order:

  1. Settle the runtime at the source. Open the manual or test report. If it says 32 hours, find the field the 36 came from and correct it. Add the mist setting to the claim either way.
  2. Add conditions to the noise claim. “28 dB” with no setting or distance is a number that can’t be compared with a competitor’s “26 dB”.
  3. Fix the outlet claim. If your structured fields hold “4 inches” under anything like “mist output”, rename it. If they don’t, the generated value has no source on your side, and that’s worth knowing too.
  4. Publish the dimensions yourself. One length of 102 cm next to a height of about 10 cm would be unusual for a 4 L humidifier. We can’t say it’s wrong, because we haven’t seen the product. But when a generated value is the only copy, you aren’t the author of your own spec.
  5. Decide what to say about room size. If you have a rating with its conditions, publish it. If you don’t, the record says unknown, and the page says nothing rather than “large rooms”.

That list fell out of seven rows. Without the record, a merchant reading their own product page would have found none of it, because the page itself looks fine.

Scope and exclusions belong in the record too

A claim can be accurate and still mislead if its scope gets lost. The snowsuit at position 9 in our “toddler snowsuit rated for minus 30” search rated the hood’s insulation to -30°C. Its generated spec line said the insulation was rated to -30°C, with no mention of the hood. A shopper with a toddler in -30°C weather needs to know which one is true. In the record, scope: "hood insulation" is a required field, not a footnote.

Exclusions are claims with the opposite polarity. Position 4 in the humidifier search said, in its description, that there is “no filter to replace” and that it has “Manual mist controls rather than a programmable humidistat”. Both are useful to the right shopper: one saves money, the other tells someone who wants automatic humidity control to look elsewhere. Store them as claims with "polarity": "excludes", with a source like any other claim. Our guide to negative product facts covers which exclusions to publish and how to word them.

How the record maps to what you publish

The record lives in your files. What you publish is a set of copies, and each destination has its own rules.

Record field Product page OpenAI product feed Schema.org markup
Value and unit Visible text: “up to 32 hours” Typed fields such as weight plus item_weight_unit. Units aren’t inferred value with unitCode
Condition Visible text: “on the low setting” Fields such as dimensions have nowhere to put it. Put it in description measurementTechnique on a PropertyValue
Unknown Say nothing, or say “not rated” if that’s true Omit the field. Don’t write “unknown” unless the field lists it Omit the property
Range “[low] to [high] dB”, with the setting named for each end Description text minValue and maxValue
Variant binding The variant picker shows the right value One row per variant, variant_dict consistent with top-level attributes One Product or offer per variant

Some of this comes straight from OpenAI’s feed reference. It says to omit unknown optional values rather than writing placeholders such as “unknown” or “n/a”, and that an empty value doesn’t mean zero or false. A review count of zero means no reviews, while an omitted one means unknown. An omitted shipping price means unknown, not free shipping. It also says that conflicting top-level and variant values won’t be reconciled for you. That’s exactly the kind of conflict the record exists to catch before you upload.

Your internal record keeps “unknown, not tested”. The feed says nothing. Both are correct, because they do different jobs.

If you sell on Shopify, OpenAI says your catalog is already integrated with ChatGPT, with no extra setup or application. Your products still have to meet Shopify Catalog’s requirements, which include a plan rule with an exception for stores on Shopify’s Agentic plan; our storefronts guide covers eligibility. Shopify also says Catalog Mapping can pull data from metafields. So the copy that matters most may be one you never typed: the catalog record built from your fields. Put the conditions in the visible description, because typed feed fields such as dimensions have nowhere to hold them, and a generated list may or may not carry them across.

What this is not

  • Not a protocol. Nobody consumes this JSON. It is an internal contract between your source documents and every copy you publish.
  • Not a ranking lever. OpenAI’s merchant page says richer data helps products surface with more accurate information. It doesn’t define richer data or measure an effect, and neither have we.
  • Not new vocabulary for its own sake. eCommerce Insights’ definition of agentic commerce optimization, which credits ReFiBuy with the term, already treats the product record as the unit of work. We go one level down, to the single claim, because that’s where the four breaks in the first table happened.
  • Not a whole-decision receipt. This records why one claim is true. It doesn’t record why an agent recommended one product over another.

How we checked

On October 27 we reopened the saved Shopify agent-catalog response for “humidifier for dry winter air large room quiet top fill”, taken on October 26, 2026 with no buyer context, top 10 results. For position 5 we read the description and the generated spec, feature and selling-point lists word for word. The description describes a “4-inch mist outlet design”. The generated spec list gives “Mist Output: 4 inches (10.16 cm) with 30° tilting” and “Dimensions: 102 cm (L) x 10.16 cm (H) x 11.02 cm (W)”. No dimension appears in the description. The runtime gap, 32 hours against 36, is already in our published receipts.

For position 4 we confirmed that the description contains “there’s no filter to replace” and “Manual mist controls rather than a programmable humidistat”, and that the record carried no generated metadata.

We didn’t inspect any product, manual or merchant admin. Store and brand names are withheld.

Your next step

Pick the one claim customers ask you about most, such as noise level, runtime or a temperature rating. Write its record: variant, value, unit, condition, scope, source document, checked date. Then search your product page, your admin fields and any feed or catalog view you can reach, and add each copy to published_copies with its exact text. Every "matches": false is a fix, and the record tells you which document settles it.