Recently Updated: 18 min read

Page, Markup and Feed Consistency: Price and Stock Audit

Page, Markup and Feed Consistency: Price and Stock Audit

A laptop stand listing shows its price and stock status in three places: the product page a shopper sees, the structured data embedded in that page, and the feed sent to Merchant Center. If the three disagree, the listing is exposed to disapproval, because Merchant Center asks for the same availability across the landing page, the checkout pages and the data source. The fix is one source record that produces all three outputs, plus a short, repeatable check that reads a sample of products in all three places. If you run a catalog or manage a seller feed on a marketplace, that routine lets you find a mismatch before a shopper or a review does.

One record, three renderings

Think of the page, the markup and the feed as three renderings of the same record. Each has its own reader, its own refresh timing and its own cache, which is exactly why they drift apart.

Where each reader looks

OutputRead byFields that matter here
Product pageThe shopperDisplayed price, stock label, add to cart button, checkout total
Structured dataSearch crawlersprice, priceCurrency, availability, priceValidUntil inside the offer
FeedMerchant Centerprice and availability attributes

Choosing the source of truth

Practical suggestion: name one system that owns price, currency and stock status for every offer, and make the page template, the JSON-LD block and the feed generator read from it. A price typed by hand in one place and generated in the other two is the shortest route to a mismatch. On a marketplace with several sellers, the source record is the seller's current offer, not the product card, since each offer carries its own price and stock.

For the choice between product snippet and merchant listing markup, see the marketplace structured data comparison.

What the Merchant Center pages require

The Availability [availability] help page (Opens in a new tab) states that the values in your data source should match the information on your website, and that availability must match across the landing page, the checkout pages and the data source. It adds that a mismatch in one of these will trigger a product disapproval. The page spells out both directions: a product that is out of stock on the landing page or at checkout but marked in stock in the data is disapproved, and so is a product that is in stock on the page but marked out of stock in the data.

The Price [price] help page (Opens in a new tab) asks for an amount and currency that match the price on the landing page and the checkout pages. It also asks you to show the price in the currency of the target country prominently on both, and not to change the price on the landing page based on a user's location. It says a product that does not meet these requirements is disapproved and that you are told in your Merchant Center account.

Tax and shipping on the price

The price page treats tax by country. For the United States and Canada it asks you to leave tax out of the price. For countries it lists as applying VAT or GST, it asks for a price that includes the tax. Shipping stays out of the price. The country lists and rules can change, so read the current page for your target country before you compare the page price with the feed price.

What the structured data page adds

The merchant listing structured data page (Opens in a new tab) makes a price property (price or priceSpecification.price) and priceCurrency required. For merchant listing experiences the price must be greater than zero. The availability property is recommended, and the page lists these values: BackOrder, Discontinued, InStock, InStoreOnly, LimitedAvailability, OnlineOnly, OutOfStock, PreOrder, PreSale and SoldOut. It tells you not to specify more than one value. It also says a listing may not display if priceValidUntil points to a past date.

The page does not state that the markup price must equal the visible price. The matching rule lives in the Merchant Center pages. Because markup is the machine-readable form of the same product data, practical suggestion: write the same value into the markup that the shopper sees. The ecommerce structured data page (Opens in a new tab) names Product and ProductGroup as the relevant types and points to a separate Merchant Center setup for structured data.

A laptop stand walked through three places

Example scenario: a marketplace seller lists an aluminium folding laptop stand in two colours and as a bundle with a carry case. The page shows the selected colour, its price and a stock label. The JSON-LD block was written when the template was built and reads the default colour. The feed lists the stand once, at the lowest variant price, with total stock across colours.

A shopper picks the bundle. The page shows the bundle price and "in stock". The markup still carries the single stand price from the default colour, and the feed shows the lowest price. All three differ, yet each looks plausible on its own. Only a side by side reading reveals it.

What the walk through finds

  1. Open the page in a private window, select the bundle and note the displayed price and stock label.
  2. Add it to the cart and note the price, currency and stock state on the checkout pages.
  3. View the page source and read the offer in the JSON-LD block for the same selection.
  4. Find the same item in the feed and read price and availability.
  5. Write the four readings in one row and mark which differ.

The row points to the template: the markup is built from the default selection, and the feed is built from a parent record. The fix belongs in the source record and in how both outputs are generated from it, not in a hand edit of one price.

Where the drift starts

Mismatches come from a handful of mechanisms. Naming the mechanism is what lets you repair it once.

Refresh timing

The page changes the moment the record changes. The feed changes when it is next generated and fetched. Between the two, the feed carries the old value. The availability page says prices and availability can change frequently and asks you to provide up-to-date data. It mentions automatic item updates as a way to avoid availability mismatches, and the price page says Google reads schema.org microdata on the landing page to refresh price data. It adds that updates happen only when Google crawls the page, so product data still has to be resubmitted regularly.

Caching layers

A cached page can show last week's price while the feed carries today's. The reverse happens too: the page is fresh while the JSON-LD block comes from a template fragment cached separately. Test the page output and the markup block independently, not only the visible price.

Price format and tax treatment

