# PriceRunner API — UK, Sweden and Denmark price comparison: search, categories, every shop's price with shipping, product specs, price history and reviews

> Keyword search on PriceRunner (pricerunner.com UK, .se Sweden, .dk Denmark). Rows are catalogue products with lowest price, cheapest offer, number of shops, rating, popularity rank and product group. The site narrows a free-text query to the category it guesses (`site_applied_filter`); `auto_category: false` searches the whole catalogue. Filter by brand, category and price (ids come from `filters` and `categories` of an earlier call).
> ReefAPI engine `pricerunner` · 6 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/pricerunner/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http). Send the key as `Authorization: Bearer <key>`, or put it in the URL (`?key=<key>`) when the client has no header field, as ChatGPT does.

## Endpoints

### POST https://api.reefapi.com/pricerunner/v1/search — 3 credits
Keyword search on PriceRunner (pricerunner.com UK, .se Sweden, .dk Denmark). Rows are catalogue products with lowest price, cheapest offer, number of shops, rating, popularity rank and product group. The site narrows a free-text query to the category it guesses (`site_applied_filter`); `auto_category: false` searches the whole catalogue. Filter by brand, category and price (ids come from `filters` and `categories` of an earlier call).

**Parameters:**
- `query` (string, required) — Search words, e.g. `iphone 15`, `headphones`, `dammsugare`, or a model number.
- `country` (enum, optional, default "uk") — Which PriceRunner: uk = pricerunner.com (GBP), se = pricerunner.se (SEK), dk = pricerunner.dk (DKK). Product ids are shared across the three; prices, shops and offers are per market. [one of: uk, se, dk]
- `page` (integer, optional, default 1) — Result page, 48 rows each. A page past the last returns no rows.
- `brand_id` (string, optional) — Brand id from the BRAND entry of `filters` of an earlier call (uk: 162 = Apple).
- `category_filter` (string, optional) — Category id from `categories[].category_filter` of an earlier search: narrows the search to it.
- `price_min` (number, optional) — Lowest price in the market's currency (the site's own price index, matched against the product's lowest price).
- `price_max` (number, optional) — Highest price in the market's currency.
- `auto_category` (boolean, optional, default true) — Let PriceRunner narrow the query to the category it guesses (its default; `site_applied_filter` says which). false = whole catalogue (headphones: 53 339 instead of 14 781).

**Returns:** results[]{row_type, product_id, title, url, description, category{category_id, name}, brand{brand_id, name}, image, lowest_price, cheapest_offer_price, cheapest_offer_merchant_id, price_mismatch, currency, price_per_unit, shop_count, rating, rating_count, popularity_rank, rank_trend, price_drop, ribbon, out_of_stock, condition, classification, product_group{group_id, name, member_count}, instalment} + count + total + page + page_size + has_more + categories[]{category_filter, name} + filters[]{filter_id, name, unit, type, options[]} + site_applied_filter + spelling_suggestion + query + country + currency

**Example request body:**
```json
{
  "query": "iphone 15",
  "country": "uk"
}
```

### POST https://api.reefapi.com/pricerunner/v1/category — 2 credits
One PriceRunner category listing (e.g. 1 = Mobile Phones): the same rows as `search`, with sort, brand, price and attribute filters and paging, plus the category's own filter lists with counts.

**Parameters:**
- `category_id` (string, required) — Numeric PriceRunner category id: the number in /cl/<id>/…, `category.category_id` of a search row or `category_path` of `product`.
- `country` (enum, optional, default "uk") — Which PriceRunner: uk = pricerunner.com (GBP), se = pricerunner.se (SEK), dk = pricerunner.dk (DKK). Product ids are shared across the three; prices, shops and offers are per market. [one of: uk, se, dk]
- `page` (integer, optional, default 1) — Result page, 48 rows each. A page past the last returns no rows.
- `sort` (enum, optional, default "popularity") — Result order. [one of: popularity, price_asc, price_desc, rating, price_drop, name]
- `brand_id` (string, optional) — Brand id from the BRAND entry of `filters` of an earlier call (uk: 162 = Apple).
- `price_min` (number, optional) — Lowest price in the market's currency (the site's own price index, matched against the product's lowest price).
- `price_max` (number, optional) — Highest price in the market's currency.
- `attribute_filter` (string, optional) — One attribute filter as `<filter_id>:<option_id>` from `filters` of an earlier call (uk category 1: 60501678:510242 = Series Apple iPhone 15).

