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

BestPrice.gr API & Scraper

The BestPrice.gr API turns Greece's second large price-comparison site into JSON in three actions.

4 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.

search takes Greek or English keywords and returns the product grid: product_id, title, url, the price BestPrice prints on the card, the category id and the product image, with the shop count where the card carries one. category walks one category's grid without a keyword, and takes an optional keyword to narrow it. product is the action the source exists for: the shop-by-shop offer table for one product, each row carrying the shop's name, its price in euros, its availability and its link, plus the product's brand, GTIN, the Greek category path, the customer rating and the market's price band. Two counts come back on purpose and they are not the same number: offer_count is how many shops the market has for that product and offers_listed is how many this response carries, because BestPrice lists the first thirty on the page itself. Measured on 2026-09-23 through the live gateway: on 103 search rows across six queries and a category, product_id, title, url, price, image and category id were filled on every single row and the shop count on 74 percent of them; on eight products the offer table ran from 3 to 30 rows, and where the market had thirty or fewer shops every one of them came back. The price is a number in euros on every row, never a string and never the site's raw integer. This is a second Greek market source beside Skroutz, useful for the same product from two comparison sites. One ReefAPI key, the standard { ok, data, meta, error } envelope, and no BestPrice account of any kind.

Reference

Which BestPrice number is which

Four of these fields look interchangeable and are not. Measured through the live gateway on 2026-09-23.

FieldWhat it isMeasured example
price_eur (search row)The price BestPrice prints on the grid card, in euros610.00 on the iPhone 15 128GB card
price_low_eur / price_high_eurThe band across the WHOLE market for that product, as the product page states it610.00 to 999.00 while the market had 74 shops
offer_countHow many shops the market has for the product74, 87 and 71 on three measured products
offers_listedHow many offers THIS response carries. The product page lists the first thirty30 of 74; but 23 of 23 and 3 of 3 where the market is smaller
offers[].price_eurOne shop's own price. The lowest of these equals price_low_eur701.33 lowest, 885.00 highest listed, on a product whose band reaches 964.26
shop_count (search row)The shop count printed on the grid card, when the card carries onefilled on 76 of 103 measured rows
offers[].availabilityThe stock line the shop declares, per offerInStock on 28 rows and BackOrder on 2 of the same product

The band and the offer list answer different questions: price_high_eur describes the whole market, while the offers array stops at the thirty the product page lists, so the highest listed offer can sit below price_high_eur. Compare like with like by reading offer_count beside offers_listed.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/bestprice/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "iphone"
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "bestprice",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 14804.6,
    "record_count": 14,
    "bytes": 121937,
    "cache_hit": false,
    "stop_reason": "complete",
    "query": "iphone",
    "charged_credits": 2,
    "version": "1.0.0"
  },
  "data": {
    "products": [
      {
        "product_id": "2162499899",
        "url": "https://www.bestprice.gr/item/2162499899/apple-iphone-17-256gb.html",
        "title": "Apple iPhone 17 256GB",
        "price_eur": 860,
        "currency": "EUR",
        "category_id": "806",
        "shop_count": 59,
        "image": "https://bbpcdn.pstatic.gr/bpimg59/2mlD0D/1VPsWP_SX250Y333/1770649991/apple-iphone-17-256gb-mg6j4qla-mg6m4qla-mg6l4qla-mg6n4qla-mg6k4qla.webp"
      },
      {
        "product_id": "2162499901",
        "url": "https://www.bestprice.gr/item/2162499901/apple-iphone-17-pro-max-256gb.html",
        "title": "Apple iPhone 17 Pro Max 256GB",
        "price_eur": 1243,
        "currency": "EUR",
        "category_id": "806",
        "shop_count": 66,
        "image": "https://bbpcdn.pstatic.gr/bpimg61/2mlD0F/1VPsYV_SX250Y333/1770650121/apple-iphone-17-pro-max-256gb-mfyn4qla-mfyp4qla-mfym4qla.webp"
      },
      {
        "product_id": "2162499900",
        "url": "https://www.bestprice.gr/item/2162499900/apple-iphone-17-pro-256gb.html",
        "title": "Apple iPhone 17 Pro 256GB",
        "price_eur": 1132.88,
        "currency": "EUR",
        "category_id": "806",
        "shop_count": 65,
        "image": "https://bbpcdn.pstatic.gr/bpimg60/2mlD0E/1VFXeJ_SX250Y333/1768383141/apple-iphone-17-pro-256gb-mg8h4qla-mg8j4qla-mg8g4qla.webp"
      }
    ],
    "page": 1,
    "limit": 24,
    "query": "iphone"
  }
}
Actions

