Fake Discount Checker: EU 30-Day Prior Price avatar

Fake Discount Checker: EU 30-Day Prior Price

Pricing

from $3.00 / 1,000 results

Go to Apify Store
Fake Discount Checker: EU 30-Day Prior Price

Fake Discount Checker: EU 30-Day Prior Price

Check 'was' and strikethrough prices against your own price history from repeated scraper runs. Flags reference prices above the 30-day prior low (EU Omnibus rule), raise-then-discount patterns, reference prices never charged, permanent sales and wrong % badges. Quotes dates and sources.

Pricing

from $3.00 / 1,000 results

Rating

0.0

(0)

Developer

Ultimate Foresight Inc

Ultimate Foresight Inc

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 hours ago

Last modified

Share

Check "was" prices and % off claims against the real price history your scraper collected. The Fake Discount Checker applies the EU 30-day prior price rule (Price Indication Directive Art. 6a, added by the Omnibus Directive) and the FTC guide on former price comparisons (16 CFR 233.1): it finds reference prices above the lowest price of the previous 30 days, prices raised just before a "sale", was prices never or only briefly charged, discounts that never end and % off claims that don't match the prices. Feed it products with history or two or more datasets from a scheduled price scraper. Click Start with the prefilled example to see it work.

This compares the shown reference price with the prices observed in the data you supply. Gaps in your history can hide lower prices, and the rules have exceptions (for example new products, perishable goods or progressive discounts). Signals are possible issues, not a finding that any seller broke a law. Not legal advice; every row carries this disclaimer.