One output may include tax while another excludes it, or the currency code may be missing in the markup. The difference can be small and still counts as a mismatch. For multi-currency pages, see the price markup guide.

Variant logic

The page shows the selected variant while the markup and the feed describe the parent. The availability page asks that a variant's availability in the data source match its own landing page. For picking the right stock value per case, see the availability markup guide.

Where the markup is produced

The merchant listing page says dynamically generated markup can make Shopping crawls less frequent and less reliable, which matters for fast-changing content such as availability and price. It recommends putting Product structured data in the initial HTML for best results. If the markup is produced with JavaScript, it also advises making sure the server has enough computing resources to handle increased traffic from Google, and it suggests submitting a sitemap to keep Google informed of changes. Practical suggestion: render the price and stock block on the server, in the first response.

Designing the sample

Checking every product every day is not realistic. A sample estimates how healthy the catalog is at a workable cost.

What to include

The documentation has no statement on sample size. Practical suggestion: draw a few products from each product group and each page template, and add recently changed products and products in an active promotion. For a laptop stand catalog the groups might be single stands, bundles with accessories, multi-colour items and low-stock items. A template fault shows up across a group, and a record fault shows up in a single product.

GroupWhy it is sampled
Items in a promotionThe price changes at the start and the end
Low-stock itemsStock status changes with each sale
Items with colour or bundle optionsVariant logic is where outputs split
Newly added itemsFirst publication exposes template faults
Long-unchanged itemsRecords that nobody updates go stale

Choosing the rhythm

Because price and stock change quickly, a weekly read is a workable baseline. Add an event-driven read after a promotion starts, after it ends, after a bulk price import and after any template change. Practical suggestion: schedule the day after a promotion ends as its own check, because the return from a sale price to the regular price is a moment when the outputs can disagree.

Writing the verdict column

Do not leave the verdict as a free comment. Use a short fixed vocabulary: match, price differs, stock differs, currency or tax differs, date differs. A fixed vocabulary lets you count verdicts at the end of the month. It also forces the reader to decide, because "looks fine" is not on the list. When a row fails, add the cause tag in the next column so the log answers both what differed and why.

What a clean week looks like

A week without a failed row does not prove the catalog is clean, it proves the sample was clean. Rotate the sampled items so that the same products are not read every week. Keep a fixed core of promotion and low-stock items, and replace the rest of the sample on a schedule you write down.

Records outside the sample

Run simple queries on the source record for the products you do not read by hand: zero or empty prices, negative stock, and sale prices whose end date has passed. The results tell you which items to read next.

The side by side log

Use one sheet with one row per product and a fixed set of columns, so the check does not depend on who runs it.

Item IDPage priceMarkup priceFeed pricePage stockMarkup stockFeed stockVerdict
Example: LS-02 (example scenario)Shown on the pageOffer priceprice attributeButton stateavailabilityavailabilityMatch, or which column differs

If only one column differs, the problem sits in that output's update path. If all three differ, question the source record.

Reading the markup

Find the JSON-LD block in the page source. Read the offer's price, priceCurrency and availability, plus priceValidUntil if present. A promotion that ended last week but left a past date in priceValidUntil can hide the listing, according to the merchant listing page.

A decision rule for which value is right

Once you find a mismatch, decide which output is wrong before you touch any of them.

  1. Read the checkout pages first. What the shopper will pay and whether the item can be bought is the reference value.
  2. Compare that value with the source record. If they differ, fix the record.
  3. If the record and checkout agree, regenerate whichever of the markup or the feed differs.
  4. If the product page and checkout differ, the cause is a template or a cache. Resolve that before regenerating markup or the feed.
  5. After the fix, read the same item in all three places again.

The order of repair and resubmission

The order matters, because fixing the downstream copy first lets the next generation overwrite it with the old value.

  1. Correct the source record.
  2. Clear the cache and reload the page.
  3. Confirm in the page source that the markup now carries the new value.
  4. Regenerate the feed and send it, or wait for the next scheduled fetch.
  5. Check the product status in Merchant Center again. Since the price page says automatic updates occur only when Google crawls the page, do not expect an instant change.
  6. Record the result and put the item on next week's list.

Stock states and what they require

Stock moves with every sale, so it deserves its own checkpoints: sold out, coming back, and temporarily closed.

Sold out

When the stand sells out, the page, markup and feed should move together. The availability page treats a mismatch in either direction as a reason for disapproval, so define one rule for what counts as sold out and apply it to all three.

Back soon

The availability page says preorder should be used only for new products that have not been released yet. For a product that is out of stock but will return and that you still take orders for, it points to backorder instead. Both need an availability date, and the page says the expected shipping date must be shown on the landing page. A date written only in the feed is a separate mismatch.

Closing the shop for a while

The page says not to set availability to out_of_stock when you take your site down for maintenance or a holiday, and suggests excluded destination instead. That keeps you from flipping every product and then having to flip each one back.

Low stock and partial stock

A laptop stand with two units left raises a practical question: is it in stock? As long as a shopper can buy it, the page, markup and feed should all say it is. The merchant listing page also lists LimitedAvailability as an availability value. Practical suggestion: decide in advance whether you use it, and if you do, make sure the feed and the page express the same state. If you do not use it, do not let the markup alone carry it.

