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

Skroutz API & Scraper

The Skroutz API turns Greece's price-comparison site into 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, and it is also the cheapest of the three: ONE upstream request, a 231 KB median, 1.4 s, and it returns every Greek merchant selling that product in one go - measured at 49 shops on a De'Longhi descaler and 48 on an iPhone 17 Pro Max. Each row carries the shop's Skroutz id, name, storefront link, star rating and how many ratings it rests on, the shop's town and country, the price as a number, the shipping fee, the total including shipping, the delivery estimate, the stock line and the shop's own listing title. Verification on 2026-09-06 covered 13 products across 8 Skroutz categories and 332 offers: price, seller name, seller id, seller URL, seller location, offer URL, shipping cost and delivery estimate were all filled on 332 of 332, and every one of the 332 prices matched an independent second extraction of the same page - 0 mismatches. search returns the product grid with the id you feed to product/offers, and product/detail returns the full Greek record: title, brand, MPN, model, colour, description, gallery, the customer rating with its per-star breakdown, and the complete technical specification grouped as Skroutz groups it. Prices are EUR. No Skroutz account, no browser - one ReefAPI key and the standard { ok, data, meta, error } envelope.

Reference

The price on a Skroutz product page is the FEATURED offer, not the cheapest one

This is the single most important thing to know before you build against Skroutz, and it is why price_min is deliberately null on product/detail. Skroutz prints one price on a product page and on a listing card: the offer it features. Checked against the same product's own merchant table on all 13 verification products on 2026-09-06, that price equalled the cheapest offer on 6 and sat ABOVE it on 7. It is always one of the real offer prices - it is honest data - but calling it a price floor would be a lie by field name.

Skroutz productPrice on the product pageCheapest merchant offerWhere the featured offer ranked
Bosch Mymoment TKA2M113 filter coffee maker41.52 EUR37.79 EUR16th of 29 offers - the worst case measured
Apple iPhone 17 Pro Max1,370.00 EUR1,362.40 EUR2nd of 48
LG Smart 32-inch Full HD TV192.90 EUR191.52 EUR3rd of 33
New Balance 530109.00 EUR108.99 EUR2nd of 43
Nike Air Force 1 '07108.00 EUR107.96 EUR2nd of 39
Samsung Smart 43-inch 4K QLED286.00 EUR285.86 EUR2nd of 29
Ulefone Armor 28 Ultra 5G944.90 EUR944.88 EUR2nd of 36

