Product Schema and Structured Data for AI Recommendations (JSON-LD, GTIN)

No AI-specific product schema exists. Here are the Product + Offer JSON-LD fields, GTIN rules, and variant modeling deciding whether AI engines recommend your SKUs.

Product Schema and Structured Data for AI Recommendations (JSON-LD, GTIN)

Your product pages already carry schema markup. Rich results show up in Google. Then a shopper asks ChatGPT for something you sell, and it describes your product vaguely or recommends someone else's.

AI shopping engines don't use a special product schema. They use the standard schema.org Product and Offer vocabulary, the same one behind Google's rich results. What matters is that it's in the server HTML, complete, carries a GTIN, and models every variant. Get those four right and your SKUs become recommendable across ChatGPT, Perplexity, and Google AI.

TL;DR: AI shopping engines use the same Product and Offer structured data that powers Google rich results. There is no separate "AI schema." What decides whether they can use it: the JSON-LD sits in the server-rendered HTML, the core fields are present (name, image, offers with price and priceCurrency), availability and a product identifier are set (GTIN preferred, then MPN or SKU), and each purchasable variant is modeled as its own Offer. GTIN is what engines use to match your product across sources, so missing GTINs quietly cap your eligibility. On-page schema and the product feed you submit to ChatGPT and Google are two channels for the same record. Keep them consistent.

Key Takeaways

  • There is no AI-specific product schema. AI answer engines use standard schema.org Product, Offer, and AggregateRating data, the same vocabulary as Google rich results, not a separate format (schema.org; OpenAI Help Center, 2026).
  • Google's required core for a merchant listing is name, image, and nested offers with price and priceCurrency. availability, brand, and an identifier are recommended, and they gate full Shopping eligibility (Google Search Central, 2026).
  • GTIN is the match key. Google uses it to reconcile your product against other sellers and data sources. Products with no unique identifier "may not be eligible for all Shopping programs or features" (Google Merchant Center Help, 2026).
  • Google recommends putting Product structured data in the initial server HTML, and most non-Google AI crawlers don't run JavaScript at all, so client-injected JSON-LD can be invisible to them (Google Search Central, 2026).
  • On-page schema and the direct product feed are two channels for the same record, and AI systems cross-check the two (OpenAI ACP product feed spec; Google Merchant Center Help, 2026).

No. AI answer engines use the standard schema.org Product, Offer, and AggregateRating vocabulary that powers Google's product rich results. There is no AI-only type, property, or namespace to add.

Structured data is machine-readable facts about a page, usually written as JSON-LD inside a <script> tag. Answer Engine Optimization (AEO) is the work of making those facts complete and consistent enough that an AI answer engine will cite or recommend you. For a store, a short list of schema.org types carries the load: Product, Offer, AggregateRating and Review, Brand, Organization, and BreadcrumbList.

Engines lean on this data because it removes guesswork. Price, availability, identifier, and which entity the page is about are stated outright instead of inferred from rendered text. OpenAI says ChatGPT "considers structured metadata from first-party and third-party providers" such as price and product description when it picks products to surface (OpenAI Help Center, 2026). Google's AI surfaces and crawler-based engines like Perplexity read the same Product and Offer markup they read for classic results.

AI answer engines rely on the same structured product data that powers Google rich results, the schema.org Product and Offer vocabulary. There is no separate AI product schema (schema.org; OpenAI Help Center, 2026).

If products still aren't appearing when shoppers ask AI what to buy, start with a systematic diagnosis of why your products aren't showing up in AI search.

Which fields do AI shopping engines actually read?

Google's required core for a merchant listing is small: name, image, and an offers object with price and priceCurrency. Everything that makes a product genuinely competitive, availability, an identifier, brand, shipping and returns, is filed as recommended, and the recommended set is getting less optional every year.

Field Google merchant listing What it does for an engine
name Required The product title shown to buyers
image Required Product photo, as an array of absolute high-res URLs
offersprice, priceCurrency Required The amount and currency to quote
offersavailability Recommended Whether it can be bought right now
gtin / mpn / sku Recommended Matches your product across sellers and sources
brand Recommended Resolves which brand entity the page is about
aggregateRating Recommended Signals trust on retail queries
shippingDetails, hasMerchantReturnPolicy Recommended Increasingly gate price and shopping treatments

