---
title: "Weekly price history for everything matching a search term"
method: GET
path: "/api/v1/public/catalog/offers/term-history"
tags: ["Offers"]
---

# Weekly price history for everything matching a search term

`GET /api/v1/public/catalog/offers/term-history`

## Request

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

Weekly price history for everything matching a search TERM (the same matcher as GET /offers/search), across ALL chains, INCLUDING expired offers — `catalog_offers` is never purged, so this is the term's whole observed history, not just what's live today. One entry per ISO week (Monday start, Europe/Copenhagen) in the window, oldest first; a week with no matching offer still appears, with nulls/0 rather than being omitted. `summary.typical_price` is the median of the weekly `min_price` over weeks that had an offer; `summary.weeks_on_offer_last_8` counts, of the last 8 weeks, how many had at least one CAMPAIGN offer (a `regular` shelf price does not count as "on offer"). With `chain_slug` the series covers only that chain's own offers (its own typical price, cheapest week and weeks on offer).

## Query parameters

- `q` string, required
- `weeks` integer
- `chain_slug` string

## Response `200`

The term's weekly price history and summary.

- object
  - `ok` true, required
  - `data` object, required
    - `query` string, required
    - `weeks` TermHistoryWeek[], required
      - `week_start` string, date, required: The week's Monday, Europe/Copenhagen calendar.
      - `min_price` number, nullable, required: Lowest shelf price (DKK) across both price_kinds that week — across pack sizes (a 33 cl can and a 1.5 l bottle compete), so not a like-for-like "cheapest"; use cheapest_unit_price for that.
      - `min_unit_price` number, nullable, required: The cheapest offer's unit price (DKK), same row as min_price.
      - `unit_price_unit` 'l' | 'kg' | 'stk' | 'null', nullable, required
      - `offer_count` integer, required: Distinct matching offers that week, both price kinds.
      - `campaign_count` integer, required: Of offer_count, how many were price_kind campaign.
      - `chain_count` integer, required: Distinct chains carrying a matching offer that week.
      - `cheapest_chain_slug` string, nullable, required: The min_price offer's chain.
      - `cheapest_chain_name` string, nullable, required
      - `cheapest_unit_price` number, nullable, required: SA-0230: the week's cheapest unit price (DKK per summary.unit), comparing only offers in that unit (unit prices under 2 DKK per l/kg are treated as parse errors and skipped). Null when no offer that week carried the unit, or summary.unit is null.
      - `cheapest_unit_price_chain_slug` string, nullable, required: The chain of the cheapest_unit_price offer.
      - `cheapest_unit_price_chain_name` string, nullable, required
    - `summary` TermHistorySummary, required
      - `weeks_total` integer, required: Number of weeks in the requested window.
      - `weeks_with_offers` integer, required: Of weeks_total, how many had at least one matching offer.
      - `typical_price` number, nullable, required: Median of the weekly min_price over weeks with offers, 2 decimals. Shelf prices across pack sizes — prefer typical_unit_price for a "typical price" claim.
      - `lowest_price` number, nullable, required: The smallest weekly min_price in the window.
      - `lowest_price_week_start` string, date, nullable, required
      - `lowest_price_chain_name` string, nullable, required
      - `weeks_on_offer_last_8` integer, required: Of the LAST 8 weeks, how many had at least one campaign offer.
      - `unit` 'l' | 'kg' | 'stk' | 'null', nullable, required: SA-0230: the unit the window compares on — the one most offers carry (ties l > kg > stk). Null when no offer has a usable unit price; every *_unit_price field is then null.
      - `weeks_with_unit_price` integer, required: Weeks with a cheapest_unit_price.
      - `typical_unit_price` number, nullable, required: Median of the weekly cheapest_unit_price (DKK per unit), 2 decimals. The like-for-like "typical price".
      - `lowest_unit_price` number, nullable, required: The smallest weekly cheapest_unit_price (DKK per unit).
      - `lowest_unit_price_week_start` string, date, nullable, required
      - `lowest_unit_price_chain_name` string, nullable, required

## 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)
