Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Ceneo API page →
E-commerce & Marketplaces

Ceneo API & Scraper

The Ceneo API returns Poland's largest price-comparison site as clean JSON, in three actions: search, product/detail and product/offers.

3 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.

product/offers is why the engine exists - one call returns every Polish merchant selling one product, each row carrying the shop's name, its Ceneo merchant id, its domain, the price in PLN, the shop's Ceneo star rating and how many ratings it rests on, the delivery line and whether delivery is free. Verification on 2026-09-06 covered 17 products across 10 Ceneo categories and 288 offers: merchant name, merchant id, price and click-through URL were present on 288 of 288, and a shop rating on 280 - the 8 without one are shops Ceneo has genuinely not rated, and they return null rather than a flattering 0.0. search returns 30 products per page with the from-price and how many shops carry each, and product/detail returns the price band across all shops, the spec table and the customer rating. Prices are PLN. No Ceneo account and no browser - one ReefAPI key and the standard envelope.

Reference

Ceneo's own aggregate disagrees with Ceneo's own offer list - and you get both

Ceneo publishes a summary band (its lowPrice/highPrice and a shop count) and, separately, the offer rows it actually renders. On 2026-09-06 those two disagreed on 4 of 17 measured products. Reconciling them into one number would be wrong either way, so they are returned as two different things and labelled as such.

What you readWhere it comes fromWhat it means
offers[] and most_expensivethe offer rows Ceneo renderswhat the site actually shows a shopper right now
product.price_maxCeneo's own published highPricewhat the site claims. On product 102507375 the claimed band max was 733.99 PLN while the dearest offer Ceneo rendered was 699.90
product.offer_countCeneo's own published countmatched the rows returned on 16 of 17 products. The gap was 187908611, where Ceneo says 37 and its page renders 36 - a parity run of the parser against the saved HTML lost 0 rows, so the inconsistency is Ceneo's
the cheapest offerthe offer rowsequalled Ceneo's published lowPrice on 17 of 17 products, and 0 of 288 offers fell outside the published band
a search row's maximum pricenot publisheda Ceneo search card prints the "od" (from) price only, so this is null by design; the real band is on the product page

Ceneo also lists offers in two different row shapes. Most are redirect offers that carry the shop's ids in the row itself; the rest are "Kup Teraz" basket offers that sell through Ceneo's own checkout and carry the merchant name only inside the shop logo. 5 of the 22 offers on the reference product were the second kind. Both are parsed, which is why the merchant name is 288/288 rather than 283/288.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/ceneo/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "logitech g733"
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "ceneo",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 1864.2,
    "record_count": 30,
    "bytes": 316035,
    "cache_hit": false,
    "pagination": {
      "page": 1,
      "has_more": true,
      "page_size": 30,
      "total": 37
    }
  },
  "data": {
    "results": [
      {
        "product_id": "96905116",
        "title": "Logitech G733 Lightspeed Czarne ([redacted-phone])",
        "brand": "Logitech",
        "url": "https://www.ceneo.pl/96905116",
        "image": "https://image.ceneostatic.pl/data/products/96905116/f-logitech-g733-lightspeed-czarne-[redacted-phone].jpg",
        "price_min": 339,
        "price_min_display": "339,00 zł",
        "price_max": null,
        "currency": "PLN",
        "offer_count": 30,
        "free_delivery_offer_count": 15,
        "rating": 3.92,
        "review_count": 6,
        "category": "Słuchawki komputerowe",
        "category_id": "90",
        "category_url": "https://www.ceneo.pl/Sluchawki_komputerowe",
        "key_specs": [
          "Rodzaj: Słuchawki z mikrofonem",
          "Komunikacja: Bezprzewodowa",
          "Złącze: USB, USB-C"
        ],
        "variant_count": 4,
        "promoted": false
      },
      {
        "product_id": "97201246",
        "title": "Logitech G733 Lightspeed Fioletowe ([redacted-phone])",
        "brand": "Logitech",
        "url": "https://www.ceneo.pl/97201246",
        "image": "https://image.ceneostatic.pl/data/products/97201246/f-logitech-g733-lightspeed-fioletowe-[redacted-phone].jpg",
        "price_min": 439.99,
        "price_min_display": "439,99 zł",
        "price_max": null,
        "currency": "PLN",
        "offer_count": 11,
        "free_delivery_offer_count": 7,
        "rating": 5,
        "review_count": 5,
        "category": "Słuchawki komputerowe",
        "category_id": "90",
        "category_url": "https://www.ceneo.pl/Sluchawki_komputerowe",
        "key_specs": [
          "Rodzaj: Słuchawki z mikrofonem",
          "Komunikacja: Bezprzewodowa",
          "Złącze: USB"
        ],
        "variant_count": 4,
        "promoted": false
      },
      {
        "product_id": "[redacted-phone]",
        "title": "Słuchawki komputerowe Logitech G733 Lightspeed Bia",
        "brand": "Logitech",
        "url": "https://www.ceneo.pl/[redacted-phone]",
        "image": "https://image.ceneostatic.pl/data/products/[redacted-phone]/f-sluchawki-komputerowe-logitech-g733-lightspeed-bialy-[redacted-phone].jpg",
        "price_min": 415.92,
        "price_min_display": "415,92 zł",
        "price_max": null,
        "currency": "PLN",
        "offer_count": 4,
        "free_delivery_offer_count": 1,
        "rating": null,
        "review_count": null,
        "category": "Słuchawki komputerowe",
        "category_id": "90",
        "category_url": "https://www.ceneo.pl/Sluchawki_komputerowe",
        "key_specs": [
          "Rodzaj: Słuchawki z mikrofonem",
          "Komunikacja: Bezprzewodowa",
          "Złącze: USB, USB-C"
        ],
        "variant_count": null,
        "promoted": false
      }
    ],
    "count": 30,
    "total_results": 37,
    "excluded_shop_offers": 0,
    "search_mode": "keyword",
    "resolved_category": null,
    "resolved_url": "https://www.ceneo.pl/;szukaj-logitech+g733",
    "page": 1,
    "sort": "relevance"
  }
}
Actions

