---
title: "This week's biggest price drops"
method: GET
path: "/api/v1/public/catalog/offers/price-drops"
tags: ["Offers"]
---

# This week's biggest price drops

`GET /api/v1/public/catalog/offers/price-drops`

## Request

- Base URL: `https://api.shelfatlas.com`
- URL: `https://api.shelfatlas.com/api/v1/public/catalog/offers/price-drops`
- Auth: HTTP bearer

Active campaign offers whose price fell against the same item (its persisted item key, which must include a pack size) in the same chain's previous catalogue — the newest campaign offer whose validity ended within the 21 days before this offer's validFrom. Only offers that started within the last 7 days count, one row per item and chain, largest absolute drop first. Campaign offers are chain-level, so lat+lng narrows to chains with an active store within radius_km. Facts only: format your own copy from previousPrice, price, dropAmount and dropPercent.

## Query parameters

- `limit` integer
- `chain_slug` string
- `lat` number
- `lng` number
- `radius_km` number

## Response `200`

This week's biggest drops, largest first. An empty list is not an error.

- object
  - `ok` true, required
  - `data` PriceDrop[], required
    - `id` string, uuid, required
    - `chainId` string, uuid, nullable, required
    - `storeId` string, uuid, nullable
    - `productId` string, uuid, nullable: The offer's best link to a curated product (highest-confidence match), or null when the offer is not linked yet. The per-chain linking rate is published on /docs/app-developers; a linked product carries ean, brand and package size via GET /products/{id}.
    - `rawName` string
    - `itemKey` string, nullable: The offer's stable item identity: a deterministic normalised name+size key, the same across weeks and chains for the same item. It is what /offers/search groups by (k:<item_key>) and what /offers/history?item_key= takes. Opaque — compare, never parse.
    - `price` string, required: Decimal string (Postgres numeric).
    - `originalPrice` string, nullable
    - `unitPrice` string, nullable
    - `unitPriceUnit` 'l' | 'kg' | 'stk' | 'null', nullable: Unit of `unitPrice`: per litre, per kilo or per piece. Null when unknown.
    - `currency` string
    - `validFrom` string, date-time, required
    - `validTo` string, date-time, required
    - `ingestedAt` string, date-time: When this offer was last actually observed by ingest — the freshness signal for "how current is this price".
    - `imageUrl` string, nullable
    - `volumeMl` integer, nullable
    - `unitCount` integer
    - `priceKind` 'campaign' | 'regular': What kind of price this is: 'campaign' — a published offer (leaflet or a chain month-campaign); 'regular' — the everyday shelf price observed in-store. Public API responses today only ever contain 'campaign' rows — everyday shelf prices are not part of the public catalog API. (Both kinds are real, currently-valid prices where they do appear; this field labels them, it doesn't filter within a response.)
    - `cropUrl` string, nullable: Our own verified crop of this offer's leaflet tile — an image of exactly this offer. Present only on chain-scoped lists (chain_slug), null where the chain's crops are not published.
    - `matchedProductIds` string[]: Which of the query's products this offer matched. Present only on product-scoped offer queries (product_id / product_ids / /products/:id/offers). Use this to attribute offers to the products you asked for; productId is the offer's single best link and may name a product outside the query.
    - `previousPrice` string, nullable, required: SA-0186: what the same item cost in the same chain in its previous catalogue (the newest campaign offer with the same item key whose validity ended within the 21 days before this offer's validFrom). Decimal string like `price`; null when unknown — no item key, a key without a pack size, a regular shelf price, or no such offer. Present on GET /offers and /offers/price-drops.
    - `isNewThisWeek` boolean, required: SA-0186: true when this campaign offer started within the last 7 days and the chain had no offer for the same item (any price kind) in the 21 days before it. False when unknown. Present on GET /offers and /offers/price-drops.
    - `dropAmount` string, required: previousPrice − price, decimal string (DKK), always > 0.
    - `dropPercent` number, required: dropAmount as a percent of previousPrice, one decimal.

## Other responses

- `400`: Invalid parameters (`invalid_params`, `incompatible_params`).
- `401`: Missing, invalid, or revoked API key (`missing_api_key` / `invalid_api_key` / `revoked_api_key`).
- `404`: The requested chain_slug does not exist (`chain_not_found`).
- `429`: Rate limit or monthly limit reached (`rate_limited` / `monthly_limit_reached`).
- `503`: Temporary backend failure (`service_unavailable`).

---

[API](https://skmtc.dev/shelfatlas/apis/shelfatlas-catalog-api.md) · [All operations](https://skmtc.dev/shelfatlas/apis/shelfatlas-catalog-api/llms.txt) · [OpenAPI document](https://skmtc.dev/shelfatlas/apis/shelfatlas-catalog-api/revisions/943a8773856b?raw)
