---
title: "Search or list products (EAN-grouped, lowest price first)"
method: GET
path: "/api/products"
---

# Search or list products (EAN-grouped, lowest price first)

`GET /api/products`

## Request

- Base URL: `https://api.glowjakt.se`
- URL: `https://api.glowjakt.se/api/products`
- Auth: none required

Each product appears once, at the lowest price among stores that currently have it in stock (or the lowest listed price if it is sold out everywhere). listing_count is the number of stores carrying the product (including sold out); offer_count is the number with it in stock right now. For a barcode query (see q), offer_count counts the store listings with that barcode, including sold-out ones, and listing_count is not set.

## Query parameters

- `q` string
- `category` 'skincare' | 'makeup' | 'haircare' | 'fragrance' | 'nails' | 'body' | 'accessories'
- `max_price` number
- `key_ingredient` string
- `exclude_ingredient` string
- `exclude_controversial` boolean
- `size` integer
- `page` integer
- `attribute` string

## Response `200`

Paged product list

- ProductPage
  - `total` integer
  - `page` integer
  - `size` integer
  - `products` ProductSummary[]
    - `id` integer
    - `name` string
    - `brand` string
    - `brand_slug` string
    - `slug` string: Use with /api/products/{slug}/offers. Product page: https://<site>/<country>/product/<slug>/
    - `price` number: Lowest price among stores that currently have the product in stock (or the lowest listed price if it is sold out everywhere), in local currency (EUR prices have decimals).
    - `currency` string
    - `original_price` number, nullable
    - `image_url` string, nullable
    - `in_stock` boolean
    - `store_name` string: Store offering that price.
    - `affiliate_url` string: Tracked buy link to the store offering that price (https://{market-domain}/go/{id}?t=...). Signed and valid for 48 hours from the response; it redirects (302) to the store. Do not store or replay expired links — fetch fresh ones.
    - `offer_count` integer: Number of stores with this product in stock right now. For a barcode match (see q on /api/products), the number of store listings with that barcode, including sold-out ones.
    - `listing_count` integer: Number of stores carrying this product, including those currently sold out. Equals the number of entries returned by the offers endpoint. Not set for a barcode match (see q on /api/products).
    - `subcategory_path` string, nullable: Product type as category/subcategory path, e.g. "makeup/lipstick".
    - `content_value` number, nullable: Package quantity in base unit (ml or g), parsed from the product name. Served by the German market (country=de) only; used for the legal unit price (Grundpreis per 1 l / 1 kg, PAngV). Null when the quantity is unknown or the product is sold by piece.
    - `content_unit` string, nullable: Base unit for content_value: "ml" or "g". German market only.

---

[API](https://skmtc.dev/glowjakt/apis/glowjakt-public-api.md) · [All operations](https://skmtc.dev/glowjakt/apis/glowjakt-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/glowjakt/apis/glowjakt-public-api/revisions/6f4e2dee0479?raw)
