Product schema for AI shopping
AI shopping agents build a structured record from your product page and compare it against competitors. This is the field-by-field breakdown of what goes into that record, which fields are hard filters, which decide close calls, and what a complete Product JSON-LD block looks like.
Product schema for AI shopping is schema.org Product markup, served as JSON-LD in a page's initial HTML, containing the offer, identity and policy fields an AI shopping agent needs to filter, compare and recommend a product.
The fields, by what they do
Not all missing fields cost the same. Hard filters remove you from the constrained candidate set entirely — an agent asked for something under $150 cannot consider a product with no price. Trust and risk fields decide which of the surviving candidates gets recommended.
| Field | Location | Role | Consequence if missing |
|---|---|---|---|
| name | Product | Identity | Product cannot be named in an answer |
| offers.price | Offer | Hard filter | Excluded from any budget-constrained query |
| offers.priceCurrency | Offer | Hard filter | Price is ambiguous; treated as unusable |
| offers.availability | Offer | Hard filter | Agent will not recommend what it cannot confirm is buyable |
| brand | Product | Trust | Cannot be matched to brand-specific requests |
| gtin / mpn / sku | Product | Trust | Listing cannot be reconciled with the same product elsewhere |
| description | Product | Comparison | Loses on feature-matched queries |
| image | Product | Presentation | Excluded from visual result surfaces |
| aggregateRating | Product | Trust | Loses close calls to rated competitors |
| hasMerchantReturnPolicy | Offer | Risk | Return terms weighed as unknown risk |
| shippingDetails | Offer | Risk | Delivery-constrained queries cannot include you |
A complete block
This is the shape Prefero's patch kit generates, with every field an agent uses. Substitute your own values; keep the structure.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Merino Base Layer Crew",
"description": "170gsm merino wool crew neck, flatlock seams, machine washable.",
"image": ["https://example.com/img/base-layer-crew.jpg"],
"sku": "SKU-123",
"gtin13": "0001234567890",
"mpn": "MPN-123",
"brand": { "@type": "Brand", "name": "Your Brand" },
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"reviewCount": "128"
},
"offers": {
"@type": "Offer",
"url": "https://example.com/products/base-layer-crew",
"price": "129.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition",
"shippingDetails": {
"@type": "OfferShippingDetails",
"shippingRate": {
"@type": "MonetaryAmount",
"value": "0",
"currency": "USD"
},
"deliveryTime": {
"@type": "ShippingDeliveryTime",
"transitTime": {
"@type": "QuantitativeValue",
"minValue": 2,
"maxValue": 5,
"unitCode": "DAY"
}
}
},
"hasMerchantReturnPolicy": {
"@type": "MerchantReturnPolicy",
"applicableCountry": "US",
"returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
"merchantReturnDays": 30,
"returnMethod": "https://schema.org/ReturnByMail",
"returnFees": "https://schema.org/FreeReturn"
}
}
}
</script>The four mistakes that void the whole block
A syntactically valid block can still produce nothing usable. These are the failures we find most often in scans.
- Injected client-side
- A theme or tag manager writes the JSON-LD after page load. Retrieval fetches do not run it, so the record does not exist. Render it server-side in the initial HTML.
- Hardcoded availability
- A template that always emits InStock. Recommending sold-out products is worse than being absent: the source gets discounted.
- Markup disagreeing with the page
- A stale price in JSON-LD against a live price in the DOM. Contradiction is treated as unreliability, not as an average.
- Category page markup on a product page
- An ItemList where a Product is expected. The agent sees a listing, not a purchasable item, and moves on.
How to verify
Fetch the product URL with JavaScript disabled — curl is enough — and confirm a Product block with a populated offers node is present in the response body. Then check the same fields exist across a sample of the catalogue rather than on the one product you tested.
In our 120-store benchmark, stores that had Product schema at all still averaged only 58/100 on field completeness: the required fields were there, the trust and risk fields were not.
curl -s https://example.com/products/your-product \ | grep -o 'application/ld+json' | head # Then inspect the block itself: curl -s https://example.com/products/your-product \ | python3 -c "import sys,re,json; \ m=re.findall(r'<script type=\"application/ld\+json\">(.*?)</script>', sys.stdin.read(), re.S); \ print(json.dumps([json.loads(x) for x in m], indent=2)[:2000])"
Frequently asked questions
- Which Product schema fields do AI shopping agents require?
- price, priceCurrency and availability act as hard filters — without them a product is excluded from constrained queries. name, brand, a product identifier, description, images, aggregateRating, hasMerchantReturnPolicy and shippingDetails decide which of the remaining candidates gets recommended.
- Does JSON-LD have to be server-rendered?
- For AI shopping agents, yes. Retrieval crawlers generally do not execute JavaScript, so schema injected after page load is invisible to them. Emit the block in the initial HTML response.
- Is microdata enough instead of JSON-LD?
- It is parsed as a fallback but it is more fragile and more often incomplete. JSON-LD is the format agents extract first and the one Prefero scores against.
- Do I need GTIN if I make my own products?
- If no GTIN exists, publish mpn and a stable sku. The purpose is reconciliation — letting an agent confirm your listing refers to the same product it saw elsewhere. Any stable identifier is better than none.
- How many product pages should I check?
- A sample across templates, not one page. Completeness usually varies by product type, and a single well-marked hero product is not evidence about the catalogue. Prefero samples multiple product URLs from your sitemap.
Audit your Product schema field by field
The scan samples your catalogue, reports presence per field, and generates the corrected JSON-LD block.