Every Polish shop's price for one product, in one call
The Ceneo API returns Poland's largest price-comparison site as clean JSON, in three actions: search, product/detail and product/offers.
3 active endpoints, on 1 and 2 credit tiers.
- POST/ceneo/v1/search
- POST/ceneo/v1/product/detail
- POST/ceneo/v1/product/offers
What Ceneo endpoints does ReefAPI ship?
3 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Ceneo API
3 of 3 endpoints, ready to run
One row per Polish merchant selling the product: shop name, Ceneo merchant id, shop domain, price in PLN, the shop's Ceneo star rating and how many ratings it rests on, the delivery line and whether delivery is free.
{ "ok": true, "meta": { "api": "ceneo", "endpoint": "product/offers", "mode": "live", "latency_ms": 1174.2, "record_count": 22, "cache_hit": false }, "data": { "product": { "product_id": "108733030", "title": "Logitech G733 Lightspeed K/DA (981000990)", "brand": "Logitech", "url": "https://www.ceneo.pl/108733030", "price_min": 339, "price_max": 599.9, "currency": "PLN", "offer_count": 22, "rating": 4.45, "review_count": 20 }, "offers": [ { "position": 1, "offer_id": "449496121", "seller": { "id": "42774", "name": "amazon.pl", "domain": "amazon.pl", "rating": 3.1, "rating_count": 76 }, "price": 339, "price_display": "339,00 zł", "currency": "PLN", "offer_url": "https://www.ceneo.pl/Click/Offer/?e=JIqwZjY-P4pzL7LX731tPdpjhUnxnvSr83_dhN0A0vw5uAirmcID-1OOot8E-rmYj09diuUdn79W6f76emypKe9ra8XlsrB6xOZRDAFckGnrzYipK0FlMxOYMS7H3QF5iZFZn2RCRvFU2jHdzjUdSSicKMwLCszw_eVZfKNhFCcgj47C37xzVrZflzZ71TOppVBMwlkFDd2lUEzCWQUN3TeZDdLIsxPPLU9tip2F4tGtzfR_yQw9edGYfnUpga5dpVBMwlkFDd1ScFHeoos6GuvKhpciNhauh0l2IhOuu82nD2iFDxipk8mLv66WqCLf2JddiJZwMvSJHNCvWMeGAb91NTeRLejD99RfDFj4PSh_2OQXG6J8UWr2i2iPuDrtMwUlL3mMqpCFgkCP1s6necaSliqxszjiiRV_yHTJClcAh3YfayPrKv1z2wDZI4d1DhaykBqDhDAAJPyVz5caZz_H4ZjbMHZt&ctx=CgsI4N2BvdyGxj8QBRIkZjcwZjExNTItYTllYy0xMWYxLWEyM2UtYjM4MzY0YTVjMTUyGiRmNzUxMjkyOS1hOWVjLTExZjEtYTk2OS00MGE0YTg4YmViNGU=&a=2", "offer_title": "Logitech G733 LIGHTSPEED Bezprzewodowy zestaw słuchawkowy do gier RGB | Zawieszany pałąk, podświetlenie LIGHTSYNC RGB, technologia mikrofonu Blue VOIC", "delivery": "Darmowa wysyłka", "free_delivery": true, "dispatch": "Wysyłka w 1 dzień", "promoted": false, "product_id": "108733030" }, { "position": 2, "offer_id": "506174310", "seller": { "id": "44201", "name": "rozetka.pl", "domain": "rozetka.pl", "rating": 4.1, "rating_count": 92 }, "price": 379, "price_display": "379,00 zł", "currency": "PLN", "offer_url": "https://www.ceneo.pl/Click/Offer/?e=StoZx0Ge0G3AlHsrAR-GSxugw6K6OpxydPyfob3dq3EDz8Mv4vCGyj_Bz5uvM-shxkA9gHaAX4yn7daM-GQT0SLtaeW5G21eU5ZZuZoqDnSClEugWVKch-DVjqc7bLgADZklry2ylGLdTRuyjanWgBfgGPPtnN2cbYNDE_Oyz3ErRk2yk3SFgJ7ojeBTtpg6a7gXshqecknU4vn6IufAd2TD50otZri9pVBMwlkFDd1b-0ZRBvrIO-JZdTQSosa20emOQ4hferpu7IOLG8RLPKVQTMJZBQ3dpVBMwlkFDd21_KGd2FVnjsGaLAzcCtwhud1dRAmrlDP6Re9Gnlgm46O1OHpDX3iCpVVJ1eWv2NSq-J_WjBjdB17Zv0xaBKXBDr-Gs9z7xX0fCcv8f465rhiSpwuGl7D-j7eykYfoQ7yQzKePTaKGVCqURNTaqcf-55tML6KTH3Yffdxom_hsbPFCsKnECGuJdKUjUfUjGi0=&ctx=CgsI4N2BvdyGxj8QBRIkZjcwZjExNTItYTllYy0xMWYxLWEyM2UtYjM4MzY0YTVjMTUyGiRmNzUxMjkyOS1hOWVjLTExZjEtYTk2OS00MGE0YTg4YmViNGU=&a=2", "offer_title": "Słuchawki bezprzewodowe Logitech Lightspeed RGB Gaming Headset G733 White (981-000883)", "delivery": "Darmowa wysyłka", "free_delivery": true, "dispatch": "Wysyłka w 1 dzień", "promoted": false, "product_id": "108733030" }, { "position": 3, "offer_id": "593263292", "seller": { "id": "4614", "name": "sferis.pl", "domain": "sferis.pl", "rating": 4.8, "rating_count": 7742 }, "price": 389.09, "price_display": "389,09 zł", "currency": "PLN", "offer_url": "https://www.ceneo.pl/Click/Offer/?e=8_sNNHoLKGxzL7LX731tPa1FFuvUnQbCzooiC-InL3l4LVsYTtC29Hu32RXj5KYvvdZM66f2tHaiPKjyHxoZ0w6QvUU31QWkZu2k3WnXNFYl75GWy2wc2rzh348DCefvo1bUOqyCiSqVP4uPmdje5qrjFK7IeAUupVBMwlkFDd2lUEzCWQUN3RLejOwbEI7stfuigIgtNopsQ6tOpD-ok6VQTMJZBQ3dpVBMwlkFDd3XHnXuDTc4W_LqeMuOgzalRF73hdRh8oKVFPMdWMzhUOa5AkYRQVilNmAYMLiHKHsk0jALjXBekKkVcL_4mSm9iOIVB76k39ubUfHYc86PH-sf3ru3BlKa7H4YgeuFgEHkBdf_Li4EuARFugZhfaXIenq-uyUrkIteywgJX2S0taBvRbfoOgK03ypMtNq6oodjB4rxv2EX-Q==&ctx=CgsI4N2BvdyGxj8QBRIkZjcwZjExNTItYTllYy0xMWYxLWEyM2UtYjM4MzY0YTVjMTUyGiRmNzUxMjkyOS1hOWVjLTExZjEtYTk2OS00MGE0YTg4YmViNGU=&a=2", "offer_title": "Słuchawki Logitech G733 Lightspeed Białe - Ekspresowa wysyłka 24h", "delivery": "Wysyłka od 9,90 zł", "free_delivery": false, "dispatch": "Wysyłka w 1 dzień", "promoted": false, "product_id": "108733030" } ], "count": 22, "cheapest": 339, "most_expensive": 599.9 } }
How the Ceneo API works
Ceneo is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 188 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Turn a Polish product name into every shop's price for it
A Ceneo search card shows the from-price only. The band and the shops behind it are on the product, and the shops are the point.
{"query": "logitech g733", "sort": "price_asc"}One credit, 30 rows. Each carries product_id, the from-price and how many shops sell it - so you can skip anything with one shop before you spend a second call.
{"product_id": "108733030"}Two credits. Every merchant, sorted cheapest first, each with its Ceneo rating and delivery line. The response also names the cheapest and the most expensive offer explicitly.
{"product_id": "108733030"}One credit for the spec table and Ceneo's own published band and shop count - which is worth holding beside the offer list, for the reason in the coverage block below.
Four credits for a Polish keyword, a product record and the complete shop-by-shop price comparison behind it.
curl -X POST https://api.reefapi.com/ceneo/v1/product/offers \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"product_id":"108733030"}'{
"ok": true,
"data": { … },
"meta": {
"api": "ceneo",
"endpoint": "product/offers",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}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 read | Where it comes from | What it means |
|---|---|---|
| offers[] and most_expensive | the offer rows Ceneo renders | what the site actually shows a shopper right now |
| product.price_max | Ceneo's own published highPrice | what 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_count | Ceneo's own published count | matched 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 offer | the offer rows | equalled Ceneo's published lowPrice on 17 of 17 products, and 0 of 288 offers fell outside the published band |
| a search row's maximum price | not published | a 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.
Which country, which id, which currency, and where Ceneo disagrees with itself
ceneo.pl only - one country, one currency, ids that are bare numbers. Measured on 2026-09-06 across 17 products in 10 Ceneo categories and 288 offers, plus the live calls behind this page. Four of these lines go against us.
This engine reads ceneo.pl. Every price, shop rating and delivery line is Polish-scoped and quoted in PLN; there is no country parameter and no second storefront. Germany, Romania and the Benelux are the idealo, emag and bol engines instead.
A Ceneo product lives at ceneo.pl/108733030 and that number is the id. Every search row returns it as product_id, and both product actions take either the number or the full URL. There is no separate offer id you have to resolve first, and no slug to keep in sync.
Between 3 and 37 across the 17 measured products. The reference product - a Logitech G733 headset - returned 22 shops between 339.00 and 599.90 PLN when it was re-run for this page, including amazon.pl, morele.net, x-kom.pl, mediamarkt.pl and komputronik.pl. Note that the product page itself renders only about 15 rows and defers the rest; a default call fetches the rest too, which is what took the reference product from 13 offers to Ceneo's own published 22.
Against us, and it is the single most important thing on this page. Ceneo publishes a summary band and a shop count, and separately renders the offers themselves. On 4 of 17 measured products the published maximum was higher than the dearest offer the site actually rendered - on one product a claimed 733.99 PLN against a dearest listed offer of 699.90. Reconciling those into one number would be wrong either way, so the offer list and the summary are returned as two different things: offers[] is what the site shows, and the product band and count are what the site claims. The cheapest offer did equal the published minimum on 17 of 17, and 0 of 288 offers fell outside the published band.
On one product Ceneo says 37 shops and its own page renders 36. A parity run of the parser against the saved HTML lost 0 rows, so the missing offer is not ours - it is Ceneo's summary being out of step with Ceneo's list. Written down rather than smoothed over, because a page where every number is 100% reads as marketing.
Ceneo does not publish the merchant's own product URL, so it is not invented. What you get is the shop's domain and Ceneo's signed click-through link. For merchants that sell through Ceneo's own basket the domain is null too, because the site shows a display name only - measured live on 3 of the 22 offers on the reference product (Madman Gaming, Jedwabiście, 81-SPORTS). Their merchant name is still filled, which took parsing a second row shape that a domain-keyed parser misses entirely.
Ceneo prints 0 out of 0 for a shop it has not rated; returning that as 0.0 would make a new shop look terrible instead of unrated, so it comes back null - 280 of 288 measured offers carried a rating and every one of the 8 without had a rating count of zero. Separately, some keywords are answered by Ceneo with a category page rather than a result list, and a category page prints no result counter: the response says so with a search mode of "category" and names the category it resolved, instead of guessing a total.
Ask Ceneo for a product that has been retired and it answers HTTP 200 and redirects you to a category listing full of other people's products. Without a guard that returns 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, and returns NOT_FOUND otherwise. A malformed id gets an HTTP 500 error page, which is classified as NOT_FOUND once two independent attempts agree - not as a block you would retry forever.
Ceneo's price chart sits behind a login and this engine holds no account, so there is no history. Per-offer stock counts, EAN/GTIN and merchant review bodies are not on the page either. All of them come back null rather than filled in. What the page does publish, and what you get, is the price, the delivery text, whether delivery is free, the dispatch line and whether a row is a paid placement.
What people build with Ceneo
The jobs this data is most often used for.
endpoints
credits per call
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.
What Ceneo data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 188 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/ceneo/v1/product/offers \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"product_id":"108733030"}'import requests
r = requests.post(
"https://api.reefapi.com/ceneo/v1/product/offers",
headers={"x-api-key": REEF_KEY},
json={
"product_id": "108733030"
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Ceneo.
Get a free key →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.
39 E-commerce & Marketplaces APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Ceneo, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 187 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-09-06.