# Empik API scraper — Poland's largest books and media retailer plus its marketplace: search products, read the full product record (author, publisher, ISBN for books) and get EVERY merchant's offer for one product — price, condition, seller rating. Prices in PLN. No account, no browser.

> Search empik.com by keyword and get the matching products: Empik product id, title, brand, image, the price actually charged, the list price and discount, the marketplace seller holding the buybox, category path, rating and delivery line. Filter by brand, seller, price band, condition, free delivery or (for books) author. Use the returned `product_id` with `product/offers` to get every seller's price for that product.
> ReefAPI engine `empik` · 6 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/empik/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, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /empik/v1/search — 3 credits
Search empik.com by keyword and get the matching products: Empik product id, title, brand, image, the price actually charged, the list price and discount, the marketplace seller holding the buybox, category path, rating and delivery line. Filter by brand, seller, price band, condition, free delivery or (for books) author. Use the returned `product_id` with `product/offers` to get every seller's price for that product.

**Parameters:**
- `query` (string, required) — What to look for on empik.com. Polish keywords match best; brand and model names ('iphone 16', 'lego speed champions') work directly. Empik matches LOOSELY — a search for 'iphone' returns 212 021 products because phone cases match too. Use `price_min` or `brand` to cut accessories out.
- `page` (integer, optional, default 1) — Result page, 1-BASED. 60 products per page. Empik stops at page 80 (4 800 products) however large `total_results` is, and past that it silently re-serves page 1 — this endpoint refuses instead of handing you duplicates. `meta.pagination.last_page` is the real last page for your query.
- `sort` (enum, optional, default "relevance") — Result ordering. Only orderings empik.com actually honours are accepted — an unknown value is rejected here rather than passed on, because the site silently ignores one it does not know. [one of: relevance, popularity, price_asc, price_desc, discount_pct, discount_amount, newest]
- `brand` (string, optional) — Restrict to one brand, using Empik's own lower-case brand slug as it appears in its filters ('apple', 'spigen', 'lego'). Measured: 'iphone' 212 021 → 'iphone'+apple 12 267.
- `seller_id` (string, optional) — Restrict to ONE marketplace seller, by the numeric Empik shop id that `product/offers` and `search` return as `seller.id` (0 = Empik itself). Measured: 'iphone' 212 021 → seller 3531 returns 40 products, all from that seller.
- `price_min` (number, optional) — Lowest price in PLN, inclusive.
- `price_max` (number, optional) — Highest price in PLN, inclusive. Measured: 'iphone' 212 021 → price 2000-5000 leaves 293.
- `condition` (enum, optional) — Restrict by item condition. Empik's marketplace carries a real second-hand tier: 'iphone' 212 021 → used_good leaves 265. [one of: new, used_as_new, used_good, used_acceptable, damaged_packaging]
- `free_delivery` (boolean, optional) — true keeps only offers Empik marks as free marketplace delivery. Measured: 'iphone' 212 021 → 31 008.
- `author` (string, optional) — Books only: restrict to one author, using Empik's own 'Surname Firstname' spelling. Measured: 'wiedzmin' 1 803 → author='sapkowski andrzej' 524.
- `max_rotations` (integer, optional, default 4) — Advanced: how many times to retry a difficult request (1-8, default 4 — leave unchanged for typical use).

