Skip to content

Guide9 min readPublished

Product structured data for AI agents

Which schema.org Product properties a store’s pages need, what Google requires and what our checks read, with a JSON-LD builder and a checker for the markup you have.

What product structured data does an AI agent need? The same schema.org Product markup Google reads: a JSON-LD block in the HTML of each product page with the product's name, image, price, currency, availability and an identifier such as a SKU or GTIN. There is no special markup for AI, and Google says so. The markup still matters, because it is the one place on the page where price and stock are written in a form that a program can read without guessing.

This guide covers which properties to include, a builder that writes the block for you, and a checker that grades the block you have against Google's rules and our own. Storewalk is ours: we build the scan, and its product data check is one of ours. Google and schema.org are quoted from their own pages, read on 3 November 2026. Which checks read what comes from our own code.

Do AI agents read product structured data?

Google is clear about its own products. Its guide to generative AI search lists "Overfocusing on structured data" among the things to drop: "Structured data isn't required for generative AI search, and there's no special schema.org markup you need to add. However, it's a good idea to continue using it as part of your overall SEO strategy, as it helps with being eligible for rich results on Google Search." Merchant listings, the product results with price and stock, are one of those rich results, and they come with a list of required fields.

Other AI vendors are quiet on the subject. We read the crawler pages of OpenAI, Anthropic, Perplexity, Meta, Amazon and Apple. Apple's mentions one schema.org property, for paywalled pages, and none of the six says anything about product markup. Nobody promises to read your JSON-LD, and nobody says they ignore it.

There is a mechanical case all the same. JSON-LD is a script tag that holds data instead of code. When the server sends it with the page, any program that fetches the HTML gets it, including one that runs no JavaScript. How agents read a page shows the difference: the visible price may be painted by a script, while the block states the price and the currency outright. Google's merchant-listing page makes a related point for its own crawler: "dynamically-generated markup can make Shopping crawls less frequent and less reliable", and "we recommend putting Product structured data in the initial HTML for best results."

Which fields does a product page need?

Google's merchant-listing page sorts the properties into required and recommended ones. Required on the Product: name, image and offers, where the offer must be an Offer, because "merchant listings require an Offer as the merchant has to be the seller of the product". Required on the Offer: a price above zero and a three-letter currency code. Availability, brand, description, identifiers, condition and the policies are recommended.

Our product data check asks for a little more. It wants an identifier (a SKU, GTIN or MPN) and an availability on every offer. Google lists both as recommended, so this is our rule, and it is stricter than Google's. Choose a property to see Google's words and what our checks do with it:

Product markup, property by property: what Google asks for and what our checks read
Pick a property

Showing: name

name

Required by Google for merchant listings

In Google’s words

“The name of the product.”

What our checks do with it

DISC-004 wants it as text. A name that is an object or a list does not count.

Source: Google Search Central: Merchant listing structured data

Google’s labels are for its merchant listings, read on 3 November 2026. The crawler pages of OpenAI, Anthropic, Perplexity, Meta, Amazon and Apple say nothing about product markup, so Google’s list is the nearest thing to a shared rulebook.

The price goes in as a number with a full stop for the decimal point: schema.org asks for priceCurrency "instead of including ambiguous symbols such as '$' in the value", so "price": "59.00" and "priceCurrency": "EUR", never "€59,00". Availability goes in as one of schema.org's values, such as https://schema.org/InStock. Google accepts the short name (InStock) too, and so do our checks, so pick either and stick with it.

How do you write the JSON-LD for a product?

Most platforms write it for you, which we come back to below. If yours doesn't, or you want to see what a complete block looks like, fill in the builder. It starts with an invented shirt from an invented shop:

A Product JSON-LD builder

Filled in with an invented product to start. Type the price as your page shows it; the builder writes it the way schema.org asks, with a full stop and no symbol.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Northwind Linen shirt",
  "image": "https://example.com/images/linen-shirt.jpg",
  "description": "A relaxed shirt in washed European linen.",
  "brand": {
    "@type": "Brand",
    "name": "Northwind Linen"
  },
  "sku": "NL-SHIRT-01",
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/products/linen-shirt",
    "price": "59.00",
    "priceCurrency": "EUR",
    "availability": "https://schema.org/InStock",
    "itemCondition": "https://schema.org/NewCondition"
  }
}
</script>

Google required: 5 of 5. Our DISC-004: complete.

Graded: the first Product.

Google requires (merchant listings)

  • Yes: name
  • Yes: image
  • Yes: offers, as an Offer (not only an AggregateOffer)
  • Yes: a price greater than zero, in price or priceSpecification.price
  • Yes: priceCurrency as a three-letter ISO 4217 code

Google recommends

  • Yes: availability
  • Yes: gtin, mpn or sku
  • Yes: brand.name
  • Yes: description
  • Yes: itemCondition

Our DISC-004 reads

  • Yes: a Product, or a ProductGroup with Product variants, at the top level or in @graph
  • Yes: name, as text
  • Yes: an identifier: sku, gtin or mpn (on a ProductGroup, on every variant)
  • Yes: offers.price on every offer
  • Yes: offers.priceCurrency on every offer
  • Yes: offers.availability on every offer

Put the block in the HTML your server sends, not in a script that adds it later, and keep every value the same as the page. Built in your browser; nothing is sent.

Put the block in the HTML your server sends, so a reader that runs no scripts still gets it. Keep every value identical to what the page shows, because an agent that finds two prices has no way to know which one to believe, and our price match check compares them. Give each variant its own offer with its own price, stock and URL. That last one is long enough to need its own guide.

How do you check the markup you have?

