Price History API: How to Show Readers a Product’s Lowest Recent Price

Readers want to know if now is a good time to buy. This guide shows how one Price History API request turns into a lowest-price label, with an interactive demo on real prices.

Price History API: How to Show Readers a Product’s Lowest Recent Price

Readers often want to know one thing before they click: is this a good time to buy? A line such as “Lowest price in the last 90 days: $79.99” answers that with a fact from the product’s own history instead of an opinion. The Price History API returns the numbers that line needs in a single request, using the product’s barcode. This guide shows how to build the label, what makes the answer less tidy than it looks, and how to test it on real prices. The demo below uses prices last pulled November 10, 2026.

What a lowest-price label has to say

A good label makes three statements, and each one comes from a different part of the history. The first is the lowest price the product reached. The second is when it reached it, so a reader can tell a low from last week from a low in the summer. The third is whether any store is at that price today, which decides whether the label reads “at its lowest price” or “lowest was $79.99 on Sep 14”.

Two choices change the answer, and a page should make them on purpose. One is the window. A product’s lowest price in the last 90 days is a different fact from its lowest price ever, and the label should say which one it is. The other is stock. A price from a day when nobody had the product in stock was never a price a reader could pay, so a careful label either leaves those days out or says it did not.

The label also has to be fair to the stores. A product sold in many places has many histories, and one store’s sale is not another store’s price. The simplest honest rule is to look across every store that has history for the barcode and report the lowest price any of them reached.

Who uses a lowest-price label

Publishers put it on product cards and gift guides, where a line such as “at its lowest price this season” gives a reader a reason to act now that is not a vague promise. Deal and coupon pages use it to separate a discount that is real from one that only looks large. Our post on telling readers whether a Black Friday deal is real applies the same idea to a claimed discount.

Newsletter teams use the label to write the one-line summary under a product, and they can pull a fresh figure before each send. Shopping assistants use it to answer “is this a good price?” from data, not from memory. The label is small enough to fit in a tool call, so an assistant can check it before it answers.

Try the lowest price

This demo runs on real results from the Price History API for popular gifts. The page holds a rotating set that is rebuilt every night, and it shows two products, a different pair on most visits. Pick a product and compare the Lowest tile with today’s price. The chart plots the lowest in-stock price for each of the last 90 days, and the request below it is the exact call that returns each history.

The target price field is optional. It shows the same history from the other side, as an alert that fires when the price reaches a number a reader chose. For the label, the Lowest tile and the open marker on the chart are the facts to read.

How one request becomes a label

The request is one barcode. The Price History API returns one entry for every store that sells that barcode and has history for it, so a single request is enough to compare stores. Setting include_series to false asks for a summary of each store and leaves out the daily series, which keeps the response small.

POST https://api.affiliate.com/v1/products/price-history

{
  "target_type": "barcode",
  "target_ids": ["810097977204"],
  "currency": "USD",
  "include_series": false,
  "per_page": 25
}

Each entry carries a stats block. This is one store’s entry from a real response, trimmed to the fields the label needs.

{
  "stats": {
    "first_date": "2026-09-11",
    "last_date": "2026-11-10",
    "current": { "date": "2026-11-10", "final_price": 47.99, "regular_price": 52.49 },
    "min_final_price": { "date": "2026-09-11", "amount": 39.99 },
    "max_final_price": { "date": "2026-10-27", "amount": 47.99 },
    "out_of_stock_days": 0
  }
}
FieldWhat it gives the label
min_final_priceThe lowest price this store reached in the window, with the date it happened.
currentToday’s price at this store, which tells you whether the store is at its low now.
first_date, last_dateHow long this store’s history is. A store with a short history cannot show a long window.
out_of_stock_daysHow many days the store did not have the product, useful for deciding how much to trust its low.
seriesOne point per observed day, with availability, when you ask for it. The demo asks for it because it draws the chart.

One call covers up to 90 calendar days, and history reaches back 365 days, so an older period can be requested by moving the from and to dates. A day without a point means the price was not observed that day, so a label should skip it instead of treating it as zero.

From the response to the label

The rule is short. Find the lowest price any store reached. If a store is at that price today, say so. If none is, show the lowest price and the date it happened.

// listings: the data array of the response, one entry per store with history
function lowestRecentPrice(listings) {
  let low = null;
  for (const l of listings) {
    const m = l.stats.min_final_price;
    if (!low || m.amount < low.amount) low = { amount: m.amount, date: m.date };
  }
  const atLow = listings.filter(l => l.stats.current.final_price <= low.amount);
  return { amount: low.amount, date: low.date, storesAtLowToday: atLow.length };
}