What the Ceneo API does

ActionDescriptionConcrete use caseKey params
searchSearch ceneo.pl by keyword and get the matching products: Ceneo product id, title, brand, image, the FROM price (the cheapest offer Ceneo knows for that product), how many shops sell it, the customer rating and review count, the category, and Ceneo's own key-parameter preview. Use the returned `product_id` with `product/offers` to get every shop's price for that product.Pricing teams call search to search ceneo.pl by keyword and get the matching products.query, page, sort, max_rotations
product/detailThe full Ceneo product record by `product_id` (or product URL): title, brand, description, image gallery, the price BAND across all shops (price_min/price_max) with Ceneo's own offer count, the customer rating, the category breadcrumb and the complete technical specification, grouped exactly as Ceneo groups it.Marketplace operators call product/detail to get the full Ceneo product record by `product_id` (or product URL).product_id, max_rotations
product/offersEvery shop offer for one product — the price comparison itself. For the given `product_id` you get one row per merchant: merchant name, Ceneo merchant id, merchant domain, price (numeric and formatted), the Ceneo shop rating and how many reviews it rests on, the delivery cost line, whether delivery is free, the declared dispatch time and a working offer link. Rows are ordered cheapest first. Ceneo shows only part of the list on the product page; by default this action returns the complete one.Catalog enrichment teams call product/offers to get every shop offer for one product.product_id, all_offers, max_rotations
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/ceneo/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"logitech g733"}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.ceneo.search with {"query":"logitech g733"}.
Use cases

Who uses this API and why

  • Polish price-intelligence teams call product/offers to see every shop's price for one product with the shop's Ceneo rating attached.
  • Repricing tools compare the cheapest rendered offer against Ceneo's published lowPrice, which matched on 17 of 17 measured products.
  • Marketplace analysts use search with price_asc across a category to find where a product's from-price sits among 30 competitors per page.
  • Catalog teams call product/detail for the Polish spec table, the price band across all shops and the customer rating.
FAQ

Questions developers ask before integrating

How many offers does product/offers return for one product?

Whatever Ceneo lists, which the 17-product verification put between 3 and 37. The product page itself renders only about 15 rows and defers the rest to its own offers view, so a call fetches that too: on the reference product 108733030 (Logitech G733 K/DA) that took the result from 13 offers to 22, which is exactly Ceneo's own published count, spanning 339.00 to 599.90 PLN. Set all_offers to false if you only want the page's first rows for one cheaper request.

Do I get a link into the shop's own product page?

No - Ceneo does not publish one, so it is not invented. What you get is the shop's domain (amazon.pl, morele.net) and Ceneo's own click-through URL, which is a signed redirect. That is everything Ceneo puts on the page. For the "Kup Teraz" basket merchants the domain is null too, because those sellers trade through Ceneo's own checkout and the site shows a display name only - measured on 3 of the 22 offers on the reference product. The merchant name is still filled.

