GEO-027·Issue 03·Technical Foundation·27 / 132
Offers, Prices, and Stock: Where AI Is Easiest to Fool
A DTC SKU can carry four competing prices: page, JSON-LD, feed, checkout. A source-of-truth playbook for Offer data, currency, tax, and stock.
Issue focusGet Understood: Product Entities, Structured Data, and the Product Graph
Tuesday morning, a DTC camping-stove seller opens a support thread: a buyer in Munich asked an assistant for a two-burner stove under €100 and got the brand’s own model back, €89 and in stock. The product page says €109 and a two-week ship date. The cause turns up before lunch: the feed last exported Thursday, the page price comes from another rule engine, the stock flag sits behind a six-hour CDN cache. Four systems each published a number that was true once.
An assistant cannot recommend a price it cannot confirm: Offer is the only citable statement of price, currency, stock, and timing, and once two copies disagree you lose the shortlist, not a click.
The model does not verify: it picks the most plausible copy
For one SKU, retrieval sees competing versions of one fact: page price, JSON-LD price, feed, last week’s search cache, a comparison site’s copy. It cannot see your admin and has no rule that the brand’s own site wins. It picks the freshest, best-structured, most-corroborated version, or hedges: “prices may vary.”
Three failures follow. A quote stuck on last week’s promo sends the buyer to a page costing €20 more; stock told backwards walks an agent to checkout and stops there; currency and tax mix across markets. Price and availability are transaction fields, not content: a clumsy sentence can be edited later, a wrong Offer cuts the funnel at the decision.
The usual counterexample: a promo price in the meta description and ads while JSON-LD and the feed keep list price. The page looks clean to a person; the machine reads three numbers. Clicks arrive for a few days, then the model treats you as unverifiable and stays quiet.
Four structural gaps, not four careless mistakes
Treat the drift as operator error and you fix it SKU by SKU forever. Four places produce it; fixing the place is cheaper.
| Source | How it shows up | Who misses it | How to check |
|---|---|---|---|
| Split systems | ERP, PIM, storefront, and feed each compute a price; the promo rule lives in one | Ops and engineering | One value per system, same SKU |
| Time lag | Nightly feed, page cache, last crawl all predate the promo | Engineering | Timestamps on page, JSON-LD, feed |
| Market differences | Currency, VAT in or out, regional pricing, shipping threshold, duties | Market and finance | Load the page in the target locale |
| Level and unit | Variant inherits parent price, per-unit beside per-case, compare-at beside actual | Merchandising | Reconcile twenty multi-variant SKUs |
The fourth is the quiet one. A price typed once on the parent is inherited by every variant page; a case pack priced per unit contradicts a cart that totals per case. Price must hang on the node buyers buy, which depends on how the product graph is built.
Five steps so four outputs read from one source
The goal is not “make the four places agree.” It is to leave no second value to read. Consistency is an architecture outcome, not a discipline.
| Step | Action | Owner | Passes when |
|---|---|---|---|
| 1 Name the source | One system writes price and stock, the rest read; promo rules live only there | Engineering, merchandising | Anyone can name who computes a SKU’s price |
| 2 Model the Offer | price, priceCurrency, availability, priceValidUntil, seller, shipping time; one Offer per variant | Engineering | No missing fields |
| 3 Sync | Event push plus a TTL inside the price promise you keep; invalidate on promo change | Engineering | Four outputs agree within one cache cycle |
| 4 Express | Currency, tax, and shipping threshold in a table; InStock, PreOrder, BackOrder, OutOfStock | Content, market | A native reader sees no ambiguity |
| 5 Verify | Daily sample of page, JSON-LD, feed, checkout; differences alert, not queue | Growth | The gap is measurable, attributable |
Step 3 hides a judgment call in a config value: the cache may live only as long as the price promise you keep, and two promo changes a day behind a 24-hour cache undo the modeling. Step 5 is where teams go through the motions — a zero gap rate is a process metric, not an outcome. If the gap is zero and the assistant still quotes stale prices, look at entity coverage and at third-party pages repeating old numbers.
Example: reconciling twenty SKUs
Example — a hypothetical brand, no real products or figures. Twenty promoted SKUs pulled at the same minute from four outputs show seven disagreements: three feed values lagging the promo, two variants inheriting the parent price, one VAT-inclusive price published as exclusive, one sold-out SKU still InStock.
The fix is not seven edits. A pricing service exposes one quote endpoint that page, JSON-LD, and feed all call. Stock becomes three states with a restock window, and the sold-out page stays up. A market parameter resolves currency and tax; cache invalidation follows the promo calendar; checkout re-validates and says the price moved instead of silently charging it.
Acceptance is seven clean daily samples before promotion resumes. The hard part is getting marketing to accept that promo prices change in the master system, not on the landing page — the problem behind fixing product master data.
Where this breaks
First, categories that convert inside marketplaces: on Amazon or Shopee the platform renders price and stock, so keep admin and feed aligned and leave the template alone.
Second, flash sales and dynamic pricing: real-time means a quote API and a costlier cache, and a price that moves every ten minutes outlives any citation. Publish a range with a validity window; expect some engines to skip you.
Third, custom and quote-based products: publish a “from” price plus the factors that move it, not an invented Offer the buyer meets in the configurator.
Fourth, very shallow stock: InStock buys cancelled orders, and an agent has already promised delivery; prefer BackOrder with a stated window — see variants and out-of-stock pages.
Fifth, an early-stage site: align the visible page and the structured data first, and skip real-time plumbing. That sequence sits in the technical foundation hub.
This month, pick one action: pull twenty promoted SKUs’ visible price, JSON-LD, feed value, and checkout total in the same minute into one reconciliation sheet. While the difference is not zero, do not write new content.