Stock held in more than one warehouse

If stock is counted per warehouse, the page may show the total while the feed reads only one location. Write down which count the shopper's order draws from, then make all three outputs read that count. Example scenario: the seller holds stands in two storage locations. The page adds both, the feed lists only the first, and the item shows as sold out in the feed while the page still lets shoppers order.

A promotion calendar for price checks

Promotion dates are known in advance, which makes promotions a predictable source of price mismatches.

  1. The day before, confirm the source record holds the sale price with the right start date.
  2. At the start, read the sale price on the page, in the markup and in the feed.
  3. Find out when the feed will next be fetched. If it falls after the start, note the gap.
  4. At the end, confirm that the price, priceValidUntil and the feed all returned to the regular value.
  5. On the next working day, refill the log for the promotion items.

Example scenario: a two-day sale on the aluminium stand starts at midnight. The page shows the sale price immediately, but the feed is fetched once a day, so for part of the first day the feed shows the regular price. If the seller knows the fetch time in advance, the sale can start shortly before it, or the feed can be refreshed by hand.

After a bulk update

A bulk price change, a stock import or a template release touches a large batch of products at once, so do not wait for the weekly read.

  1. Write down what changed: which products, which field, what time.
  2. Pick five products from the batch, including the first and last in processing order.
  3. Read each in the three places and fill the log.
  4. If one fails, pause the rest of the run and find the cause.
  5. Read the same five again after the fix.

Bulk jobs run through a set of records in order. If a job stops partway, early records are updated and late ones are not. Reading the first and last record is the cheapest evidence of whether the job finished.

A weekly routine that stays short

StepActionOutput
1Open the product issues in Merchant CenterPrice and availability warnings
2Read sampled items in the three placesLog rows
3Compare this week's price and stock changes with the source recordList of changed items
4Check promotions that endedConfirmation of return to regular price
5Tag each mismatch with a causeTiming, cache, format or variant

Why tag the cause

After a month the tags show which mechanism repeats. Timing tags point to a shorter fetch interval or cache lifetime. Variant tags point to the template. Without tags every mismatch looks new, and the same fault returns.

Cross reading with Merchant Center

A warning in the account is a confirmation of your own sample. Match it to the item ID and the log row. If your sample finds a difference that the account has not flagged, you still have time to fix it. For the wider range of feed errors, see the Merchant Center product data errors guide.

Leaving the routine with one person

Keep the log in a shared file and make any two people able to run the weekly read, so a holiday does not stop the check.

Mistakes that leave a mismatch in place

Checking only the product page

The availability page counts the checkout pages and the data source along with the landing page. A check that stops at the product page covers a third of the rule.

Treating a unit price as the product price

A stand page can show a list price, a sale price and an instalment amount side by side. Note which one the markup carries and which one the feed carries. A mismatch exists when the markup holds the instalment amount and the checkout asks for the full price.

Comparing display text rather than values

A page may display 1,250.00 while markup carries 1250.00. These are the same amount. Compare the numbers, then the currency code, then the tax treatment.

Repairing the feed and leaving the template

A feed edit is overwritten at the next generation if the template or record caused the fault. Find the origin first.

Leaving an expired date in the markup

A past priceValidUntil can stop the listing from displaying, according to the merchant listing page. Update or remove it when a promotion ends.

Checklist

  • One source record owns price, currency and stock status.
  • Page, JSON-LD and feed are generated from it.
  • The sample includes every group, template, promotion and recent change.
  • Page, checkout, markup and feed are read separately for each sampled item.
  • priceValidUntil carries no past date.
  • Tax treatment matches the target country's rule on the price page.
  • Repairs follow the order record, cache, markup, feed.
  • The weekly read and the day-after-promotion read are on the calendar.

Frequently Asked Questions

Does a price or stock mismatch affect the listing directly?

The availability page says a mismatch between the landing page, checkout pages and data source will trigger a product disapproval. The price page says a product that does not meet its requirements is disapproved.

Can the markup price differ from the page price?

Merchant Center asks that product data match the website. Practical suggestion: keep the markup identical to the displayed price.

What sample size should I use?

Practical suggestion: take a few items from each group and template, and add recently changed and promotion items.

Do automatic item updates make the check unnecessary?

No. The availability page presents them as an option that helps avoid mismatches. The price page says updates happen only when Google crawls the page and that product data should still be resubmitted regularly.

Can I change a price based on the visitor's location?

The price page asks you not to change the product price on the landing page based on a user's location.

Is JavaScript-generated markup a problem?

The merchant listing page says dynamically generated markup can make Shopping crawls less frequent and less reliable, and recommends putting Product structured data in the initial HTML.

Conclusion

Page, markup and feed have to tell one story. Make a single record the source, sample every group and template, read the checkout, the markup and the feed side by side, and repair in the order record, cache, markup, feed. A short weekly read that also covers the day after each promotion catches a mismatch before it becomes a disapproval.

If you want to place your products where shoppers browse, see the available ad spaces.

0 Comments

No comments yet for this article.

Post a comment

Please log in to leave a comment. Login