So product/detail returns that number as price and returns price_min, price_max and offer_count as null, pointing at product/offers - which is the only surface where the real band and the real count exist. product/offers returns both, and its count matched the shop count Skroutz prints on its own merchant table on 10 of the 10 products where Skroutz prints one (14/14, 9/9, 29/29, 29/29, 33/33, 36/36, 39/39, 43/43, 48/48, 49/49). That parity is what establishes there is no hidden pagination to chase.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/skroutz/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "teka gfh 73"
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "skroutz",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 1253.7,
    "record_count": 3,
    "bytes": 121993,
    "cache_hit": false,
    "pagination": {
      "page": 1,
      "has_more": false,
      "page_size": 3,
      "total": 3
    }
  },
  "data": {
    "results": [
      {
        "product_id": "809",
        "title": "Teka GFH 73 Μηχανισμός Απορρόφησης 73cm Inox",
        "url": "https://www.skroutz.gr/s/809/Teka-GFH-73-Michanismos-Aporrofisis-73cm-Inox.html",
        "image": "https://a.scdn.gr/images/sku_main_images/000000/809/large_[redacted-phone]_teka_gfh_73_michanismos_aporrofisis_73cm_inox.jpeg",
        "price": 130,
        "price_display": "130,00 €",
        "price_from": 130,
        "price_to": null,
        "variant_family": false,
        "price_before_discount": null,
        "currency": "EUR",
        "rating": null,
        "review_count": null,
        "rating_scale": null,
        "category": "Απορροφητήρες Κουζίνας",
        "category_url": "https://www.skroutz.gr/c/408/aporrofitires_kouzinas.html",
        "key_specs": "Απορροφητική Ισχύς: Max 329m³/h, με Πλενόμενο Φίλτρο",
        "delivery": null,
        "promoted": true
      },
      {
        "product_id": "40592764",
        "title": "Teka Ανταλλακτικό Φίλτρο Ενεργού Άνθρακα 12x12cm",
        "url": "https://www.skroutz.gr/s/40592764/Teka-61801346-Antallaktiko-Filtro-Energou-Anthraka-Aporrofitira-Symvato-me-Teka-12x12cm.html",
        "image": "https://d.scdn.gr/images/sku_main_images/040592/40592764/large_[redacted-phone]_teka_cnl_1c_antallaktiko_filtro_energou_anthraka_aporrofitira_symvato_me_teka_61801346.jpeg",
        "price": 13,
        "price_display": "13,00 €",
        "price_from": 13,
        "price_to": null,
        "variant_family": false,
        "price_before_discount": null,
        "currency": "EUR",
        "rating": 1,
        "review_count": 1,
        "rating_scale": null,
        "category": "Αξεσουάρ Απορροφητήρων",
        "category_url": "https://www.skroutz.gr/c/4202/axesouar-aporrofitiron.html",
        "key_specs": "Συμβατότητα: Teka",
        "delivery": "Παράδοση έως Τετ, 09 Σεπ",
        "promoted": false
      },
      {
        "product_id": "53083779",
        "title": "Wessper Ανταλλακτικό Φίλτρο Ενεργού Άνθρακα",
        "url": "https://www.skroutz.gr/s/53083779/Wessper-OP-5575-Antallaktiko-Filtro-Energou-Anthraka-Aporrofitira-Symvato-me-Teka.html",
        "image": "https://b.scdn.gr/images/sku_main_images/053083/53083779/large_[redacted-phone]_wessper_op_5575_antallaktiko_filtro_energou_anthraka_aporrofitira_symvato_me_teka_[redacted-phone].jpeg",
        "price": 12.9,
        "price_display": "12,90 €",
        "price_from": 12.9,
        "price_to": null,
        "variant_family": false,
        "price_before_discount": null,
        "currency": "EUR",
        "rating": null,
        "review_count": null,
        "rating_scale": null,
        "category": "Αξεσουάρ Απορροφητήρων",
        "category_url": "https://www.skroutz.gr/c/4202/axesouar-aporrofitiron.html",
        "key_specs": "Συμβατότητα: Teka",
        "delivery": "Παράδοση έως Τετ, 09 Σεπ",
        "promoted": false
      }
    ],
    "count": 3,
    "duplicate_cards_dropped": 1,
    "total_results": 3,
    "search_mode": "keyword",
    "resolved_title": null,
    "resolved_url": "https://www.skroutz.gr/search?keyphrase=teka+gfh+73",
    "query": "teka gfh 73",
    "page": 1
  }
}
Actions

What the Skroutz API does

ActionDescriptionConcrete use caseKey params
searchSearch skroutz.gr by keyword and get the matching products: Skroutz product id, title, image, the price skroutz prints on the card (the offer it FEATURES, which is not always the cheapest one — measured 120,00 € on a card whose cheapest merchant offer was 108,99 €; null when the card shows a variant range instead, with the endpoints in price_from/price_to), the customer rating and review count, the category and skroutz's own key-spec summary. Use the returned `product_id` with `product/offers` to get every Greek shop's price for that product.Pricing teams call search to search skroutz.gr by keyword and get the matching products.query, page, max_rotations
product/detailThe full Skroutz product record by `product_id` (or product URL): title, brand, description, image gallery, manufacturer part number, model and colour, the price skroutz features on the page, the customer rating with its review count and per-star breakdown, the category, and the complete technical specification grouped exactly as skroutz groups it.Marketplace operators call product/detail to get the full Skroutz product record by `product_id` (or product URL).product_id, max_rotations
product/offersEvery Greek merchant offer for one product — the price comparison itself, in a single request. For the given `product_id` you get one row per shop: the shop with its Skroutz id, name, storefront link, star rating and how many reviews it rests on, its town, the price (numeric and formatted), the price before a running coupon and the discount, the shipping fee and the total, the promised delivery date, declared stock, and the merchant's own listing title. Rows are ordered cheapest first.Catalog enrichment teams call product/offers to get every Greek merchant offer for one product.product_id, sort, include_product, max_rotations
Code samples

