Your pricing page is read more often by machines than any other page you own, including your homepage. The reason is dull. Pricing is the question buyers ask about a named vendor more than any other, it gets asked at the point where the decision is actually made, and most companies answer it in a format no parser can read.
The gap between those two facts is where the damage happens. An engine asked what you cost will answer. If it cannot read your page it will answer from a review site, a three year old blog comparison, or a confident guess. None of those is under your control and one of them is usually wrong.
Why pricing sits where it does
Think about where questions land in a buying process. Early questions are about categories, and engines answer those from general knowledge. Late questions are about specific vendors and specific numbers, and those can only be answered from retrieved pages. Pricing is the archetypal late question.
It is also the question buyers are least willing to work for. Harvard Business Review’s research on B2B purchasing found that the buyers who rated information as easy to find were dramatically more likely to complete a purchase without regret, and that making information easier to use beat making it more persuasive. That was written about human buyers reading websites. It describes machine readers even better, because a machine will not scroll, will not click a toggle, and will not wait for a script.
The asymmetry that should worry you. A human who cannot find your pricing might email sales. An engine that cannot find your pricing will state a number anyway, sourced from somewhere else, to a prospect who will never tell you it happened.
The three ways a pricing page becomes unreadable
We have looked at a lot of these. Nearly every failure is one of three, and none of them is about writing.
The prices are rendered by JavaScript. Plan tiers and figures arrive from an API after the page loads, often with a monthly and annual toggle that swaps them client side. Rendering behaviour varies by crawler and by circumstance, and what gets into the initial HTML response is the only part you can rely on. If the number is not in the source, treat it as absent until proven otherwise.
The detail is behind an interaction. Accordions, tooltips, hover states and comparison drawers hide exactly the information buyers ask about, which is what is included at each tier. Content that requires a click to reveal is often present in the DOM and, even when it is, it arrives stripped of the heading that gave it meaning. A parser gets Unlimited with nothing attached.
The page says contact us. This is a decision rather than a bug, and it has a cost that is now much larger than it was three years ago. When there is no number, the engine finds one elsewhere. We have seen engines quote a per seat figure from a 2021 press release to a prospect evaluating a product that repriced twice since.
| What a buyer sees | What a parser usually gets | Result in an answer |
|---|---|---|
| A clean three column plan table | Three plan names, no figures | Names your tiers, hedges on cost |
| Monthly and annual toggle | Whichever state renders server side, unlabelled | States a price with the wrong billing period |
| Feature list in an accordion | A list of features with no tier attached | Claims a feature is in the free plan |
| Contact us for pricing | Nothing | Quotes a third party estimate as fact |
| From $X per user per month | From $X per user per month | States it correctly and cites you |
The quickest way to see which row you are in is to ask four engines what you cost and read the answers side by side. When they disagree with each other, something other than your pricing page is being used. Our free AI visibility check runs exactly that and shows you which source each engine leaned on, which is usually the surprising part.
What to publish when you genuinely cannot publish a price
Plenty of businesses have real reasons not to put a number on a page. Enterprise deals with negotiated terms, usage models where the number is meaningless without volume, regulated markets. Fine. You can still make the page answerable, because the thing that is missing is not precision, it is structure.
Five things are publishable even when the final figure is not.
- The unit. Per seat, per workspace, per thousand events, per gigabyte processed. This alone resolves most of the confusion, because it tells the engine what kind of number a price even is for you.
- A floor. The smallest realistic annual commitment. Programmes typically start at around twenty four thousand a year is a publishable sentence and it filters your inbound more effectively than any qualification form.
- What moves it. Seats, volume, environments, support tier, data residency. Name the three or four variables that actually change the quote.
- What is always included. The things every customer gets regardless of tier. This is the part buyers most often get wrong about you, and it is free to state.
- What is never included. Implementation, migration, premium support. Saying this plainly costs you nothing and prevents the comparison where a competitor looks cheaper because they bundled it.
A page carrying those five facts will be quoted accurately by an engine even without a single dollar figure. A page carrying none of them will be answered from a review site. That is the actual choice, and it is not between transparency and discretion.
Vocabulary matters here more than most places, because pricing terms are used inconsistently across the industry. A seat in your product and a seat in a competitor’s may be different things. Defining your own terms somewhere machine readable is the cheapest way to stop the two being conflated, which is one of the arguments for keeping a glossary page.
The markup, which takes twenty minutes
Schema does not make the page rank. What it does is remove the inference step. Without markup a parser has to work out that $49 in a styled cell belongs to the Pro tier, is per user, is monthly, and is in US dollars. With markup it does not have to work out anything.
The types you want are Offer and PriceSpecification, documented in the structured data guidance for products and offers. Keep the markup and the visible text identical. If they ever diverge you have built a cloaking problem in exchange for nothing.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Acme Analytics Pro",
"description": "Usage analytics for product teams, billed per active seat.",
"brand": { "@type": "Brand", "name": "Acme" },
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://example.com/pricing/",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"price": "49.00",
"priceCurrency": "USD",
"unitText": "active seat",
"billingDuration": 1,
"billingIncrement": 1,
"referenceQuantity": {
"@type": "QuantitativeValue",
"value": 1,
"unitCode": "MON"
}
}
}
}
The unitText and referenceQuantity fields are the ones people skip and they are the ones carrying the meaning. A price without a unit and a period is not a price, it is a number. Which schema types are worth this effort in general, and which are decoration, is covered in what matters and what does not in schema for AEO.
Most pricing page problems are twenty minutes of work that nobody owns.
The fix is rarely a project. It is usually server rendering one component, moving four sentences out of an accordion, and adding a block of markup. The reason it does not happen is that pricing sits between product, marketing and engineering, so it belongs to nobody in particular.
If it would help to have the specific failure named and evidenced before you go asking for engineering time, that is what a free visibility check from us produces. You get the answers engines currently give about your pricing, the source each one used, and the exact reason your page lost.
The sentence test
Here is the whole thing reduced to something you can check in a minute. Somewhere on your pricing page, in the raw HTML, there should be a sentence a machine could lift out and hand to a model without modification.
Something like this. Acme Analytics starts at forty nine dollars per active seat per month billed annually, with a minimum of ten seats. Implementation is a one off charge from two thousand dollars and is not included.
That sentence is unglamorous and no designer will thank you for it. It is also self contained, contains every variable, and survives being separated from its page, which is the property that decides whether a passage gets retrieved at all. The underlying mechanics are in how retrieval decides which sources to pull, and pricing pages fail the first gate more often than any other page type we look at.
Right click, view source, search for your price. If it is not there as text, nothing else on this page matters yet.
Staying on the right side of the claims you make
One thing worth saying plainly because it costs people money. If you publish a starting price, the conditions attached to it need to be visible in the same place, not in a footnote a parser will never associate with it. Regulators have been clear for a long time that qualifying terms have to be clear and conspicuous rather than buried, and an engine quoting your headline figure without a condition it could not see is a version of that problem you did not anticipate.
The practical version is simple. Put the conditions in the same sentence as the number. It protects you and it happens to be exactly what makes the passage self contained.
How to tell whether it worked
Do not look at traffic. Pricing page sessions will not move and that is not the mechanism.
Ask the four engines what you cost, once a month, logged out, and record the answer verbatim. You are watching for three transitions. From no answer to an answer. From an answer sourced elsewhere to an answer sourced from you. From a hedged answer to a plain one.
Expect four to eight weeks for the first, longer for the third, because moving from hedged to plain requires the engine to treat your page as the settled source rather than one of several. That is a corroboration effect and it depends partly on third parties. The same dynamic decides whether you get named at all, which we went through in how ChatGPT picks which companies to name.
Four things people do that make it worse
Putting the price in an image. It happens more than you would think, usually in a redesign where the pricing table became a component that renders to canvas. The number is now invisible to everything except a human eye.
Using a different price in the markup than on the page. Usually accidental, usually because the markup was written once and the page was updated twice. Audit both together or not at all.
Hiding pricing from logged out visitors. Every crawler is a logged out visitor. If pricing appears only after signup, pricing does not exist as far as any engine is concerned.
Treating the page as a conversion asset only. Pricing pages get optimised for the humans who reach them and never for the far larger number of people who ask about pricing without ever arriving. Those people are getting an answer from somewhere. The page’s job now includes being that somewhere.
Related reading
- The AEO technical playbook. Where the pricing page sits in the order of work, alongside everything else worth doing.
- Your about page is an entity document. The same treatment applied to the other page every engine reads and nobody maintains.
- What AEO is. The full picture if this is the first thing of ours you have read.
One last thing worth saying. View source on your own pricing page and search for the number before you do anything else on this list. That single check separates a content problem from a rendering problem, and those have different owners, different timelines and very different costs. Most teams we look at have the second one and had been budgeting for the first.
