TL;DR
- AI shopping assistants read the same Product JSON-LD Google has consumed for years, but they are stricter about
Offers,price,priceCurrency,availability, and product identifiers (GTIN/MPN/SKU). aggregateRatingandreviewblocks are the single biggest lever for getting listed alongside competitors in ChatGPT Shopping and Gemini's product panels.- Ship one canonical Product entity per URL, keep price in sync with what renders on the page, and use
ItemListon category pages rather than stuffing multiple products into one Product node. - Feed accuracy matters more than markup volume. If your JSON-LD says "InStock" and the page says "Sold out," assistants downrank or drop the listing.
- Test with Google's Rich Results Test and Schema.org validator, then confirm the raw HTML (not the rendered DOM) contains the JSON-LD so LLM crawlers without JS execution can see it.
AI shopping surfaces — ChatGPT Shopping, Gemini's shopping panels, Perplexity's product comparisons, and Google's AI Overviews for commercial queries — are pulling structured product data from the open web at query time and from indexed snapshots. The markup itself is not new. What changed is which fields get used, how strictly they are validated, and how quickly a mismatch between markup and page content will get you filtered out.
What AI shopping assistants actually parse
ChatGPT Shopping, launched in 2024 and expanded through 2025, sources product results from a mix of merchant feeds, third-party aggregators, and structured data on retailer pages. OpenAI has stated the results are not ads and are chosen based on relevance signals, which in practice means schema hygiene, review data, and price freshness carry weight. See OpenAI's overview of shopping in ChatGPT for the current mechanics.
Gemini's shopping experience leans on Google's existing Merchant Center graph plus Product structured data crawled from retailer pages. Perplexity's shopping card, introduced in late 2024, similarly relies on structured data and merchant partnerships (Perplexity blog).
The intersection of what all three consume reliably:
name,description,image(multiple, high-resolution)brand(as anOrganizationorBrandnode, not a string)sku,mpn, and at least onegtin8/12/13/14where applicableofferswithprice,priceCurrency,availability,priceValidUntil,url,itemConditionaggregateRatingwithratingValue,reviewCount, andbestRating- Individual
reviewnodes withauthor,datePublished, andreviewRating
Anything else — award, hasMerchantReturnPolicy, shippingDetails — is upside, not table stakes. Return policy and shipping nodes are increasingly required for Google Merchant listings and are a good signal to AI assistants that the merchant is legitimate.
A real JSON-LD example
Below is a working Product block for a single SKU page. It validates in Google's Rich Results Test and contains only fields AI assistants demonstrably use.
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Fjord 40L Waterproof Backpack",
"image": [
"https://example.com/img/fjord-40l-front.jpg",
"https://example.com/img/fjord-40l-side.jpg",
"https://example.com/img/fjord-40l-open.jpg"
],
"description": "40-liter roll-top backpack with welded seams, laptop sleeve, and IPX6 waterproofing.",
"sku": "FJ-40-BLK",
"mpn": "FJ40BLK-2026",
"gtin13": "5012345678900",
"brand": {
"@type": "Brand",
"name": "Fjord Gear"
},
"offers": {
"@type": "Offer",
"url": "https://example.com/products/fjord-40l",
"priceCurrency": "USD",
"price": "189.00",
"priceValidUntil": "2026-12-31",
"itemCondition": "https://schema.org/NewCondition",
"availability": "https://schema.org/InStock",
"hasMerchantReturnPolicy": {
"@type": "MerchantReturnPolicy",
"applicableCountry": "US",
"returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
"merchantReturnDays": 30,
"returnMethod": "https://schema.org/ReturnByMail",
"returnFees": "https://schema.org/FreeReturn"
}
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"reviewCount": "312",
"bestRating": "5"
}
}
Three things that trip teams up on this block: price must be a string without a currency symbol, availability must be a full Schema.org URL (not "InStock"), and aggregateRating.reviewCount has to reflect actual reviews present on the page or in linked review nodes. Fabricated review counts get sites removed from AI surfaces once caught.
Offers, price, and availability drift
The most common failure mode is not missing schema — it's stale schema. A page renders "$149 — Sold out" while the JSON-LD still declares "price": "189.00" and "availability": "InStock". Google's structured data guidance and every AI assistant treat this as a trust violation.
Practical fixes:
- Generate JSON-LD server-side from the same inventory and pricing source as the visible page. Do not maintain a separate CMS field for schema.
- If you cache pages aggressively, invalidate schema on price and stock changes, not just on product edits.
- For variant products, either emit a
ProductGroupwith childProductnodes (Google's newer pattern) or a singleProductwith anOffersarray — never both. - Set
priceValidUntilto a real date within 12 months. Missing or past dates cause Google to drop the rich result, and Gemini inherits that filtering.
Reviews are the ranking layer
Once basic Product schema is clean, aggregateRating and per-review markup determine whether you show up in comparison-style prompts like "best 40L waterproof backpack under $200." AI assistants aggregate ratings across sources, but they weight ratings that are (a) attached to a specific SKU, (b) backed by visible review content on the same page, and (c) corroborated by third-party review sites via sameAs or brand entity signals.
If your reviews live in a JavaScript widget that loads after page render, the JSON-LD should still be present in the initial HTML. LLM crawlers like GPTBot and ClaudeBot do not reliably execute JavaScript, so client-rendered review counts will be invisible to them even if Googlebot sees them.
Category pages: use ItemList, not stacked Products
A common mistake on collection pages is dumping five Product JSON-LD blocks into <head>. Google and AI assistants expect one primary entity per URL. For a category or collection page, use an ItemList where each itemListElement references the canonical product URL:
{
"@context": "https://schema.org",
"@type": "ItemList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "url": "https://example.com/products/fjord-40l" },
{ "@type": "ListItem", "position": 2, "url": "https://example.com/products/fjord-30l" }
]
}
Let the linked pages carry their own Product schema. This mirrors how AI assistants build product comparison responses — they crawl the list, then fetch each canonical PDP.
FAQ
Do I need a Google Merchant Center feed if my schema is perfect?
For ChatGPT Shopping and Perplexity, no — they can source directly from structured data and partners. For Gemini and Google AI Overviews on commercial queries, a Merchant Center feed materially increases the chance of inclusion because Google reconciles feed data with on-page schema.
Will AI assistants penalize me for missing GTINs?
Not penalize, but they will deprioritize you against competitors who supply them. GTINs let assistants match your product to reviews and price data across the web. For proprietary products without a GTIN, supply mpn and brand — that combination is treated as a valid identifier.
Should I add Product schema to blog posts that mention products?
No. Product schema belongs on pages where the product is the primary entity and is purchasable. Use mentions or link to the canonical PDP from editorial content. Misapplied Product schema is a common reason rich results get suppressed.