What the BestPrice.gr API does

ActionDescriptionConcrete use caseKey params
searchSearch BestPrice by keyword. Returns the product grid: title, the price BestPrice shows (the lowest across shops), how many shops carry it, and the product id you feed to `product`.Pricing teams call search to search BestPrice by keyword.query, page, limit
barcodeFind a product by its BARCODE (EAN-13, EAN-8, UPC-12 or GTIN-14) and get the BestPrice product id, so a catalogue can be matched on barcodes instead of names. Keyword `search` cannot do this: BestPrice's text index has no barcodes in it. Each row carries `match_type`: `barcode_exact` means BestPrice itself declared an exact barcode match (measured 25 of 25 correct, no false positive), `text_match` means it fell back to a fuzzy name match and MAY be a different product. By default only exact matches are returned. Coverage is partial and honest: 25 of 36 barcodes taken off BestPrice's own product pages resolved (3/3 in electronics, appliances, laptops, toys and tools; 1/3 in supermarket and beauty), so an empty answer means BestPrice's barcode index does not carry that code — not an error. Feed the returned `product_id` to `product` for every Greek shop's price.Marketplace operators call barcode to find a product by its BARCODE (EAN-13, EAN-8, UPC-12 or GTIN-14) and get the BestPrice produc….barcode, strict, limit
productOne product with EVERY shop offer: the shop name, its price, availability and the price band across the market (lowest, highest, how many shops). This is the whole point of a price-comparison source. It also returns the product's BARCODE (`gtin`, with `gtin_type` naming the key it came from) — published on 36 of 36 pages measured across 12 categories — so a catalogue can be matched on barcodes even for the codes BestPrice's `barcode` lookup does not carry.Catalog enrichment teams call product to get one product with EVERY shop offer.product_id
categoryBrowse one category's grid without a keyword. Same rows as `search`. Take the category id from a search row's `category_id` or from a category URL.Retail analysts call category to get browse one category's grid without a keyword.category_id, page, limit, query
Code samples

Call search from your stack

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

Who uses this API and why

  • Greek price monitoring: one product id, every listed shop's price and stock, plus the market's low and high in euros.
  • Repricing for Greek e-shops: watch where your own shop sits in the offer table for the products you carry.
  • Cross-checking a second comparison site beside Skroutz before publishing a price or a claim about the cheapest offer.
  • Catalogue enrichment: brand, GTIN, the Greek category path and the product image from a keyword or a category walk.
  • Market research on a Greek category: walk the grid by category id and read prices and shop counts across the shelf.
FAQ

Questions developers ask before integrating

Do I get every Greek shop selling a product?

You get every offer the product page lists, which is the first thirty, and you are told how many the market has. Measured on eight products on 2026-09-23: 30 of 74, 30 of 87, 30 of 71, 25 of 26, and 23 of 23, 23 of 23, 23 of 23 and 3 of 3 where the market had thirty or fewer shops. So for most products you get all of them, and for the very crowded ones you get the cheapest end of the table plus an honest count of what is behind it. offers_listed and offer_count are both in the response so you never have to guess which you are holding.

Does it work with Greek keywords?

Yes, and that is the better way to search it. Greek queries were measured alongside English ones on 2026-09-23 and returned the same shape of rows, so a category phrase in Greek works as naturally as a brand and model in Latin letters. Titles, the category path and the stock lines come back in the site's own language, unmodified.

Is the price a number, and in which currency?

A number, in euros, on every row. The site's own markup carries the price as an integer, which is the trap a hand-written parser walks into and publishes a price a hundred times too large; the conversion happens once inside the engine, so price_eur is 610.0 and never 61000. There is one currency here because there is one market: bestprice.gr is Greece only, and there is no country parameter behind it.

How do I go from a search result to the shop comparison?

Every search and category row hands back product_id, and product takes that id or a full bestprice.gr product URL. A dead or wrong id is answered with NOT_FOUND rather than an empty-looking success, which matters here because the site answers an unknown product with a normal page rather than a 404.

What does this add if I already use Skroutz?

A second Greek comparison site for the same product. The two rank shops differently and do not carry identical merchant sets, so reading both is how a Greek pricing tool sees the market rather than one site's view of it. Both are separate engines here with their own actions and their own credit prices.

Which fields can be empty?

Measured across 103 rows on 2026-09-23: product_id, title, url, price, image and category id were filled on all 103, and shop_count on 76 of them, because BestPrice does not print a shop count on every grid card. On the product side, the rating and its count come back as null when the site publishes no rating for that product, which was the case on four of the eight measured products, rather than being dressed up as a zero.