Treat "recommended" as "required in practice." A product with no identifier is hard for Google to classify and "may not be eligible for all Shopping programs or features" (Google Merchant Center Help, 2026). A stale OutOfStock gets your product filtered out of recommendations even when everything else is right. schema.org supports InStock, OutOfStock, PreOrder, and BackOrder, among others; Google accepts a subset for the availability property. For resale or refurbished catalogs, set itemCondition so an engine doesn't present used stock as new.

The direction is clear in the 2026 docs: shippingDetails (with shippingRate and shippingDestination) and hasMerchantReturnPolicy (with applicableCountry, returnPolicyCategory, and merchantReturnDays) now influence whether price and shopping treatments render at all on many retail queries. Google recommends setting a single return policy at the Organization level rather than repeating it on every Offer (Google Search Central, 2026).

Which product fields each channel asks for Both channels require the same core. They diverge on availability and brand, which the feed requires, and on GTIN, which is recommended for the page and optional for the feed. Google merchant listing OpenAI ACP product feed Required Recommended Optional name image price avail. GTIN brand ship/ret rating Source: Google Search Central (Merchant listing structured data); OpenAI ACP product feed spec, 2026. The ACP feed's required fields include availability and brand; GTIN is an optional but recommended enrichment.
Same core in both channels. The gaps, availability, brand, and GTIN, are exactly where incomplete records lose recommendations.

How do I write a valid Product + Offer JSON-LD block?

Put one JSON-LD <script type="application/ld+json"> block per product page. Set @type to Product, nest an offers object inside it, and render the block in the HTML your server returns.

{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Trailline 24L Daypack, Slate",
  "image": ["https://example.com/img/trailline-24l-slate.jpg"],
  "description": "24-liter weatherproof daypack with a roll-top closure.",
  "sku": "TL-24-SLT",
  "gtin13": "0123456789012",
  "brand": { "@type": "Brand", "name": "Trailline" },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/p/trailline-24l-slate",
    "priceCurrency": "USD",
    "price": "129.00",
    "availability": "https://schema.org/InStock",
    "itemCondition": "https://schema.org/NewCondition"
  }
}

The values above are illustrative. Replace them with real data and hold to a few rules: one product entity per page; image as an array of absolute URLs, not /img/... paths; price as a string with no currency symbol; and every value identical to what the shopper sees on the page. A schema price that differs from the displayed price is a trust failure, not a rounding detail.

Google renders JavaScript and can read JSON-LD your scripts inject. It still recommends putting Product markup in the initial HTML, because dynamically generated markup makes Shopping crawls "less frequent and less reliable" for fast-changing fields like price and availability (Google Search Central, 2026). Most non-Google AI crawlers skip JavaScript entirely, so server rendering is the safe default.

The next fields to add are shippingDetails, which nests shippingRate and shippingDestination, and hasMerchantReturnPolicy, which nests applicableCountry, returnPolicyCategory, and merchantReturnDays. Both increasingly affect whether a price treatment shows at all. When you write the prose beside the markup, follow how to structure the product description itself.

Is GTIN required, and what happens without it?

A GTIN isn't strictly required to render a basic product snippet. It is what engines use to match your product across sellers and sources. Without any identifier you're capped at basic snippets. With a GTIN you're eligible for full merchant listings and cross-source reconciliation.

GTIN stands for Global Trade Item Number. It's the umbrella over UPC, EAN, and ISBN, and it comes in gtin8, gtin12, gtin13, and gtin14 lengths. Brand-manufactured products usually already have one, assigned through GS1 and printed on the packaging. For custom or handmade goods with no GTIN, use mpn plus brand as the fallback. A wrong or reused GTIN is worse than none: Google disapproves products with an invalid GTIN, and reusing one tells an engine two different products are the same.

In OpenAI's Agentic Commerce Protocol (ACP) product feed, item_id per variant is required and gtin is optional but improves catalog matching (OpenAI ACP product feed spec, 2026). The pattern holds across channels. Some identifier is mandatory in practice; a GTIN specifically is the one that unlocks comparison.

Google uses the GTIN to match a product across sources, and "accurate matching to products can't be assured when GTIN is missing." Products submitted with no unique identifier may not qualify for all Shopping programs or features (Google Merchant Center Help, 2026).

Here is an Offer with no identifier:

