As of October 7, 2026, Shifter has the largest pool of live US IPs, more than Oxylabs and Bright Data, at a fraction of the cost.Shifter now has the largest pool of live US IPs

See benchmarks

Knowledge

Public-Interest Price Monitoring: Collecting Evidence That Stands Up to Scrutiny

How consumer groups, journalists and compliance teams monitor prices to test discount claims, and how to collect evidence a retailer cannot dismiss.

Priya Nair

October 11, 2026 · 10 min read

“Was 89.99, now 59.99” is one of the oldest claims in retail, and one of the easiest to fake: raise the price for a few weeks, then “cut” it back to where it was. Consumer organisations, journalists, regulators and retailers’ own compliance teams all monitor prices to catch this. Their findings only matter if they hold up when the retailer pushes back, and retailers do push back.

This guide covers price monitoring done for accountability rather than for pricing strategy: what the rules on discount claims say, how to collect price evidence that survives scrutiny, and code that tests a discount claim against the price history behind it.

This is general information, not legal advice. The rules differ by country, and anyone publishing allegations or bringing a complaint should take legal advice first.

What the rules say about discount claims

Most jurisdictions treat a misleading reference price as a misleading commercial practice. The European Union goes further and sets a specific, testable rule.

  • European Union. Since 28 May 2022, any announcement of a price reduction must show the prior price, defined as the lowest price the trader applied in a period of at least 30 days before the reduction. Member states may set different rules for goods that perish quickly, for products on sale for less than 30 days, and for reductions that increase progressively. In September 2024, the EU’s Court of Justice held in a case involving the retailer Aldi Süd that a reduction advertised as a percentage, or as a promotional “price highlight”, must also be measured against that 30-day lowest price, not the price just before the sale.
  • United Kingdom. Misleading price comparisons are an unfair commercial practice, and since April 2025 the Competition and Markets Authority can decide breaches of consumer law and fine businesses directly, without going to court first.
  • United States. The Federal Trade Commission’s Guides Against Deceptive Pricing treat a former price as a legitimate basis for a comparison when it is the actual, bona fide price at which the article was offered to the public on a regular basis for a reasonably substantial period.

The EU rule is the most useful for monitoring because it turns “is this discount genuine?” into arithmetic: find the lowest price in the 30 days before the sale and compare. That is only possible with a price history, which is why monitoring has to start well before the sale it is meant to test.

What makes price evidence hold up

A retailer faced with a finding will question the data before the conclusion. Evidence holds up when it answers the obvious challenges in advance.

The challengeWhat answers it
”Your data is wrong.”The raw page, captured with its URL, a UTC timestamp and a hash, so the price can be re-read from the original
”You missed days.”Daily observations, with the coverage of each window reported, and no finding made when coverage is too low
”That was a different product.”A stable product identifier (SKU, EAN or the retailer’s own ID) recorded with every observation
”That price was for another region.”The location, store or delivery postcode the price applied to, recorded and held constant
”That was a member or app-only price.”Logged-out collection of the public price, with the conditions shown on the page recorded
”You picked the worst examples.”A published method and a sample defined before the analysis, with all results reported, not just the bad ones

Daily collection matters more here than in most monitoring. Research on online prices shows that weekly sampling catches most regular price changes at large retailers, but a fake reference price can sit inside a single week. Our study of how fast online prices change covers cadence in detail. The capture side, from screenshots to hashing and timestamps, is the same discipline as building court-ready evidence from online listings.

Testing a discount claim

The function below takes a product’s daily price history and an announced reduction, and checks it the way the EU rule does. It refuses to judge when too many days are missing, and it records the coverage so a reader can see how complete the evidence was. A second function stores each observation with a timestamp and a hash of the raw page.

import hashlib
from datetime import datetime, timedelta, timezone


def evidence_record(url, raw_body, price, currency):
    """One observation, stored so that anyone can later check what was seen and when."""
    return {
        "url": url,
        "captured_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
        "sha256": hashlib.sha256(raw_body).hexdigest(),
        "price": price,
        "currency": currency,
    }


def lowest_prior_price(history, start, days=30, min_coverage=0.8):
    """Lowest observed price in the `days` before `start`, if we watched closely enough.

    history: {date: price} from daily observations.
    Returns (price, coverage); price is None when too many days are missing to say.
    """
    window = [start - timedelta(days=d) for d in range(1, days + 1)]
    seen = [history[d] for d in window if d in history]
    coverage = len(seen) / days
    if coverage < min_coverage:
        return None, round(coverage, 2)
    return min(seen), round(coverage, 2)


def check_discount(history, start, sale_price, shown_prior=None, shown_percent=None):
    """Compare an announced reduction with the lowest price in the 30 days before it."""
    prior, coverage = lowest_prior_price(history, start)
    result = {"start": start.isoformat(), "sale_price": sale_price, "lowest_30d": prior,
              "coverage": coverage, "findings": []}
    if prior is None:
        result["findings"].append("not enough observations before the sale to judge")
        return result
    real_percent = round(100 * (prior - sale_price) / prior, 1)
    result["real_percent"] = real_percent
    if sale_price >= prior:
        result["findings"].append("no real reduction: the sale price is not below the 30-day low")
    if shown_prior is not None and shown_prior > prior:
        result["findings"].append(f"shown prior price {shown_prior} is above the 30-day low {prior}")
    if shown_percent is not None and shown_percent > real_percent + 0.5:
        result["findings"].append(f"claims {shown_percent}% off, but it is {real_percent}% off the 30-day low")
    return result

