Skip to content

Price history

Where a price reduction is announced, the prior price shown alongside it is generally expected to be the lowest price the item was sold at over a preceding reference period, rather than an inflated reference price. The EU Omnibus Directive sets this out explicitly; confirm what applies in the markets you sell into. priceHistory exposes the pricing data needed to build that display: the lowest selling price a variant has held over a reference period, and how far today’s price sits above it.

Availability is gated by the HISTORICAL_LOWEST_PRICE site feature. On sites without it, the field is not present in the schema.

Querying price history

priceHistory sits on ProductVariant alongside price and takes the same currency and shipping destination. The pair matters: the history is resolved per destination, so a variant can have a lowest price in one country and none in another.

query ProductVariantPriceHistory {
product(sku: 12515764, strict: false) {
sku
title
variants {
sku
title
price(currency: GBP, shippingDestination: GB) {
price {
amount
currency
displayValue
}
rrp {
amount
currency
displayValue
}
}
priceHistory(currency: GBP, shippingDestination: GB) {
lowestPrice {
amount
currency
displayValue
}
difference {
amount
currency
displayValue
}
periodDays
wasPrice {
amount
currency
displayValue
}
}
}
}
}

Fields

  • lowestPrice — the lowest selling price the variant held during the reference period, for the requested currency and destination.
  • difference — the current price minus lowestPrice, floored at zero. It measures how far today’s price sits above the 30-day low, so it is not a saving and must not be presented as one. It is zero whenever the current price is at or below the variant’s own lowest price.
  • periodDays — the length of the reference period the figures were calculated over, currently 30 days.
  • wasPrice — the next lowest distinct price in the period. Nullable. See Was price below.

When price history is null

priceHistory returns null whenever neither the requested destination nor the base-country fallback has a genuine historical lowest price for the requested currency. This can happen for a newly listed product for which the pricing stack holds no history, and for a variant whose only available figure is today’s price, which is suppressed rather than passed off as a historical low.

In that case the field is null rather than echoing today’s price back as the 30-day low, so a null result should be treated as “no prior price to advertise against” and the price displayed on its own.

difference and periodDays are non-null within a PriceHistory, so once the object is present you can rely on all three of the original fields being populated.

Was price

A variant already sitting at its 30-day low has a difference of zero: there is nothing to show a saving against, because today’s price is the lowest price. wasPrice covers that case by exposing the next lowest distinct price in the period. It is selected by price rather than by date, so it is the second lowest price the variant held, which is not necessarily the price it most recently dropped from: for a history of £10, £8, £12 then £7, the was price is £8.

wasPrice is returned only when all of the following hold:

  • the reference period holds two or more distinct prices for that destination;
  • the variant’s current price is at or below its own lowest price for that destination;
  • the was price is strictly above the current price.

Otherwise it is null. A variant that has held a single price throughout the period returns a lowestPrice equal to its current price and a null wasPrice.

The was price is not inherited between shipping destinations. Every other figure on PriceHistory falls back to the base country’s pricing where a destination has no pricing of its own, but a was price is published per destination, and an absent destination cannot be distinguished from one whose prior price simply matched the base country’s. Inheriting would attribute a promotion to a destination that never ran it, so a destination without its own was price returns null. The practical effect is that wasPrice under-reports rather than over-reports: some eligible destinations return null.

wasPrice is nullable and is never returned on its own — priceHistory is null without a lowestPrice, so a was price always arrives alongside one.

Displaying the two together

The two fields answer different questions, and a display typically picks one:

  • difference greater than zero — the variant is above its 30-day low. Show lowestPrice as the prior reference price the current price is measured against. difference is how far above that low today’s price sits, not a saving.
  • difference of zero with a wasPrice — the variant is at or below its 30-day low. wasPrice is the prior higher price to display it against.
  • difference of zero with no wasPrice — there is no usable prior higher price for this destination. Show the price on its own. This does not mean the variant held a single price throughout the period: a was price is also absent where the destination has none of its own, or where the value is not strictly above the current price.