Why is total_results sometimes null on a search?

Because Ceneo answered your keyword with a category page instead of a result list, and a category page prints no result counter. Rather than guessing a number, the response tells you what happened: the search mode comes back as "category" along with the category Ceneo resolved and its URL. Searching "pralka" is the measured example - Ceneo redirects it to its Pralki category. The rows are still parsed normally, 30 per page.

What happens with a retired or malformed product id?

Both become NOT_FOUND, and this needed real work because Ceneo does not 404. A retired id answers HTTP 200 and redirects to a category listing full of other people's products - without a guard the call would have returned ok:true with a category heading as the product title. The engine checks that the id you asked for is still in the final URL and still on the page's own product node. A malformed id gets HTTP 500 with a 3 KB error page, which is classified as NOT_FOUND once two independent exits agree, not as a block you should retry forever.

Which sort values actually change the order?

Four: price_asc, price_desc, rating_desc and popularity. Each was verified live to change the ordering. Anything else is rejected with an error rather than accepted and silently ignored, because a filter that is accepted and ignored is worse than no filter at all. Note that price_asc sorts products by their CHEAPEST offer, since that is the number a Ceneo search card shows.

Is the shop rating ever zero?

It is null, never zero. Ceneo prints 0/0 for a shop it has not rated, and returning that as 0.0 would make a brand-new shop look terrible instead of unrated. Of 288 measured offers, 280 carried a rating and the 8 that did not all had a rating count of 0 - plus.pl, t-mobile.pl, orange.pl and similar. The invariant was checked directly: there were 0 rows where the rating was null but the rating count was above zero.

Can I get price history or per-shop stock?

No. Ceneo's price chart sits behind a login and this engine holds no account, so there is no history in the response. Per-offer stock counts, EAN/GTIN and merchant review text are not on the page either, and all come back null rather than filled in. What the page does publish - and what you get - is price, delivery text, whether delivery is free, the dispatch line and whether the row is a paid placement.

What is the Ceneo API?

Ceneo API is a ReefAPI endpoint group for polish price comparison: every shop's price for one product. It returns live JSON through POST requests under /ceneo/v1.

Is the Ceneo API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Ceneo calls use the same shared credit balance as every other ReefAPI engine.

Do I need a Ceneo login or account?

No login to Ceneo is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.

How fresh is the Ceneo data?

The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the Ceneo API use?

Ceneo actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.

Can I call Ceneo from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call ceneo actions with the same key, credit pool and JSON envelope used by normal REST requests.

Is the Ceneo API a Ceneo scraper?

It is the managed alternative to a DIY Ceneo scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same polish price comparison: every shop's price for one product back as clean JSON.

docs / ceneo

Ceneo

Polish price comparison: every shop's price for one product.

base /ceneo/v13 endpoints
post/ceneo/v1/product/detail1 credit

The full Ceneo product record by `product_id` (or product URL): title, brand, description, image gallery, the price BAND across all shops (price_min/price_max) with Ceneo's own offer count, the customer rating, the category breadcrumb and the complete technical specification, grouped exactly as Ceneo groups it.

ParameterAllowed / rangeDescription
product_idrequiredCeneo product id — the number in the product URL (https://www.ceneo.pl/108733030). A full product URL is also accepted. Every `search` row returns this as `product_id`.
max_rotations = 4optional1–8Advanced: how many times to retry a difficult request (1–8, default 4 — leave unchanged for typical use).
Try in playground →
post/ceneo/v1/product/offers2 credits

Every shop offer for one product — the price comparison itself. For the given `product_id` you get one row per merchant: merchant name, Ceneo merchant id, merchant domain, price (numeric and formatted), the Ceneo shop rating and how many reviews it rests on, the delivery cost line, whether delivery is free, the declared dispatch time and a working offer link. Rows are ordered cheapest first. Ceneo shows only part of the list on the product page; by default this action returns the complete one.

ParameterAllowed / rangeDescription
product_idrequiredCeneo product id — the number in the product URL (https://www.ceneo.pl/108733030). A full product URL is also accepted. Every `search` row returns this as `product_id`.
all_offers = trueoptionaltrue (default) returns EVERY merchant offer Ceneo lists for the product. false returns only the offers the product page shows without expanding the list (about 15) and costs one request less.
max_rotations = 4optional1–8Advanced: how many times to retry a difficult request (1–8, default 4 — leave unchanged for typical use).
Try in playground →