**Returns:** results[]{same row shape as search} + count + total + page + page_size + has_more + category{category_id, name, path[], leaf, children[]} + filters[] + sort + country + currency

**Example request body:**
```json
{
  "category_id": "1",
  "country": "uk"
}
```

### POST https://api.reefapi.com/pricerunner/v1/product — 3 credits
One PriceRunner product: title, brand, category path, image, description, editorial article and FAQ, rating and count, popularity rank in its category, national lowest / highest price and offer count, international lowest price, lowest in-stock price, PriceRunner's price-level verdict with its change, the full spec sheet and every variant of its product group with its own id and price.

**Parameters:**
- `product_id` (string, required) — PriceRunner product id: `product_id` of a search / category row, or the number after the dash in a product URL (/pl/1-<id>/…).
- `country` (enum, optional, default "uk") — Which PriceRunner: uk = pricerunner.com (GBP), se = pricerunner.se (SEK), dk = pricerunner.dk (DKK). Product ids are shared across the three; prices, shops and offers are per market. [one of: uk, se, dk]

**Returns:** product{product_id, title, url, description, article, faq[], brand, category, category_path[], image, rating, rating_count, popularity_rank{rank, category}, lowest_price_national, highest_price_national, national_offer_count, lowest_price_international, international_offer_count, lowest_price_in_stock, lowest_price_any_offer, currency, price_level{level, change_absolute, change_percent}, classification, specs[]{group, label, value, description}, variants[]{product_id, title, url, lowest_price, attribute_values, image}, variant_count, meta_title} + lowest_prices{national_with_shipping, national_without_shipping, international_with_shipping, international_without_shipping} + country

**Example request body:**
```json
{
  "product_id": "3208336570",
  "country": "uk"
}
```

### POST https://api.reefapi.com/pricerunner/v1/offers — 2 credits
Every shop's offer for one product on PriceRunner: shop (name, id, rating and count, labels, payment methods, return policy), offer title, price, shipping cost, total incl. shipping, campaign price, stock status, delivery days, instalment, attributes, and the click-out link; plus the national / international price summary and the sponsored placements apart. Filter by condition (new, used, refurbished), national or international shops and stock; sort by PriceRunner's recommendation, price, price with shipping or delivery time.