What is the BestPrice.gr API?

BestPrice.gr API is a ReefAPI endpoint group for greek price comparison: every shop's price for one product, the market's price band and the shop count, in eur. It returns live JSON through POST requests under /bestprice/v1.

Is the BestPrice.gr API free to try?

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

Do I need a BestPrice.gr login or account?

No login to BestPrice.gr 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 BestPrice.gr 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 BestPrice.gr API use?

BestPrice.gr actions currently cost 1-3 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.

Can I call BestPrice.gr from an AI assistant or MCP client?

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

Is the BestPrice.gr API a BestPrice.gr scraper?

It is the managed alternative to a DIY BestPrice.gr 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 greek price comparison: every shop's price for one product, the market's price band and the shop count, in eur back as clean JSON.

Why does my BestPrice.gr scraper keep getting blocked?

Most BestPrice.gr scrapers break on anti-bot defenses, rate limits and IP bans that need rotating residential proxies and browser fingerprinting to clear. ReefAPI handles all of that for you — no proxies, no captchas, no maintenance — and returns live JSON. Blocked calls are free.

docs / bestprice

BestPrice.gr

Greek price comparison: every shop's price for one product, the market's price band and the shop count, in EUR.

base /bestprice/v14 endpoints
post/bestprice/v1/barcode1 credit

Find a product by its BARCODE (EAN-13, EAN-8, UPC-12 or GTIN-14) and get the BestPrice product id, so a catalogue can be matched on barcodes instead of names. Keyword `search` cannot do this: BestPrice's text index has no barcodes in it. Each row carries `match_type`: `barcode_exact` means BestPrice itself declared an exact barcode match (measured 25 of 25 correct, no false positive), `text_match` means it fell back to a fuzzy name match and MAY be a different product. By default only exact matches are returned. Coverage is partial and honest: 25 of 36 barcodes taken off BestPrice's own product pages resolved (3/3 in electronics, appliances, laptops, toys and tools; 1/3 in supermarket and beauty), so an empty answer means BestPrice's barcode index does not carry that code — not an error. Feed the returned `product_id` to `product` for every Greek shop's price.

ParameterAllowed / rangeDescription
barcoderequired—The barcode: EAN-13 (8806091024749), EAN-8, UPC-12 or GTIN-14. Spaces and hyphens are ignored. A 13-digit code that misses is retried zero-padded to 14 automatically.
strict = trueoptional—true (default): return ONLY rows BestPrice declared an exact barcode match for. false: also return its fuzzy name matches, marked `match_type: text_match` — useful for review, but 2 of 6 measured fuzzy rows were a DIFFERENT product, so do not treat one as a barcode match.
limit = 8optional1–8Rows to return (1-8). The source's own ceiling is 8; a barcode normally resolves to exactly one.
Try in playground →
post/bestprice/v1/product3 credits

One product with EVERY shop offer: the shop name, its price, availability and the price band across the market (lowest, highest, how many shops). This is the whole point of a price-comparison source. It also returns the product's BARCODE (`gtin`, with `gtin_type` naming the key it came from) — published on 36 of 36 pages measured across 12 categories — so a catalogue can be matched on barcodes even for the codes BestPrice's `barcode` lookup does not carry.

ParameterAllowed / rangeDescription
product_idrequired—The numeric product id, or a bestprice.gr product URL.
Try in playground →
post/bestprice/v1/category2 credits

Browse one category's grid without a keyword. Same rows as `search`. Take the category id from a search row's `category_id` or from a category URL.

ParameterAllowed / rangeDescription
category_idrequired—Numeric category id (806), or a bestprice.gr category URL.
queryoptional—Optional keyword to narrow the category.
page = 1optional1–1-based page of the grid (24 products a page).
limit = 24optional1–24Rows to return from the page (1-24). The source serves 24 a page; use `page` for more.
Try in playground →
Built for volume
5M+ requests a day

Measured at 60 requests a second across the fleet, with no central bottleneck. Volume pricing is on request, and per-key limits are raised for high-volume accounts.

Missing a source?
We build it

Tell us a site we do not cover yet and it becomes an engine. A customer asked for bestprice.gr on a Sunday and it was in the catalog the next day.

Support
2 minute median reply

Median time from a question in the live chat to the first answer, measured across every answered conversation. Setup help included, no support tier to buy.

One key, one balance
Every API included

No per-site plans and no separate subscriptions. One key and one credit pool across the whole catalog, so adding a source costs nothing up front.

Planning something large? Tell us the volume and the sources and we will come back with what it costs and what we would have to build.