An Amazon deal is only a deal if its price is lower than what the product recently cost. To check, compare the deal price from /api/amazon-deals with the Buy Box price history from /api/amazon-product-statistics: the lowest price in the 30 and 90 days before the deal started, and the highest. A deal at or above the 30-day low is no reduction, and a 'was' price above the 90-day high was never the Buy Box price in that time.
Key Takeaways
- One deals call returns up to 50 deals with deal price, 'was' price (basisPrice) and start time; one statistics call per deal adds the Buy Box price history.
- Compare with the 30 and 90 days before the deal started, not before today, or the deal's own days count as history.
- A deal price at or above the 30-day low is no reduction: the product sold that cheaply within the last month.
- A basisPrice above the 90-day high was never the Buy Box price in those 90 days; the deals data does not say whether it is a List Price or a Typical Price.
- In the EU, a trader announcing a price reduction must show the lowest price it applied in at least the 30 days before.
How can you tell if an Amazon deal is real?
Compare the deal price with what the product cost before the deal began. The Buy Box price - the featured offer most buyers see - gets an entry whenever a check finds a new value, so its history gives the lowest and highest recorded price of any window. Two numbers decide most deals: the lowest Buy Box price of the 30 days before the deal, and the highest of the 90 days before. Amazon itself marks 30-, 90- and 365-day lows on product pages and shows up to 365 days of price history; the API does the same check for a whole page of deals at once.
| Verdict | When | What it means |
|---|---|---|
| Lowest in 90 days | At or below the 90-day low | A real low - worth a look |
| Below the 30-day low | Under the 30-day low only | A cut; it was cheaper before |
| Not below the 30-day low | It sold this cheaply this month | No reduction - skip it |
| Was-price above the 90-day high | Over 1 % above the 90-day high | Ignore the stated saving |
How do I check Amazon deals against price history in Python?
Fetch today's deals, then one statistics call per deal. prices_between() returns every recorded Buy Box price in effect during a window - the one in effect at its start plus every later change. The price history has no entry while nobody held the Buy Box, so the function also reads the holder history, where "-1" marks that time, and does not carry an old price across it. check() builds the 30-, 90- and 365-day windows from the deal's start, applies the verdicts and notes a short history or an unknown start. get_with_retry() comes from retry.py, new_session() and ApiError from sellermagnet.py in the Python quickstart.
deal_check.py - every deal against its 30- and 90-day Buy Box history
"""Deal check: is each deal's price really low against the Buy Box history, and is its 'was' price real?"""
import sys
import threading
from concurrent.futures import ThreadPoolExecutor
from datetime import date, timedelta
import requests
from retry import get_with_retry
from sellermagnet import ApiError, new_session
MARKETPLACE = "ATVPDKIKX0DER" # deals: any marketplace; statistics: 11 of them
MINOR = 100 # history prices are in minor units; 1 on amazon.co.jp
_local = threading.local()
def session():
if not hasattr(_local, "session"):
_local.session = new_session()
return _local.session
def prices_between(history, holders, start: date, end: date) -> list[float]:
"""Recorded Buy Box prices in effect during [start, end): the one in effect at start plus every later one.
The price history has no entry while nobody held the Buy Box; the holder history marks that time with
"-1", so a price from before such a gap is not carried across it."""
points = [(date.fromisoformat(d), p / MINOR) for d, p in history or []]
points += [(date.fromisoformat(t[:10]), None) for t, seller in holders or [] if seller == "-1"]
points.sort(key=lambda x: x[0])
before = [p for d, p in points if d < start]
return [p for p in before[-1:] + [p for d, p in points if start <= d < end] if p is not None]
def check(deal: dict) -> dict:
price, was = (deal.get("dealPrice") or {}).get("priceTotal"), deal.get("basisPrice")
row = {"asin": deal["asin"], "deal": price, "was": was, "low30": None, "low90": None, "high90": None,
"low365": None, "verdict": "", "title": (deal.get("productTitle") or "")[:40]}
if not price:
return {**row, "verdict": "no deal price"} # 0.0: the page price could not be read
started = deal.get("dealStartTime") or "N/A"
start = date.fromisoformat(started[:10]) if started != "N/A" else date.today()
try:
data = get_with_retry(session(), "amazon-product-statistics", asin=deal["asin"], marketplaceId=MARKETPLACE)
except ApiError as err:
return {**row, "verdict": f"error {err.status}"}
except requests.RequestException as err:
return {**row, "verdict": type(err).__name__}
history, holders = data["stats"].get("buyBoxPriceHistory"), data.get("buyBoxSellerIdHistory")
window = {days: prices_between(history, holders, start - timedelta(days=days), start) for days in (30, 90, 365)}
if not window[30] or not window[90]:
return {**row, "verdict": "no Buy Box price before the deal"}
row.update(low30=min(window[30]), low90=min(window[90]), high90=max(window[90]), low365=min(window[365]))
if price >= row["low30"]:
verdict = "not below the 30-day low" # the price was already this low recently
elif price <= row["low90"]:
verdict = "lowest in 90 days"
else:
verdict = "below the 30-day low"
if was and was > row["high90"] * 1.01:
verdict += "; was-price above the 90-day high"
since = data.get("trackingSince")
if since and date.fromisoformat(since[:10]) > start - timedelta(days=90):
verdict += f"; tracked only since {since[:10]}"
if started == "N/A":
verdict += "; start unknown, measured from today"
return {**row, "verdict": verdict}
if __name__ == "__main__":
try:
deals = get_with_retry(new_session(), "amazon-deals", marketplaceId=MARKETPLACE, count=50)["deals"]
except (ApiError, requests.RequestException) as err:
sys.exit(f"no deals: {err}")
unique = list({d["asin"]: d for d in deals if d.get("asin") not in (None, "N/A")}.values())
with ThreadPoolExecutor(max_workers=4) as pool:
rows = list(pool.map(check, unique))
order = {"lowest in 90 days": 0, "below the 30-day low": 1, "not below the 30-day low": 2}
for r in sorted(rows, key=lambda r: order.get(r["verdict"].split(";")[0], 3)): # best deals first
was = f"{r['was']:.2f}" if r["was"] else "-"
span = (f"30d low {r['low30']:.2f} 90d {r['low90']:.2f}-{r['high90']:.2f} 365d low {r['low365']:.2f}"
if r["low90"] else "")
print(" ".join(filter(None, [r["asin"], f"deal {r['deal']:.2f} was {was}", span, r["verdict"]])))
Output, best deals first (illustrative data)
B0EXAMPLE1 deal 24.99 was 34.99 30d low 29.99 90d 29.99-34.99 365d low 17.99 lowest in 90 days
B0EXAMPLE8 deal 44.99 was 54.99 30d low 54.99 90d 44.99-54.99 365d low 44.99 lowest in 90 days
B0EXAMPLE9 deal 21.99 was 25.99 30d low 25.99 90d 25.99-25.99 365d low 25.99 lowest in 90 days; tracked only since 2026-09-23
B0EXAMPLE3 deal 24.99 was 39.99 30d low 29.99 90d 19.99-29.99 365d low 19.99 below the 30-day low; was-price above the 90-day high
B0EXAMPLE2 deal 34.99 was 79.99 30d low 34.99 90d 34.99-39.99 365d low 34.99 not below the 30-day low; was-price above the 90-day high
B0EXAMPLE6 deal 49.99 was 59.99 30d low 49.99 90d 49.99-59.99 365d low 49.99 not below the 30-day low; start unknown, measured from today
B0EXAMPLE4 deal 0.00 was 19.99 no deal price
B0EXAMPLE5 deal 15.00 was - error 404
B0EXAMPLE7 deal 29.99 was 39.99 no Buy Box price before the deal