**Parameters:**
- `product_id` (string, required) — PriceRunner product id: `product_id` of a search / category row, or the number after the dash in a product URL (/pl/1-<id>/…).
- `country` (enum, optional, default "uk") — Which PriceRunner: uk = pricerunner.com (GBP), se = pricerunner.se (SEK), dk = pricerunner.dk (DKK). Product ids are shared across the three; prices, shops and offers are per market. [one of: uk, se, dk]
- `sort` (enum, optional, default "recommended") — Offer order. [one of: recommended, price, price_with_shipping, delivery]
- `condition` (enum, optional, default "new") — Which offers by condition (the site's default view is new). [one of: new, used, refurbished, all]
- `origin` (enum, optional, default "national") — Shops in the market's own country, foreign shops selling into it, or both. [one of: national, international, all]
- `stock` (enum, optional, default "available") — Stock filter. [one of: available, in_stock, all]
- `max_offers` (integer, optional, default 100) — Cap on the rows returned (PriceRunner sends the whole list in one response).

**Returns:** offers[]{position, offer_id, title, price, shipping_cost, total_price, total_price_source, currency, campaign_price, price_per_unit, stock_status, availability, delivery_days_min, delivery_days_max, instalment, labels[], attributes[], clickout_url, merchant{merchant_id, name, url, country, international_country, rating, rating_count, labels, payment_methods, return_period_days, return_cost, return_policy}} + count + total_offers + cheapest_price + cheapest_total_price + summary{lowest_national, highest_national, national_count, lowest_international, international_count, lowest_in_stock, lowest_any_offer} + sponsored_offers[] + condition_counts + sort + condition + origin + stock

**Example request body:**
```json
{
  "product_id": "3208336570",
  "country": "uk"
}
```

### POST https://api.reefapi.com/pricerunner/v1/price_history — 2 credits
PriceRunner's own price history for one product: the lowest price on each day with the shop that had it, lowest / highest / median in the range. The source's daily lowest spans every condition and contains single days far below the band (mis-matched shop offers); those are kept as published and flagged `suspect_low`.

**Parameters:**
- `product_id` (string, required) — PriceRunner product id: `product_id` of a search / category row, or the number after the dash in a product URL (/pl/1-<id>/…).
- `country` (enum, optional, default "uk") — Which PriceRunner: uk = pricerunner.com (GBP), se = pricerunner.se (SEK), dk = pricerunner.dk (DKK). Product ids are shared across the three; prices, shops and offers are per market. [one of: uk, se, dk]
- `time_range` (enum, optional, default "3m") — How far back (one point per day). [one of: 1w, 1m, 3m, 1y, 2y, all]
- `merchant_id` (string, optional) — Only this shop's line (`merchant.merchant_id` of an `offers` row).

**Returns:** product_id + time_range + currency + points[]{date, price, merchant_id, merchant_name, offer_id, suspect_low} + count + first_date + last_date + lowest_in_range{date, price, merchant_name} + lowest_in_range_excluding_suspect + highest_in_range + median_in_range + suspect_point_count + source_lowest + source_highest + merchants_in_chart + identity{requested_product_id, response_product_id, matches}

**Example request body:**
```json
{
  "product_id": "3208336570",
  "country": "uk",
  "time_range": "3m"
}
```

### POST https://api.reefapi.com/pricerunner/v1/reviews — 2 credits
Reviews of one product on PriceRunner: user reviews PriceRunner collects from retailers, expert test reviews, or Klarna verified-buyer reviews — score, text, author, source shop or publication, date, language. Paged with `cursor`. `include_summary` adds the overall score, counts and the 1-5 star histogram.

**Parameters:**
- `product_id` (string, required) — PriceRunner product id: `product_id` of a search / category row, or the number after the dash in a product URL (/pl/1-<id>/…).
- `country` (enum, optional, default "uk") — Which PriceRunner: uk = pricerunner.com (GBP), se = pricerunner.se (SEK), dk = pricerunner.dk (DKK). Product ids are shared across the three; prices, shops and offers are per market. [one of: uk, se, dk]
- `review_type` (enum, optional, default "user") — Which reviews. [one of: user, pro, customer]
- `limit` (integer, optional, default 10) — Reviews per call.
- `cursor` (string, optional) — `next_cursor` of the previous call, for the next batch.
- `include_summary` (boolean, optional, default false) — Also return the overall score, counts and star histogram (one more request).

**Returns:** reviews[]{date, type, score, score_max, title, text, author, source, source_domain, language, country, reviewed_product, pros, cons, votes_up, votes_down, link} + count + has_more + next_cursor + review_type + summary{score, score_count, user_review_count, pro_review_count, user_score_distribution, pro_score_distribution} (include_summary)

**Example request body:**
```json
{
  "product_id": "3208336570",
  "country": "uk"
}
```

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

## More
- Try it live, no code: https://reefapi.com/playground?engine=pricerunner
- Human docs page: https://reefapi.com/docs/pricerunner
- Overview page: https://reefapi.com/pricerunner-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