Here are three illustrative offers on the same sale day (made-up histories, not real retailers):

from datetime import date, timedelta

from discounts import check_discount

sale = date(2026, 11, 27)


def daily(prices_before_sale):
    """Daily observations for the days before the sale, oldest first."""
    n = len(prices_before_sale)
    return {sale - timedelta(days=n - i): p for i, p in enumerate(prices_before_sale)}


offers = {
    "kettle":  (daily([49.99] * 40), 39.99, 49.99, 20),
    "blender": (daily([59.99] * 25 + [89.99] * 15), 59.99, 89.99, 33),
    "toaster": (daily([34.99] * 30 + [29.99] * 10), 27.99, 34.99, 20),
}
for name, (history, price, shown_prior, shown_percent) in offers.items():
    result = check_discount(history, sale, price, shown_prior, shown_percent)
    print(name, result["lowest_30d"], f"{result['real_percent']}%", result["findings"] or "ok")
kettle 49.99 20.0% ok
blender 59.99 0.0% ['no real reduction: the sale price is not below the 30-day low', 'shown prior price 89.99 is above the 30-day low 59.99', 'claims 33% off, but it is 0.0% off the 30-day low']
toaster 29.99 6.7% ['shown prior price 34.99 is above the 30-day low 29.99', 'claims 20% off, but it is 6.7% off the 30-day low']
  • The kettle was 49.99 for the whole period and is offered at 39.99. The 20% claim is accurate.
  • The blender was 59.99 for most of the period, rose to 89.99 for the last 15 days, and is “reduced” back to 59.99 with a claim of 33% off. Against the 30-day low it is not reduced at all. This is the classic pattern.
  • The toaster shows a real reduction, but a smaller one than claimed: it was already 29.99 for the ten days before the sale, so 27.99 is 6.7% off, not 20%.

The 80% coverage threshold is a judgement call. Pick one before you start, apply it to every product, and report it alongside the results.

Running a monitoring project

  1. Define the sample first. Choose the retailers, categories and products before the sale season, and record why. A sample chosen after seeing the prices invites the charge of cherry-picking.
  2. Start early. The EU test needs at least 30 days of history before the sale. Start six weeks ahead to allow for gaps.
  3. Collect the public price. Logged out, from a fixed location, using the retailer’s own product pages. Record the location you collected from; prices and promotions are often regional.
  4. Capture everything. Keep the raw page, the parsed price and the evidence record for every observation. Storage is cheap; a missing day is not recoverable.
  5. Check before you publish. Re-read flagged prices from the raw pages by hand. Many apparent violations turn out to be parsing errors, a different variant, or a bundle.
  6. Give the trader a chance to respond. Journalists and consumer organisations usually put findings to the retailer before publishing. Responses sometimes reveal a legitimate explanation, such as a regional price you did not see.
  7. Publish the method. Report the sample, the dates, the cadence, the coverage threshold and the full results.

Collecting responsibly

Public-interest monitoring is still data collection, and the same principles apply. Collect public prices at a modest rate, from product pages a shopper could open, without logging in. Keep personal data out of the dataset entirely: price evidence needs products and prices, not reviewers or customers. Our web scraping best practices cover the rest.

Where prices vary by country, collect from within each market so you see the price local shoppers see. Residential proxies with country targeting are the usual way to do that at scale, and keeping the location fixed for each market is as important as the cadence.

FAQ

What is the 30-day rule for price reductions?

In the European Union, an announcement of a price reduction must show the prior price, which is the lowest price the trader applied during at least the 30 days before the reduction. The EU’s Court of Justice confirmed in 2024 that percentage reductions must be calculated from that price.

How can I tell whether a discount is fake?

Track the product’s price daily for at least 30 days before the sale. If the sale price is not below the lowest price in that period, or the claimed percentage is larger than the real reduction from that lowest price, the discount claim is likely misleading under EU rules.

How long do I need to monitor prices before a sale?

At least 30 days for the EU test, and in practice around six weeks so that a few missed days do not leave the window incomplete.

Can price monitoring evidence be used in a complaint?

It can support one, if it is well documented: raw pages, timestamps, product identifiers, the location the price applied to and a published method. Take legal advice before filing a complaint or publishing allegations.

The bottom line

Fake discounts are easy to make and, with the right data, easy to test. The EU’s 30-day rule turns a discount claim into a comparison against a price history, so monitoring has to start well before the sale. Collect daily, from a fixed location, logged out, and keep the raw evidence for every observation. Refuse to judge where the data is thin, check every finding by hand, and publish the method. Evidence collected that way is hard to dismiss.

Sources and references

Ready to get started?

Try Shifter's residential proxies, 205M+ IPs, 195+ countries, from $0.10/GB.

Get Started