An AI agent understands your product page as an offer when it can answer three questions without guessing: What do I get, who is it for, and exactly what does it cost? These answers belong in the page first as visible text, in a fixed order and with complete price information: amount, unit, period and a tax note. Structured data following Schema.org comes on top as a second layer. It repeats the text, it doesn't replace it.
- The first paragraph names product, audience and starting price in one sentence.
- A price without unit, period and tax note is not a price to an agent.
- "Not included" and "not suitable for" help a comparison as much as the feature list does.
- Whatever is in the markup must also be in the text. Based on observations so far, the text is the source that arrives more reliably.
- If you sell to consumers in Germany, the total price including VAT is mandatory.
How does an AI agent read your product page?
Most agents don't see a layout. They prefer to read the accessibility tree, the structure the browser builds from the HTML: headings, lists, tables, link texts. Slobodan Manic describes it in Search Engine Journal (June 2026) as the same model screen readers have used for two decades. He also warns that a price which only appears after client-side JavaScript may never reach that tree. A price tile recognizable as a "price" only through color and font size stays a loose number there.
ChatGPT's web search receives even less. According to Dan Petrovic's reconstruction, the model gets no raw HTML but converted plain text in excerpts. We lay out our assessment in the article on ChatGPT's own index: we assume the crawler doesn't render JavaScript and that JSON-LD can get lost in the conversion to plain text. That isn't clearly proven. The consequence is clear anyway: deliver the information server-side and write it into the text.
Which blocks belong on the page, and in what order?
Six blocks in a fixed order cover what an agent needs for a comparison. Each block gets a real heading (H2) and stands on its own. An agent splits the page into sections and evaluates each one separately, and a person jumps to the right spot the same way. The example in the table is a made-up software subscription for medical practices.
| Block | What goes in | Example |
|---|---|---|
| Offer sentence (H1 and first paragraph) | Product, audience, starting price | "Online appointment booking for medical practices with up to 5 treatment rooms, from €49 per month plus VAT." |
| Features | List of included features, then explicitly: not included | "Included: online booking, SMS reminders. Not included: billing with health insurers." |
| Prices | Table: plan, amount, unit, period, tax, minimum term | "Basic: €49 per practice per month, plus VAT, cancel monthly" |
| Audience | Who it is for, with a concrete limit, and who it isn't for | "For single and group practices. Not for hospitals with their own patient management." |
| Terms | Region, term, cancellation, setup | "Available in Germany. Setup at no extra cost." |
| FAQ | The questions that really come up before buying | "Can I switch between plans?" |
The order has a reason. The offer sentence at the top is the passage an agent is most likely to take over when it gives someone a short answer. If all it says is "The smart solution for your practice", the agent has nothing to pass on.
How do you write prices an agent can compare?
The most common gap isn't the missing price but the half price. "€49" alone leaves four questions open: per what, for which period, net or gross, and does it apply now or only after a promotion? A person infers that from context. An agent comparing three providers may, in the worst case, put net next to gross.
So write out every price in full, ideally in an HTML table rather than designed tiles: "€49 per practice per month, plus VAT." Tiers, add-ons and discounts get their own rows with their own unit. "Price on request" is allowed, but it takes you out of every price comparison. If possible, give at least a starting price. How to answer cost questions without a fixed list price is covered in Do I have to show my prices publicly?
For the German market there is an additional rule. The Price Indication Ordinance (PAngV) governs price indications by businesses to consumers. Any business that offers something to consumers or advertises to them stating prices must state the total price, and if the price is broken down, the total price has to be highlighted. Under the ordinance, total price means the price including VAT and all other price components. Anyone who intentionally or negligently fails to state it, or states it incorrectly or incompletely, commits an administrative offense.
For the page structure, that means: for B2C, the gross price comes first, and the markup carries the same number. If your offer is aimed exclusively at businesses, give the net price with a visible "plus VAT" and make the audience unambiguous in the audience block.
How do you describe features and audience?
Write down the limits, not just the strengths. Agents work on behalf of people with a concrete requirement: "Appointment software with SMS reminders for a practice with three rooms." A feature list that only lists strengths leaves the agent wondering whether something is missing or just not mentioned.
Two rules help:
- Numbers instead of adjectives. "Up to 5 treatment rooms" instead of "for small and medium-sized practices". An agent can't check "for SMEs" against a requirement.
- Name exclusions explicitly. A sentence like "Not included: …" stops an agent from recommending you for something you don't deliver. That saves you enquiries that never turn into customers.
Keep terms consistent across the whole page. If the plan is called "Basic" at the top, it can't be "Starter" in the price table and "entry package" in the FAQ. To a person that is style, to an agent it is three products.
What does the matching JSON-LD look like?
Structured data following Schema.org describes the same information in a fixed vocabulary, as a second layer beneath the text. An Offer there is an offer to transfer some rights to an item or to provide a service. A UnitPriceSpecification records whether VAT is included (valueAddedTaxIncluded) and which quantity the price refers to (referenceQuantity, with the unit as a UN/CEFACT code). You add the audience via audience, which is also allowed on Product and Service.
For the example from the table, it looks like this:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Practice Scheduler Basic",
"description": "Online appointment booking with SMS reminders for medical practices with up to 5 treatment rooms. Not included: billing with health insurers.",
"audience": {
"@type": "Audience",
"name": "Medical practices with up to 5 treatment rooms"
},
"offers": {
"@type": "Offer",
"eligibleRegion": "DE",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"price": "49.00",
"priceCurrency": "EUR",
"valueAddedTaxIncluded": false,
"referenceQuantity": {
"@type": "QuantitativeValue",
"value": "1",
"unitCode": "MON"
}
}
}
}
</script>
Mind the format: Schema.org requires a dot as the decimal separator and the currency as an ISO 4217 code, so 49.00 and EUR, not "49,00 €". And everything in it also appears in the visible text. Google puts it as a principle: structured data must be a true representation of the page content, and content readers can't see should not be marked up. A price only in the markup is wrong twice over: it doesn't reliably arrive, and it violates the policy.
How do you check the result?
Four checks show whether the page comes across as an offer:
- Load it without JavaScript. If the offer sentence, price table and audience are still there, crawlers that don't execute JavaScript can read them too.
- Read only the headings and first sentences. If that adds up to a complete offer, the structure holds.
- Compare markup and text. Check every number in the JSON-LD against the visible number. Mismatches usually appear when a price changes in the shop and the markup is maintained by hand.
- Ask an AI assistant. Give it the URL with the question: "How much does the product on this page cost per month, including or excluding VAT, and who is it for?" Every uncertainty in the answer points to a gap in the text.
Our Tech Audit checks the technical part automatically, per page type: crawler access, semantic HTML and structured data. It doesn't judge whether the price information is complete in content. That's what steps 2 and 4 are for.
Is adding JSON-LD alone enough?
+
No. With ChatGPT's web search, according to Petrovic's reconstruction, the model receives converted plain text rather than HTML. Whether markup survives in that plain text isn't clearly proven. Visible text is the safer route, even if the model only reads it in excerpts.
Net or gross: what goes on the page?
+
For consumers in Germany, the total price including VAT. For pure B2B offers, the net price with a visible "plus VAT", and in the markup accordingly valueAddedTaxIncluded: false.
Does an llms.txt help for product pages?
+
It can help, but it doesn't replace a well-built page. llms.txt is a proposal by Jeremy Howard (Answer.AI, September 2024): a Markdown file at /llms.txt that lists the most important pages with one sentence of context each. According to Search Engine Journal, Google's John Mueller said in April 2025 that, as far as he knew, no AI service had announced it would use the file.
What comes after a readable product page?
+
The next step is a page where agents act instead of guess. With Web MCP, a website offers clearly defined tools such as "check availability" or "book appointment". The foundation remains a page that reads cleanly.