Call search from your stack

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

Who uses this API and why

  • Greek price-monitoring teams call product/offers to get every merchant's price, shipping fee, total and delivery date for one product in a single request.
  • Repricing tools read price_min and price_max from product/offers rather than the product page, because the page price was above the cheapest offer on 7 of 13 measured products.
  • Marketplace sellers check where their own Skroutz offer ranks among up to 49 competitors, with each shop's star rating and rating count attached.
  • Catalog teams call product/detail for the Greek title, brand, MPN, model, colour and the full spec table grouped exactly as Skroutz groups it.
FAQ

Questions developers ask before integrating

How many Greek shops does one product/offers call return, and what does it cost?

As many as Skroutz lists, in a single upstream request - there is no pagination on the merchant table. Measured on 2026-09-06: 49 shops on a De'Longhi descaler (382 KB, 1.5 s), 48 on an iPhone 17 Pro Max (361 KB, 1.4 s), 43 on a New Balance 530, 36 on a Ulefone Armor 28 Ultra, 14 on the Teka GFH 73 reference product (102 KB, 0.96 s). A single-merchant product is 21 KB and 0.63 s. Median across the 13 products was 231 KB and 1,425 ms. That makes offers the CHEAPEST of the three actions on bytes - a product page is 429 KB median - which is unusual for a price-comparison site and is the reason it is priced the same as the other two rather than above them.

Is the price on a search row or a product page the cheapest price?

No. It is the offer Skroutz features, and it was above the cheapest merchant offer on 7 of the 13 verification products - once by 10 percent, at rank 16 of 29. On a listing card the same rule holds: a card reading 120,00 EUR sat on a product whose cheapest merchant offer was 108,99 EUR. If you need a floor, call product/offers and read price_min there; that action returns the real band and its cheapest and most expensive rows. product/detail returns price_min, price_max and offer_count as explicit nulls so you cannot mistake the featured price for a band.

Why is price null on some search rows?

Because that card is a variant family and Skroutz printed a RANGE instead of a price - "285,86 EUR - 1.999,00 EUR" for a TV sold in 43 to 98 inches. Measured on the television category page: 33 of 48 cards were in that state. A first-number-wins parser would return 33 confident wrong prices there, so the engine returns price as null, puts the two endpoints in price_from and price_to, sets variant_family to true, and always returns price_display with exactly the string Skroutz printed. Between price and price_to, every row on every page measured was accounted for: 48/48 TVs, 52/52 perfumes, 57/57 laptops, 55/55 washing machines.

Does the merchant price include a coupon discount?

Yes, and this one is a trap in the raw page. Each merchant row carries a data attribute with a pre-coupon price, and on a row with a running coupon that number is wrong: the rendered price was 759,05 EUR, the struck-through price 799,00 EUR and the coupon 39,95 EUR. Reading the attribute would ship a price 39.95 EUR too high while returning ok:true. The engine reads the rendered final price instead and returns price_before_discount and discount alongside it. 3 of the 332 measured offer rows were in that state - rare, and exactly the rows a customer would notice.

Why does a search sometimes return a category page instead of search results?

Because Skroutz answers broad keywords with one of its own pages - "laptop" becomes its laptops category, "samsung" becomes its Samsung brand page - and it drops the page number on the way, so asking for page 2 of a redirected keyword returns page 1 again. The engine detects that and re-requests from the resolved URL, so paging works either way; it costs one upstream request when Skroutz stays on its search route and two when it redirects. The response tells you which happened: search_mode reads keyword or resolved, with resolved_title and resolved_url. A keyword can also resolve onto an editorial article, which carries no product cards at all - that comes back as an honest count of 0 with the article URL, not as an error.