"offers": {
  "@type": "Offer",
  "priceCurrency": "USD",
  "price": "129.00",
  "availability": "https://schema.org/InStock"
}

And the same Offer, fixed:

"offers": {
  "@type": "Offer",
  "priceCurrency": "USD",
  "price": "129.00",
  "availability": "https://schema.org/InStock",
  "gtin13": "0123456789012",
  "mpn": "TL-24-SLT",
  "brand": { "@type": "Brand", "name": "Trailline" }
}
How strongly each identifier lets an engine match your product GTIN is the only identifier that reliably reconciles your product with other sellers and data sources. GTIN (UPC / EAN / ISBN) MPN + brand SKU only (internal) No identifier 0 1 2 3 Source: AEOsome analysis of Google Merchant Center product-identifier documentation, 2026. Match strength is a qualitative assessment, not a measured value.
SKU tells your warehouse which shelf. It tells an outside engine almost nothing. GTIN is the identifier that travels.

Consistent identifiers across your on-page schema and your feed also stop an engine from treating one product as several. It's part of keeping your brand and product identity consistent across every source an engine reads.

How do I model product variants so each SKU is recommendable?

Give every purchasable variant its own Offer with its own identifier, price, and availability. A single Product with a price range and no per-variant detail is legible to a person and useless to an engine that needs a specific SKU to recommend.

Model variants one of two ways. Use ProductGroup with hasVariant to hold the variants under one parent, or publish discrete Product entities that each carry inProductGroupWithID. Google supports ProductGroup for merchant listings, and its guidance is current for 2026 (Google Search Central, 2026). Either way, variesBy names the differentiating attributes such as color and size, and the group ID must match between the parent and every variant.

The common failure is client-side: a variant selector changes price and stock in the browser without updating the JSON-LD. The crawler only ever sees the default variant. It recommends a size that's out of stock, and the shopper lands on a dead option.

Run every variant through this checklist:

  1. Each purchasable variant has its own Offer with its own sku, price, and availability.
  2. Each variant carries an identifier: gtin where you have one, otherwise mpn plus brand.
  3. Variants sit under one ProductGroup with hasVariant, or as separate Product entities with matching inProductGroupWithID / productGroupID.
  4. variesBy lists the attributes that differ.
  5. The on-page group and variant IDs match the feed's item_group_id and item_id.
  6. The JSON-LD updates when a shopper switches variant. Price and availability change with the selection, not just the visible text.

In the audits we run at AEOsome, the products that get recommended almost always carry the fuller record: Product plus a per-variant Offer, a GTIN, shipping and return policy. The ones that don't are usually missing two or more of those. We built SubFex to keep variant IDs matched between page and feed so the record never drifts. That mapping is the SKU-level work behind a full feed compliance checklist.

Schema on the page vs the product feed, which does what?

They're two delivery channels for the same structured record. On-page JSON-LD is read when a crawler fetches your product page. The direct feed, OpenAI's ACP feed or Google Merchant Center, is pushed straight to the platform on its own schedule, independent of any crawl. Use both. Keep them consistent.

The feed's advantages are speed and control. Google's scheduled fetches default to daily and are configurable, and event-driven price or stock changes go through an API rather than a fixed interval. You map fields explicitly, exclude products per platform, and get diagnostics when something fails. It's the channel to trust for anything that changes hourly.

On-page schema still matters. It works for engines with no feed program, it reinforces the product entity on the live page, and it feeds Google's rich results at the same time. Most stores need both channels populated, not a choice between them.

The product feed delivers price and inventory to the platform directly and is refreshed on a schedule you set. On-page schema is read when the page is crawled. AI systems use both, and they cross-check them (OpenAI ACP product feed spec; Google Merchant Center Help, 2026).

Consistency is the signal. When the feed says one price and the PDP schema says another, you give the engine a reason to trust neither record and drop the recommendation. For how the selection actually works, see why your products don't appear in ChatGPT Shopping, and confirm your crawler policy isn't hiding the pages your schema lives on in the GPTBot myth.

How do I confirm an AI crawler can actually read my schema?

Check three things. The JSON-LD is in the raw server response, not injected only by JavaScript. It validates against schema.org and Google's requirements with no missing fields. The values match the rendered page. Then monitor for drift as the catalog changes.