What do the deals and the history contain?
Deals carry dealPrice.priceTotal (0.0 when the page price could not be read), basisPrice (null when no reference price is shown) and dealStartTime (ISO 8601 UTC, or "N/A" - then the script measures from today and says so). The Buy Box history is in minor units - 3499 is 34.99; trackingSince says how far back it goes. The deal price is the item price; the Buy Box history includes shipping, so on offers that charge shipping the deal can look cheaper than it was.
One deal and the history the script reads (trimmed, illustrative values)
{
"deal": {
"asin": "B0EXAMPLE2",
"dealPrice": {"priceTotal": 34.99, "priceCurrency": "USD"},
"basisPrice": 79.99,
"savings_percentage": 56,
"dealStartTime": "2026-10-11T08:00:00.000Z"
},
"statistics": {
"trackingSince": "2024-01-10",
"buyBoxSellerIdHistory": [["2026-06-15 09:12:00", "A1EXAMPLESELLER"]],
"stats": {
"buyBoxPriceHistory": [["2026-06-15", 3999], ["2026-08-14", 3699], ["2026-09-18", 3499]]
}
}
}
The EU 30-day rule
Article 6a of Directive 98/6/EC, added by the Omnibus Directive, requires a trader announcing a price reduction to show the lowest price it applied during at least the 30 days before. The script compares against the Buy Box price across all sellers, not one trader's own prices - it is a buyer's check, not a compliance check.

Which deals are worth checking first?
The ones with the biggest stated saving: an inflated 'was' price shows up there first. One deals call and jq list every deal whose 'was' price is at least 1.5 times the deal price - one credit, then check only those against the history. The deals API guide covers department filters and lightning deals, the price history guide the other price series. The 365-day low puts a Black Friday deal next to the summer sales outside the 90-day window; for a message when a watched product drops, see the Telegram price tracker.
Deals whose 'was' price is 1.5x the deal price or more
curl -sG "https://sellermagnet-api.com/api/amazon-deals" \
-H "X-Api-Key: $SELLERMAGNET_API_KEY" --max-time 120 \
--data-urlencode "marketplaceId=ATVPDKIKX0DER" \
--data-urlencode "count=50" \
| jq -r 'if .success then .data.deals[]
| select(.basisPrice != null and .dealPrice.priceTotal > 0 and .basisPrice >= 1.5 * .dealPrice.priceTotal)
| "\(.asin) \(.dealPrice.priceTotal) was \(.basisPrice) \(.productTitle[:50])"
else error(.message) end'
Frequently Asked Questions
How do I know if an Amazon deal is a real discount?
Compare the deal price with the lowest Buy Box price of the 30 days before the deal started. If the product already sold at that price or lower, the deal is no reduction.
What does a 'was' price above the 90-day high mean?
The stated reference price was never the Buy Box price in the 90 days before the deal. Amazon says a List Price reflects the suggested retail price and a Typical Price what customers recently paid on Amazon; the deals data does not say which one basisPrice is.
How many credits does a deal check cost?
One for up to 50 deals and one statistics call per deal checked - about 51 credits for a full page, plus one for each 502 or 503 that get_with_retry() retries.
Which marketplaces are covered?
Deals work on every marketplace the API supports; the price history covers US, UK, DE, FR, IT, ES, JP, CA, IN, MX and BR. Set MINOR to 1 on amazon.co.jp.
Why measure from the deal's start, not from today?
A deal that started three days ago has three days of deal prices in the recent history. Measuring from the start keeps them out of the comparison.
Bottom line: one deals call and one history call per deal show which deals are real lows, which are last month's price with a new badge, and which 'was' prices never happened. A free account includes 150 credits - enough to check two full deal pages before Black Friday.