Run on that real response for a small kitchen appliance, the function returns a low of $33.99 reached on Sep 14, with no store at that price today. The label would read “Lowest price in the last 90 days: $33.99 on Sep 14”, which is accurate and says plainly that the price is higher now. If a store were at the low today, the label could say “at its lowest price” instead.

When the answer is less tidy

Three cases are worth handling before the label goes live. The first is stock. The summary above takes each store’s lowest price whether or not the store had the product that day. A stricter label counts only days with the product in stock, which needs the series. This is the rule the demo uses.

// listings: the response with include_series true
function lowestInStock(listings) {
  let low = null;
  for (const l of listings)
    for (const p of l.series)
      if (p.availability === "InStock" && (!low || p.final_price < low.amount))
        low = { amount: p.final_price, date: p.date };
  return low;
}

The second case is coverage. A barcode can match more listings than have history. In the response above, 14 listings matched the barcode and 8 had history, so a label built from the response compares eight stores, not fourteen. The label should be written for the stores it actually saw. The third case is a short history. A store tracked for three weeks cannot say anything about the last 90 days, so check first_date before you claim a window.

What the November 10, 2026 pull shows

We ran the same request on November 10, 2026 for the six gifts in that day’s set, with the window set to the last 90 days. Two of the six sat at the lowest in-stock price of the window that day, and four sat above it. The largest gap was on the Garmin Forerunner 165 watch, $38.01 above its low of $199.99.

ProductToday90-day lowVs the low
Cuisinart Fast Freeze Max ice cream wand$105.99$105.99At the low
Garmin Venu X1 watch$697.00$599.98$97.02 above
Garmin Forerunner 165 watch$238.00$199.99$38.01 above
Garmin Venu 4 watch$549.99$499.98$50.01 above
Revlon Perfect Heat hair dryer$32.99$32.99At the low
NutriBullet Lite immersion blender$39.99$33.99$6.00 above

This table is fixed to November 10, 2026. The demo above is rebuilt every night with a different set of gifts, so its products and numbers will change. Treat the table as a record of one day and the demo as the live version of the same check.

A handful of products is a small sample and not a market study. Each figure describes one product across the stores that report history for it, in US dollars. It says nothing about products outside the list.

What to check before you publish a label

Name the window. Say “lowest in the last 90 days” rather than “lowest ever”. History beyond the window is not in that response, and a reader should know what the claim covers.

State what was observed. “Lowest in the last 90 days: $33.99 on Sep 14” is a fact from the history. A label that sounds like advice goes further than the data does. Our guide to how price history helps a reader trust a deal shows how to keep a label factual.

Match on the barcode. Two colors or two bundles of the same model are different products with different barcodes, and mixing them makes a low look lower than it was. Barcode search explains why the barcode comes first, and the same product’s histories across stores shows how different they can be.

Confirm stock separately. A label can say a price was low and still link to a store that is out of stock today. Handling out-of-stock and price-changed offers lays out how a page or an agent can check before it sends a reader.

Getting started in three steps

Moving from the demo to a label of your own takes three steps, and the request panel above already contains the second one.

StepWhat to do
1. Get a keyRequest an API key from Affiliate.com. Every request sends it as a Bearer token in the Authorization header, which is why the demo never needs one.
2. Request a historyPOST a barcode to https://api.affiliate.com/v1/products/price-history with currency set to USD. Use the summary for a quick label and the series for a strict one.
3. Print the label with a dateRun the function above, show the low and when it happened, and keep the time you last checked so the page can say how fresh the figure is.

Keeping a lowest-price label current

Prices move daily, so a label that updates weekly will be wrong most of the time. The demo above is rebuilt every night and shows the date it was last pulled, so readers can see how old the figures are. A page of your own can do the same: pull on a schedule, store the result and print the time beside it. How often product pages should be updated discusses how often is often enough.

The label also pairs well with the list price. Comparing regular price with final price shows how to test a discount claim, and a page that shows both the low and the claim lets a reader see the whole picture.

One API call
One request, one honest label
  • ✓A price record for every store that sells a barcode
  • ✓The lowest price and the date it happened, ready to print
  • ✓Up to 90 days per call, and 365 days of history
Get API access →
Request
{
  "target_type": "barcode",
  "target_ids": [
    "810097977204"
  ],
  "currency": "USD",
  "include_series": false,
  "per_page": 25
}