Start with the server response. Use view-source or a curl fetch of the page and search for "@type": "Product". If the block only appears after JavaScript runs, a crawler that doesn't execute your scripts will never see it. Next, run the markup through the Rich Results Test and the Schema Markup Validator, and check Merchant Center diagnostics for feed-side errors. Then compare schema values against the rendered page, field by field.

Symptom Likely cause Fix
Validator passes, no rich result Only minimum fields present Add brand, identifier, shippingDetails, hasMerchantReturnPolicy
Schema absent in curl, present in browser JSON-LD injected by client-side JavaScript Render Product markup server-side
"Missing field gtin" warnings across the catalog Identifiers not mapped from the PIM or feed Populate gtin from GS1 data; use mpn + brand where none exists
Engine recommends an out-of-stock variant JSON-LD not updated on variant switch Bind price and availability to the selected variant
Feed and page prices disagree Two systems updating on different schedules Make one source authoritative; sync the other to it

"No errors" is a floor, not the goal. A valid block with only the minimum fields still loses to a complete one. The validator tells you the markup parses. It doesn't tell you the record is competitive.

The ongoing part matters more at scale. New variants, price changes, and out-of-stock states all break schema silently across a large catalog. This is a monitoring job, not a one-time fix. It's the Monitor → Audit → Optimize → Verify loop applied to structured data: watch for drift, audit what broke, fix the record, confirm the engine now reads it.

Frequently asked questions

Does schema markup help my products show up in ChatGPT or Perplexity?

It helps engines read your products accurately: price, availability, identifier, and which entity the page is about. Perplexity and Google's AI surfaces read Product and Offer markup from crawled pages; ChatGPT relies on structured product metadata, primarily from your product feed (OpenAI Help Center, 2026). Schema is necessary, not sufficient. Feed completeness and variant modeling still decide whether you get recommended.

Is GTIN required for product schema?

Not to render a basic product snippet. But Google uses the GTIN to match your product across sellers and sources, and products with no unique identifier may not qualify for all Shopping features (Google Merchant Center Help, 2026). Supply GTINs wherever you have them, and use mpn plus brand where none exists.

What schema types do I need for an eCommerce product page?

Product with a nested Offer is the core. Add Brand, AggregateRating or Review, shippingDetails, and hasMerchantReturnPolicy, plus BreadcrumbList and Organization at the site level (Google Search Central, 2026). There is no separate AI schema to add.

Does product JSON-LD have to be server-side rendered?

Effectively yes. Google can render JavaScript and read JS-injected JSON-LD, but it recommends Product markup in the initial HTML for crawl reliability, and most non-Google AI crawlers don't run JavaScript at all (Google Search Central, 2026). Server rendering is the choice that works for every engine.

What's the difference between product schema and a product feed?

Schema is markup on your live page, read when a crawler fetches it. A feed is a structured file pushed straight to the platform, OpenAI's ACP feed or Google Merchant Center, refreshed on a schedule with no crawl required. Same underlying data, two channels. Keep them consistent.

Same Schema. Higher Bar.

Three required core fields. One rule: put the JSON-LD in server-rendered HTML. Zero AI-specific schema types to learn.

The job was never new markup. It's a complete, GTIN-carrying, variant-level product record that stays consistent across your page and your feed. If your SKUs lack that, they're invisible to AI shopping engines at the variant level, no matter how strong your Google rankings. If your GTINs are missing or reused, you're capped at basic snippets. If your page and feed contradict each other, you build trust debt.

Run a free AEOsome audit to see which of your SKUs carry the structured data AI shopping engines need, and which are invisible at variant level. It also flags whether reviews and AggregateRating move recommendation for your categories.


About the author. Vijaya Kumar Channalli is the founder of AEOsome (Tartu, Estonia), which helps eCommerce brands get their products recommended when shoppers ask AI what to buy. He writes about AI shopping visibility, product-feed compliance, and how Answer Engine Optimization differs from SEO. More at vijay.cc.

Sources: schema.org, Product, Offer, and ProductGroup vocabulary; Google Search Central, Merchant listing (Product) structured data and Product variants (ProductGroup) structured data; Google Merchant Center Help (GTIN and supported structured data attributes); OpenAI documentation (Agentic Commerce Protocol product feed spec; "Shopping with ChatGPT search" Help Center).