**Returns:** results[]{product_id, title, url, image, brand (null in categories where Empik files the creator instead — 1/71 on vinyl, 17/60 on books), price_pln (what you pay), list_price_pln (ALWAYS null on a search row — the grid publishes no list price and the tile's rounded percentage cannot rebuild one accurately; call product/detail for it), discount_pct (Empik's own tile figure, integer-rounded, and it under-reports — absent on 8 of 18 products product/detail shows as discounted), currency=PLN, seller{id, name, is_empik}, category, category_path[], delivery, rating, promoted}, count, promoted_count (sponsored tiles inside the grid — returned, flagged, and repeated on every page by the source), total_results (Empik's own printed match count), page, sort (meta.pagination carries last_page)

**Example request body:**
```json
{
  "query": "wiedźmin"
}
```

### POST /empik/v1/product/detail — 1 credit
The full Empik product record by `product_id` (or product URL): title, category breadcrumb, description, image gallery, rating, format/variant, the complete attribute table exactly as Empik groups it, and the creator block — author and publisher for books, performer and label for music, brand and producer for goods. For books it also returns ISBN-13 and EAN.

**Parameters:**
- `product_id` (string, required) — Empik product id — the code in the product URL (…/ostatnie-zyczenie…,p1102239921,ksiazka-p → p1102239921). A full product URL is also accepted. Empik uses three id shapes and all work: 'p1102239921', 'prod58904739' and a bare legacy number like '7291'. Every `search` row returns `product_id`.
- `max_rotations` (integer, optional, default 4) — Advanced: how many times to retry a difficult request (1-8, default 4 — leave unchanged for typical use).

**Returns:** product{product_id, title, url, category, breadcrumb[], category_id, product_type, format, variant_name, release_date, rating, rating_count, image, images[], description, tags[], available_in_store, creators{brand, series, license, line, author[], publisher[], producer[], performer[], director[]}, isbn (books only), ean (books only), empik_index, pages, cover_type, language, original_language, edition_year, publication_date, specs[]{label, values[]}, price_pln, list_price_pln, currency=PLN, seller{…}, best_offer{…}}

**Example request body:**
```json
{
  "product_id": "p1102239921"
}
```

### POST /empik/v1/product/offers — 1 credit
Every seller offer for one product — the price comparison itself. One row per merchant: seller name, Empik shop id, shop page, super-seller flag, seller rating and how many ratings it rests on, the price actually charged and the list price, whether the discount needs an Empik membership, the item condition (new, used as-new/good/acceptable, damaged packaging), declared dispatch window and the delivery line. Rows keep Empik's own ordering; `cheapest` is computed separately because that ordering is NOT purely by price.

**Parameters:**
- `product_id` (string, required) — Empik product id — the code in the product URL (…/ostatnie-zyczenie…,p1102239921,ksiazka-p → p1102239921). A full product URL is also accepted. Empik uses three id shapes and all work: 'p1102239921', 'prod58904739' and a bare legacy number like '7291'. Every `search` row returns `product_id`.
- `max_rotations` (integer, optional, default 4) — Advanced: how many times to retry a difficult request (1-8, default 4 — leave unchanged for typical use).

**Returns:** product{product_id} + offers[]{position, offer_id, seller{id, name, url, logo_url, super_seller, is_foreign, rating, rating_count, is_empik}, price_pln, list_price_pln, discount_pct (computed), discount_pct_source, discount_amount_pln, discount_type, membership_price, currency=PLN, unit_price_pln, min_price_pln, price_type, condition, condition_note, availability, availability_label, stock_level (null — Empik does not publish it logged-out), delivery, delivery_options[]} + count, seller_count, cheapest, most_expensive, cheapest_new, has_used, sort_info (Empik's own printed explanation of the ordering)

**Example request body:**
```json
{
  "product_id": "p1102239921"
}
```

### POST /empik/v1/products/batch — 2 credits
Up to 30 products in ONE request — id, title, url, category, rating, cover, creators and the current buybox offer (price, list price, seller) for each. This is the cheap way to refresh a watchlist: 30 products for the price of one call instead of 30 separate `product/detail` calls.

**Parameters:**
- `product_ids` (array, required) — Up to 30 Empik product ids in one call. Above 30 the source returns only the first 30, so this endpoint rejects a longer list instead of silently dropping the rest.
- `max_rotations` (integer, optional, default 4) — Advanced: how many times to retry a difficult request (1-8, default 4 — leave unchanged for typical use).

**Returns:** results[]{product_id, title, url, category, rating, rating_count, image, creators{brand, author[], publisher[], performer[]}, price_pln, list_price_pln, currency=PLN, seller{…}, best_offer{…}}, count, requested, missing[] (ids Empik returned nothing for)

**Example request body:**
```json
{
  "product_ids": [
    "p1102239921",
    "p1538551909"
  ]
}
```

### POST /empik/v1/product/reviews — 1 credit
Customer reviews for one product, 30 per page: author name, date, the 1-5 score, title and body, how many readers found it useful, whether Empik marks the purchase as verified. Also returns the full star histogram (how many votes at each score) and Empik's own AI summary of the reviews with its keyword list.

**Parameters:**
- `product_id` (string, required) — Empik product id — the code in the product URL (…/ostatnie-zyczenie…,p1102239921,ksiazka-p → p1102239921). A full product URL is also accepted. Empik uses three id shapes and all work: 'p1102239921', 'prod58904739' and a bare legacy number like '7291'. Every `search` row returns `product_id`.
- `page` (integer, optional, default 1) — Review page, 1-BASED, 30 reviews per page. `total_reviews` and `pages` tell you how far you can go.
- `sort` (enum, optional, default "default") — Review ordering. These are the six orderings empik.com itself publishes for its review list. [one of: default, popular, highest_rate, lowest_rate, newest, oldest]
- `max_rotations` (integer, optional, default 4) — Advanced: how many times to retry a difficult request (1-8, default 4 — leave unchanged for typical use).

**Returns:** reviews[]{review_id, author, created_at, score, title, content, useful_votes, useless_votes, verified_purchase, commercial, status}, count, total_reviews, pages, page, hidden_count, rating_histogram[]{score, votes}, total_votes, ai_summary{date, content, keywords[]} (null when Empik has not generated one)

**Example request body:**
```json
{
  "product_id": "p1102239921"
}
```

### POST /empik/v1/product/variants — 1 credit
The other editions of the same title — for a book: paperback, hardcover, ebook EPUB/MOBI, audiobook, foreign-language printing; for music: the other formats. Each variant returns its own resolvable Empik product id and URL, so you can feed it straight back into `product/offers`.

**Parameters:**
- `product_id` (string, required) — Empik product id — the code in the product URL (…/ostatnie-zyczenie…,p1102239921,ksiazka-p → p1102239921). A full product URL is also accepted. Empik uses three id shapes and all work: 'p1102239921', 'prod58904739' and a bare legacy number like '7291'. Every `search` row returns `product_id`.
- `max_rotations` (integer, optional, default 4) — Advanced: how many times to retry a difficult request (1-8, default 4 — leave unchanged for typical use).

**Returns:** variants[]{product_id, name, url, price_pln (null — Empik leaves the price out of the variant list; call product/offers for it), release_date, sub_variants[]}, count

**Example request body:**
```json
{
  "product_id": "p1102239921"
}
```

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