Bol Offers avatar

Bol Offers

Pricing

from $15.00 / 1,000 bol-offers

Go to Apify Store
Bol Offers

Bol Offers

Give it EAN/GTIN codes and get the bol.com buy box for each: winning seller, price, shipping, total price, condition and availability, in the Netherlands and Belgium. One row per EAN. bol.com publishes one winning offer per product, not a full seller list.

Pricing

from $15.00 / 1,000 bol-offers

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Bol.com Buy Box Scraper - Winning Offer by EAN

Give this Actor a list of EAN/GTIN codes and it returns the bol.com buy box for each one: the winning seller, price, shipping, total price, condition and availability, in the Netherlands and Belgium.

It reads a cache that ShoppingScraper keeps warm rather than hitting bol.com live on every call, which has one consequence worth knowing up front.

The first lookup is free

Every EAN comes back in one of three states:

statuswhat it meanscharged
cachedthe buy box is readyyes
scraped_no_offersthe scrape ran and bol.com had no offer for ityes
queued_for_scrapenothing known yet, a scrape has just been queuedno

An EAN nobody has asked for before is scraped on demand, which takes about five minutes. The run waits for that (up to wait_for_scrape_seconds, ten minutes by default) and returns the offers in the same run, so a cold cache normally costs you a few minutes, not a second run. A row only stays queued_for_scrape when the scrape had not landed by the time the wait ran out.

A queued_for_scrape row costs you nothing, and that is enforced by where it is written rather than by a promise. Charged rows go to the default dataset, which is what Apify bills per item. Queued rows never touch it: they are listed in a QUEUED_EANS record in the key-value store, together with the list to retry, and the run summary says how many are still open. Run the Actor again for those EANs a few minutes later.

scraped_no_offers is charged on purpose: "nobody sells this on bol.com" is a real answer, and it took a real scrape to establish.

It is the buy box, not the seller list

bol.com publishes one winning offer per product plus a price range, so offers_count is at most 1. If you need every seller on a listing, this is not that Actor, and no setting here will change it.

Input

FieldTypeDefaultNotes
eansarrayrequiredEAN/GTIN codes.
countrystringnlnl or be. Everything else is rejected.
max_age_hoursinteger24How old a cached result may be and still count as a hit.
wait_for_scrape_secondsinteger600How long the run polls for EANs that had to be scraped first. 0 returns immediately.
forcebooleanfalseDemand data newer than the TTL and trigger an immediate re-scrape.
ttl_hoursinteger6Only used with force.
concurrencyinteger10EANs looked up at once.

EAN only. The endpoint does not accept bpid, sku or product_id; those return an error. A bol product id passed in the EAN field is accepted and queued, and the row is flagged bpid_passthrough: true so you can tell those rows apart, but whether the upstream scraper resolves a bol id rather than a GTIN is not something this Actor can promise.

Output

One row per EAN, so the output joins straight back onto your input list through requested_identifier, including rows that are still queued.

{
"channel": "bol",
"ean": "8710398523082",
"gl": "nl",
"requested_identifier": "8710398523082",
"found": true,
"status": "scraped_no_offers",
"billed": true,
"offers_count": 0,
"offers": []
}

What this does not do

No product description, no rating, no review count. The offers endpoint carries seller and price data, and this Actor passes through what is there.

already_queued on a queued row is global: true when anyone at all has a scrape running for that combination, not only you. It is information, never a billing signal.

FAQ

Why did my run return nothing? Either the EAN had not been scraped on bol.com yet and the scrape did not land inside the wait (the row says queued_for_scrape, it was free, run again in a few minutes), or the lookup itself failed. A failed lookup is never dressed up as "no offers": it is listed in the errors record, and when every lookup fails the run is marked failed with the reason.

Why only one offer? Because bol.com shows a buy box rather than a seller list. See above.

Does Belgium work the same as the Netherlands? Both are accepted by the endpoint. Belgian coverage is thinner in practice, so expect more queued_for_scrape rows on a first pass.