Google offers two tools and says what each is for. The Rich Results Test is "the official Google tool for testing your structured data to see which Google rich results can be generated by the structured data on your page." The Schema Markup Validator is there to "validate all Schema.org-based structured data that's embedded in web pages, without Google feature specific warnings." Use the first for Google's rules and the second for plain schema.org.

The checker below does a third job: it grades a block against Google's required and recommended fields and against what our DISC-004 reads, side by side. Copy the block from your product page's source (View source in the browser, not Inspect, so you see what the server sent) and paste it in. JSON-LD is unforgiving. One missing comma, and the block tells every reader as much as a shop sign in invisible ink. The last example shows what that looks like.

Check your Product JSON-LD, three ways
Start from an example, or paste your own below

Google required: 5 of 5. Our DISC-004: complete.

Graded: the first Product.

Google requires (merchant listings)

  • Yes: name
  • Yes: image
  • Yes: offers, as an Offer (not only an AggregateOffer)
  • Yes: a price greater than zero, in price or priceSpecification.price
  • Yes: priceCurrency as a three-letter ISO 4217 code

Google recommends

  • Yes: availability
  • Yes: gtin, mpn or sku
  • Yes: brand.name
  • Yes: description
  • Yes: itemCondition

Our DISC-004 reads

  • Yes: a Product, or a ProductGroup with Product variants, at the top level or in @graph
  • Yes: name, as text
  • Yes: an identifier: sku, gtin or mpn (on a ProductGroup, on every variant)
  • Yes: offers.price on every offer
  • Yes: offers.priceCurrency on every offer
  • Yes: offers.availability on every offer

Checked in your browser against Google’s merchant-listing rules and our DISC-004’s own code. It reads JSON-LD only; Google’s Rich Results Test also reads microdata and RDFa. Nothing you paste is sent.

What does our scan read?

DISC-004 samples up to three product pages and looks for a Product node in the JSON-LD (or a ProductGroup with Product variants), at the top level or inside an @graph list. A page counts as complete when the Product has a name, an identifier, and a price, currency and availability on every offer. Offers inside an AggregateOffer count; an AggregateOffer with only a low and a high price has no price for us to read. The score is the share of sampled pages that are complete.

Other checks read the same block. Price transparency takes the currency from it, availability compares its stock state with the words on the page, and the price match check compares its price with the one a shopper sees. Our shipping and returns checks read the policies on the same offer, which the shipping and returns guide covers.

Two layouts that Google accepts used to trip up our scanner. Both now read the way Google reads them:

  • A price written only inside priceSpecification counts as the offer's price for DISC-004, DISC-005 and EVAL-003. Google accepts it ("The active price is required but may be nested inside a priceSpecification property"), and BigCommerce's Catalyst storefront writes prices that way. A specification marked as a list or strikethrough price doesn't count, and if several give different prices, we read none rather than guess.
  • A ProductGroup with its variants nested under hasVariant counts as the product. The name comes from the group, each variant brings its own offer, and the group has an identifier when every variant has one. Our price, availability, shipping, returns and price match checks read those offers too. Google documents that layout, and Shopify's structured_data filter prints "a ProductGroup if they have one or more variants".

Our availability check reads the stock state in any of its spellings: InStock, https://schema.org/InStock or the older http:// form.

What do Shopify, WooCommerce, BigCommerce and Magento output?

Each platform writes something, and none writes everything:

  • On Shopify, Dawn prints the structured_data filter, which Shopify describes as converting "an object into a schema.org structured data format": a Product, or a ProductGroup when there are variants. Other themes write their own. See the Shopify guide.
  • On WooCommerce, core prints name, URL, description, image, SKU, a GTIN when it is valid, MPN, offers and reviews, but no brand. A variable product whose prices differ gets one AggregateOffer with a low and a high price and no single offers. The WooCommerce guide covers the filters that change it.
  • On BigCommerce, the Cornerstone theme prints name, SKU, MPN, GTIN, brand and an offer with price, currency, condition and availability. Catalyst puts the price inside priceSpecification. See the BigCommerce guide.
  • On Magento and Adobe Commerce, the stock Luma theme writes microdata, not JSON-LD, and no availability, so DISC-004, which reads JSON-LD only, finds nothing. An extension or a theme that writes JSON-LD fixes that. See the Magento guide.

Whichever you run, paste one real product page into the checker before you change anything. The agent readiness checklist puts this task first, for good reason: an agent that can't read the price won't get far enough to fail at anything else.

Frequently asked questions

Is there special structured data for AI agents?

No. Google says "there's no special schema.org markup you need to add" for its generative AI search, and we found no other AI vendor that defines any. The markup that helps is the ordinary schema.org Product and Offer, which Google's merchant listings already ask for.

Which Product properties does Google require?

For merchant listings, name, image and offers on the Product. On the Offer, a price greater than zero (in price or priceSpecification.price) and a three-letter ISO 4217 priceCurrency. Availability, brand, identifiers, description, condition and the shipping and return policies are recommended.

Does Google require a GTIN?

Not for merchant listings. Google lists gtin, mpn and sku as recommended and asks you to "Include all applicable global identifiers". Our DISC-004 does require one identifier, which is our own rule.

Should JSON-LD be added with JavaScript or in the HTML?

In the HTML your server sends. Google can read JSON-LD that a script adds, but its merchant-listing page warns that dynamically generated markup "can make Shopping crawls less frequent and less reliable", and a reader that runs no scripts never sees it at all.

Can I use microdata instead of JSON-LD?

Google's Rich Results Test reads JSON-LD, microdata and RDFa, and Google recommends JSON-LD "if your site's setup allows it". Our DISC-004 reads JSON-LD only, so a microdata-only page reads to it as missing.

The sources below were last checked on the date shown.