JSON-LD Product: price and currency AI can read
Updated 2026-08-03
Why an AI agent needs structured data
A shopper asks ChatGPT or Perplexity: "how much is this model, and is it in stock?" To answer, the model has to name a specific price, currency and stock status. On a normal HTML page the price can sit anywhere and in any shape — "1,299 lei", "1299", "from 999". The agent should not have to guess, and if the data reads poorly it will simply skip your product.
JSON-LD Product is a machine block where the store states it plainly: the price is this, the currency is this, availability is this. The agent reads it and names the figure with confidence — and your product lands in the answer instead of a competitor's.
This is the product category — 30% of the AI-readiness score, the heaviest of the five weights. In our rating of 63 stores across Moldova and Romania the median is 38 out of 100, and weak product data is one of the main reasons for low scores.
AI bots already read product pages at scale: our AI Traffic Index counted about 1,005,146 bot hits over two weeks on a three-store panel, and the single most-read product drew 73,715 requests. The question is not whether agents reach your product page — it is whether they can name your price once they do.
What the minimal markup looks like
The block goes into the <head> or <body> of every product page:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Example Runner sneakers",
"image": "https://example.com/img/runner.jpg",
"sku": "RUN-42",
"offers": {
"@type": "Offer",
"price": "1299.00",
"priceCurrency": "MDL",
"availability": "https://schema.org/InStock"
}
}
</script>
Three fields inside offers decide everything. Let's break them down.
The three fields that name the price
| Field | What to put | Example |
|---|---|---|
price | a number, no currency symbol, no spaces, dot separator | "1299.00" |
priceCurrency | an ISO 4217 code in a separate field | "MDL", "RON", "EUR" |
availability | a schema.org URL, not free text | "https://schema.org/InStock" |
price is the number alone. priceCurrency is the currency, kept separate: MDL for Moldova, RON for Romania. Without it "1299" is meaningless — 1299 of what? availability is a status pointing to the vocabulary, InStock or OutOfStock, and the agent uses it to decide whether the product is even worth recommending.
Common mistakes
- No currency.
priceis there,priceCurrencyis not. The model sees a number with no unit — it either drops the price or guesses the currency and risks showing the shopper the wrong sum. - Availability as a string.
"availability": "in stock"instead of the URLhttps://schema.org/InStock. Free text is not parsed — use the vocabulary code. - Price not in the markup. The price is drawn as an image or injected by JS after load. A crawler that does not execute JavaScript sees an empty slot. The price must sit in the JSON-LD as text.
- Markup price ≠ page price. Rich Results Test and the models cross-check the two. A mismatch reads as distrust, and at worst Google flags the markup as invalid.
- One price for all variants. Sizes and colours have different prices, but the markup carries one static value. Use variants (
hasVariant) or a range, or the agent will quote the wrong one.
How to check
- Open the product page, view the source (
Ctrl+U) and findapplication/ld+json— the block must be present as text. - Paste the URL into Google Rich Results Test — it shows whether
Productis recognised and which fields it read. - Run the free Botmetria audit on your domain. It checks JSON-LD Product across the catalog — whether
price,priceCurrencyandavailabilityare present and valid — and shows the product category score (30% of the total). Score bands:>70green,41–70yellow,≤40red.
If you run WooCommerce, the Botmetria plugin outputs correct JSON-LD Product with price, currency and availability itself, pulled from the product record — no hand-editing the theme.
Next on the topic — the guide on llms.txt for your store: another way to help AI understand your catalog.
FAQ
Do I need JSON-LD if the price is already visible on the page?
A human reads the price with their eyes; an AI agent or crawler does not, especially if it is drawn as an image or injected by JS. JSON-LD states the price, currency and availability as text in one machine-readable place, so the agent names them confidently instead of guessing.
Which currency code for Moldova and Romania?
Moldova is MDL, Romania is RON, and EUR if you sell in euros. These are ISO 4217 codes, and priceCurrency must be the code itself, not a "lei" or "€" symbol.
Does JSON-LD Product affect the Botmetria score?
Yes, directly. It is the product category — 30% of the AI-readiness score, the biggest weight. Correct price, priceCurrency and availability across the catalog raise it; their absence is a main reason the median across 63 stores is only 38 out of 100.
Does WooCommerce add the markup by itself?
Stock WooCommerce does not always output it fully, while the Botmetria plugin emits correct JSON-LD Product with price, currency and availability from the product record automatically — no manual theme editing.
Related guides
- ChatGPT says "out of stock" but the item is available
- ChatGPT shows outdated prices: why it happens and how to fix it
Check your store for free
A 60-second audit shows how ready your store is for AI agents — and exactly what to fix first.