What does the Fake Discount Checker do?

  • ✅ Reference above the 30-day low (high when there's no real reduction): the was price is higher than the lowest price seen in the 30 days before the price drop, with the actual reduction against that low.
  • ✅ Raised before the discount (high): the price went up and then came back down as a "discount", the pattern in CJEU case C-330/23 (Aldi Süd).
  • ✅ Reference never or briefly charged: the was price was never observed, or only for a short time, before being used as a comparison (FTC 16 CFR 233.1).
  • ✅ Continuous discount: the same "sale" price shown for most of the history.
  • ✅ Claimed % mismatch: the % off shown doesn't match the current and was prices.
  • ✅ History checks: too little or partial history in the window is reported instead of guessed.
  • ✅ Output per product: assessment, currentPrice, referencePrice, claimedDiscountPct, computedClaimPct, priceSince, prior30DayLow, prior30DayLowDate, actualDiscountVs30DayLowPct, observations, signals (signalId, severity, message, sourceUrl), checkedAt and a disclaimer.

Who is it for?

  • Retailers and marketplace sellers checking their own sale prices before the EU, a regulator or a competitor does.
  • Price monitoring and comparison services adding a fake-discount flag to their data.
  • Consumer groups, researchers and journalists studying Black Friday and sale-event pricing.
  • Brands watching how resellers advertise discounts.

How to check discount claims

  1. Click Start with the prefilled example (a kettle raised from 39.99 to 59.99 and then "discounted" back, and a toaster with a real reduction).
  2. Replace it with Products that have a history of {date, price, wasPrice, discount}, or Snapshots with one row per product per day.
  3. Or select two or more datasets from the same price scraper scheduled daily. Dates come from a date field such as scrapedAt or from the dataset's creation date; use Field map for price and ID fields.
  4. Keep Window (days) at 30 for the EU rule, or change it for other rules.
  5. Turn on Only save rows with findings; you only pay for saved products.

Input example

This is the prefilled input:

{
"products": [
{
"id": "EXAMPLE-KETTLE",
"title": "Example electric kettle",
"history": [
{
"date": "2026-09-01",
"price": 39.99
},
{
"date": "2026-09-08",
"price": 39.99
},
{
"date": "2026-09-15",
"price": 39.99
},
{
"date": "2026-09-22",
"price": 59.99
},
{
"date": "2026-09-29",
"price": 59.99
},
{
"date": "2026-10-06",
"price": 59.99
},
{
"date": "2026-10-13",
"price": 39.99,
"wasPrice": 59.99,
"discount": "-33%"
}
]
},
{
"id": "EXAMPLE-TOASTER",
"title": "Example toaster",
"history": [
{
"date": "2026-09-01",
"price": 49.99
},
{
"date": "2026-09-08",
"price": 49.99
},
{
"date": "2026-09-15",
"price": 49.99
},
{
"date": "2026-09-22",
"price": 49.99
},
{
"date": "2026-09-29",
"price": 49.99
},
{
"date": "2026-10-06",
"price": 49.99
},
{
"date": "2026-10-13",
"price": 34.99,
"wasPrice": 49.99,
"discount": "-30%"
}
]
}
]
}

Dataset mode:

{"datasetIds": ["DATASET_ID_DAY_1", "DATASET_ID_DAY_2", "DATASET_ID_DAY_30"], "fieldMap": {"id": "asin", "price": "price.value", "wasPrice": "listPrice.value", "date": "scrapedAt"}, "windowDays": 30, "onlyFlagged": true}

Output example

Real output from a run of the prefilled input on 2026-10-30 (long finding lists are shortened here; the run returns all of them):

[
{
"productId": "EXAMPLE-KETTLE",
"title": "Example electric kettle",
"url": null,
"currency": null,
"observations": 7,
"firstSeen": "2026-09-01",
"lastSeen": "2026-10-13",
"currentPrice": 39.99,
"referencePrice": 59.99,
"claimedDiscountPct": 33,
"computedClaimPct": 33.3,
"priceSince": "2026-10-13",
"prior30DayLow": 39.99,
"prior30DayLowDate": "2026-09-15",
"priorWindowObservations": 4,
"actualDiscountVs30DayLowPct": 0,
"assessment": "claim conflicts with observed price history",
"signals": [
{
"signalId": "reference_above_30_day_low",
"severity": "high",
"message": "Reference price 59.99 is higher than the lowest price seen in the 30 days before the reduction (39.99 on 2026-09-15). Against that low, the actual reduction is 0% (no real reduction).",
"sourceUrl": "https://eur-lex.europa.eu/eli/dir/1998/6/oj",
"windowStart": "2026-09-13",
"windowEnd": "2026-10-12"
},
{
"signalId": "price_raised_before_discount",
"severity": "high",
"message": "The price was 39.99 on 2026-09-15, rose to 59.99 on 2026-09-22, then was shown as a discount to 39.99 from 2026-10-13.",
"sourceUrl": "https://curia.europa.eu/juris/liste.jsf?num=C-330/23"
}
],
"windowDays": 30,
"checkedAt": "2026-10-30T18:52:08+00:00",
"disclaimer": "Automated comparison of the shown reference ('was') price with the prices observed in the..."
},
{
"productId": "EXAMPLE-TOASTER",
"title": "Example toaster",
"url": null,
"currency": null,
"observations": 7,
"firstSeen": "2026-09-01",
"lastSeen": "2026-10-13",
"currentPrice": 34.99,
"referencePrice": 49.99,
"claimedDiscountPct": 30,
"computedClaimPct": 30,
"priceSince": "2026-10-13",
"prior30DayLow": 49.99,
"prior30DayLowDate": "2026-09-15",
"priorWindowObservations": 4,
"actualDiscountVs30DayLowPct": 30,
"assessment": "no conflict found in observed history",
"signals": [],
"windowDays": 30,
"checkedAt": "2026-10-30T18:52:08+00:00",
"disclaimer": "Automated comparison of the shown reference ('was') price with the prices observed in the..."
}
]

How much does it cost to check discounts?

This Actor uses pay-per-event pricing: $0.003 per product saved (one row per product, however many price observations it has) plus a $0.00005 start fee per run, plus small platform usage paid by you (a few hundredths of a cent for small runs). That's about $0.30 for 100 products and $3 for 1,000 products plus usage. With Only save rows with findings on, products without signals aren't saved or charged. You can set a maximum cost per run in the run options.

Use it through the API, integrations or AI agents

  • Run it and get results in one call: https://api.apify.com/v2/acts/ultimatemc~discount-claim-checker/run-sync-get-dataset-items
  • Use it from AI agents through the Apify MCP server: https://mcp.apify.com?tools=ultimatemc/discount-claim-checker
  • Schedule it after a daily scraper run, send flagged rows to Slack or email with webhooks, or connect it to Make, Zapier, n8n or Google Sheets.
  • Pass the dataset IDs of your scheduled price scraper runs; the run reads them with read-only access.

How it works

For each product the latest observation is the claim checked. The Actor finds when the current price started, takes the window of days before that (30 by default) and compares the reference price with the lowest price in that window, following Article 6a of Directive 98/6/EC and the European Commission's 2021 guidance on it, checked on 2026-10-30. Price parsing handles US and EU formats (1,299.00 and 1.299,00). Everything is deterministic with no AI and no outside calls.

Sources:

FAQ

Does a high signal mean the discount is illegal?

No. It means the observed prices conflict with the claim. Your history may have gaps, and the rule has exceptions. Treat it as a lead to check.

How much history do I need?

At least the window (30 days by default) before the price drop. With less, you get insufficient_history or partial_history instead of a verdict.

Can I use daily scraper runs?

Yes. Schedule your price scraper daily and select its datasets. Each row's date comes from a date field or the dataset's creation date.

Does it work for US prices?

Yes. US law doesn't have a fixed 30-day rule, but FTC 16 CFR 233.1 says a former price should be one actually offered for a reasonably substantial period. Change Window (days) if you use another period.

Is it AI?

No. It's deterministic arithmetic on your data.

Limitations

  • Results are only as complete as the price history you supply.
  • It doesn't know about exceptions like new products, perishables or loyalty prices.
  • One currency per product is assumed.
  • Rules and guidance as of 2026-10-30.

Other tools by Ultimate Foresight

Found a wrong result? Open an issue on the Issues tab with the product's price history, and we'll review the logic.