How reliable is the parsed price - has it been checked against the page?

Twice, independently. A second extractor written as raw regex over each merchant block, sharing no code with the engine's parser, agreed on 332 of 332 offer rows. The only two rows where the two disagreed at all were merchant NAMES, and there the engine was the more correct one - it decodes HTML entities, so it returns "Woman's Fashion" and "Web & IT" where the naive extractor returns the escaped text. A recursive scan of every string in all 26 verification payloads found 0 raw HTML tags and 0 HTML entities.

Is a shop rating of zero a real rating?

There is never a zero. 252 of 332 measured offers carried a shop rating; the other 80 came from shops Skroutz has genuinely not rated, and those return null for both the rating and the rating count, never 0.0. The invariant was checked directly - 0 rows had a null rating sitting next to a non-null rating count. Note also that a shop's rating and a product's rating are two different numbers and are returned in two different places: on one verification product the item had a review_count of 6 while its single seller had a rating_count of 3.

What does Skroutz NOT publish?

A rating scale, first of all: there is no maximum-rating value anywhere in the page or its structured data, so rating_scale is null on every action rather than an assumed 5. What you get instead is the per-star histogram itself, so you can read the buckets first-hand. Also absent: a price band or shop count on the product page (both live on product/offers), a link into the merchant's own site - the only link Skroutz exposes is its own click-through - an exact stock number when the shop declares a band like "5+ pieces" (the text is returned, the number stays null), a per-size price, since Skroutz prices the product rather than the size, and a shop rating for an unrated shop. Skroutz also has no stable search page size; it returns 48 to 60 rows depending on the page it resolved to, so read count.

What is the Skroutz API?

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

Is the Skroutz API free to try?

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

Do I need a Skroutz login or account?

No login to Skroutz 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 Skroutz 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 Skroutz API use?

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

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

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

docs / skroutz

Skroutz

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

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

The full Skroutz product record by `product_id` (or product URL): title, brand, description, image gallery, manufacturer part number, model and colour, the price skroutz features on the page, the customer rating with its review count and per-star breakdown, the category, and the complete technical specification grouped exactly as skroutz groups it.

ParameterAllowed / rangeDescription
product_idrequiredSkroutz product (SKU) id — the number in the product URL (https://www.skroutz.gr/s/809/…html → 809). A full product URL is also accepted. Every `search` row returns it 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/skroutz/v1/product/offers1 credit

Every Greek merchant offer for one product — the price comparison itself, in a single request. For the given `product_id` you get one row per shop: the shop with its Skroutz id, name, storefront link, star rating and how many reviews it rests on, its town, the price (numeric and formatted), the price before a running coupon and the discount, the shipping fee and the total, the promised delivery date, declared stock, and the merchant's own listing title. Rows are ordered cheapest first.

ParameterAllowed / rangeDescription
product_idrequiredSkroutz product (SKU) id — the number in the product URL (https://www.skroutz.gr/s/809/…html → 809). A full product URL is also accepted. Every `search` row returns it as `product_id`.
sort = priceoptionalprice · final_priceOrder of the merchant rows. Only the orderings skroutz.gr actually honours are accepted; anything else is rejected rather than silently ignored. (The site's third ordering, 'nearest shop', needs a shopper location and is not offered here.) The response is additionally sorted cheapest-first by `price`.
include_product = falseoptionalfalse (default) keeps this a single 105 KB request and returns the product block skroutz publishes on the merchant table itself (id, brand, category, price band, offer count) with `title` null. true fetches the product page as well so `product.title`, images, rating and specs are filled in — one extra request, ~200 KB.
max_rotations = 4optional1–8Advanced: how many times to retry a difficult request (1-8, default 4 — leave unchanged for typical use).
Try in playground →