PLUS Scraper avatar

PLUS Scraper

Pricing

from $1.50 / 1,000 products

Go to Apify Store
PLUS Scraper

PLUS Scraper

PLUS supermarket product API alternative: all ~17,300 plus.nl products with prices, unit prices, deals with dates, EAN barcodes on every product and, on request, Nutri-Score and vegan labels, in about 3 minutes, no proxy. Every run checks its count against PLUS's own total.

Pricing

from $1.50 / 1,000 products

Rating

0.0

(0)

Developer

Sleep Mode Systems

Sleep Mode Systems

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 hours ago

Last modified

Categories

Security

Limited permissions

Share

PLUS Scraper extracts products from PLUS supermarket (https://www.plus.nl): prices, unit prices, deals (aanbiedingen) with their dates, an EAN barcode on every product, organic flag, categories and stock status, and on request Nutri-Score, vegan, vegetarian and deposit labels. It is the only PLUS actor that reads the full catalog, and every run checks itself: it compares the products it read with PLUS's own total and reports the result as coverage, which was 1 (17,326 of 17,326) in the last full run.

Price: $1.50 per 1,000 products, plus $1.00 per 1,000 for product details. A full run reads all 17,326 products in about 3 minutes on Apify, with no proxy.

What does the PLUS Scraper extract?

DataFieldsFilled in last full run
IdentityexternalId, name, brand, ean, gtins100%: every product has its barcode
SizesizeText, packCount, quantity, unit99.5%
Priceprice, currency, unitPrice, unitPriceUnit100% price, 99.5% unit price
DealspromoPrice, promoText, promoType, promoStart, promoEnd1,587 products on a deal (9.2%), all with dates
Product factsorganic, badges, storeOnly100% organic flag (1,030 organic), 240 store-only
With detailsnutriScore, vegan, vegetarian, deposit, quality logos in badgeswith withDetails: Nutri-Score 28.5% (4,931), vegan 2,875, vegetarian 4,517, deposit 1,048
CategorycategoryPath, category100%
Links and stockurl, imageUrl, inStock100% url and stock flag, 99.4% image

Last full run: 2026-11-04, 17,326 products, 1,524 requests, all HTTP 200.

Who uses the PLUS Scraper?

  • Price comparison sites load the full catalog and match it to Albert Heijn, Jumbo and Dirk on ean, which every PLUS product has.
  • Deal and folder apps read this week's PLUS aanbiedingen with promoStart, promoEnd and the deal text.
  • Brand and category managers follow their own and competing products' price and deals at PLUS per week.
  • Retail and market analysts track PLUS's prices, its own brand (3,710 PLUS products) and deal share across 31 top-level categories.
  • Nutrition and food apps use nutriScore, vegan, vegetarian and organic with withDetails.
  • Developers who need a PLUS supermarket product API without maintaining one call this actor from JavaScript, Python or REST.

How much does the PLUS Scraper cost?

Pay per event. You pay for products written to the dataset, for product details when you ask for them (from the details file or read live, the same price), and a tiny start fee. Platform usage is included.

EventPrice
Product written to dataset$0.0015
Product details (withDetails)$0.001 per product
Actor start$0.00005 per run at the default 512 MB

PLUS Scraper cost examples

ScenarioProductsCost
Small test, maxItems: 100100$0.15
Keyword search, keywords: ["halfvolle melk"]57$0.09
Same search with withDetails57$0.14
This week's deals, onlyBonus: true1,587$2.38
Full catalog17,326$25.99
Full catalog with details17,326$43.32
Full catalog every week, 4 runs a month69,304$103.96

Product counts are from runs on 2026-11-04. Set maxItems to cap any run. Set the run's maximum charge in Apify to cap spend; the actor stops cleanly when it is reached and reports how many products it got.

How do you configure the PLUS Scraper?

FieldTypeDefaultMeaning
keywordsarray of stringsemptySearch for these words instead of reading the full catalog.
eansarray of stringsemptyLook up these barcodes instead of reading the full catalog.
onlyBonusbooleanfalseKeep only products on a deal, in any mode.
withDetailsbooleanfalseAdd each product's details: Nutri-Score, vegan, vegetarian, deposit, quality logos, from the actor's details file.
freshDetailsbooleanfalseWith withDetails: read every product's details live from PLUS, with in-store availability.
maxItemsinteger100000Stop after this many products. The default covers the full catalog.
minItemsinteger1Fail the run if fewer products were found.

With keywords and eans empty, the actor reads the full catalog.

How do you scrape the full PLUS supermarket catalog with the PLUS Scraper?

Use it for a complete list of PLUS products with prices and barcodes. Leave the input empty. The actor reads PLUS's whole product list, compares the count with PLUS's own total, and reads the list once more if it came up short.

{}

How do you get the PLUS aanbiedingen of this week with the PLUS Scraper?

onlyBonus keeps products on a deal and works with every mode. Free-delivery offers do not count. On the full catalog it reads all products and stores those on a deal: 1,587 in the last run, 1,287 of them running Wednesday 4 to Tuesday 10 November.

{
"onlyBonus": true
}

How do you search PLUS by keyword with the PLUS Scraper?

Use it when you need a product group. One PLUS search runs per keyword, with all result pages: halfvolle melk returned 57 products.

{
"keywords": ["halfvolle melk", "pindakaas"]
}

How do you look up PLUS products by EAN barcode with the PLUS Scraper?

PLUS's own search does not find barcodes. The actor knows the barcode of every PLUS product from a file it carries, finds the products, and reads the list for their current price and deal: about 3 minutes on Apify, however many barcodes. Leading zeros are optional. A barcode the file does not know is looked for among products new since; one not found is not on sale, and has expected: 0 in the run summary.

{
"eans": ["8413498121102", "8718182066272"]
}

How do you get Nutri-Score and vegan labels with the PLUS Scraper?

Set withDetails. Every product then carries its details: Nutri-Score, organic, vegan and vegetarian logos, deposit (statiegeld) and quality marks such as Beter Leven or MSC. PLUS gives details only one product at a time, so the actor ships with a details file read in one full run (detailsDate, 2026-11-05 for the current file: 17,345 of 17,345 products) and reads live only the products the file does not know. A full run with details then takes about 2 minutes (125 seconds and 1,562 requests locally, 32 products read live), instead of about 28 minutes. On a search of 916 products, the details from the file and read live were identical for every product.

Set freshDetails as well to read every product's details from PLUS now, including in-store availability: one request per product, a few seconds on a search, about 28 minutes on the full catalog.

{
"keywords": ["yoghurt"],
"withDetails": true
}

Which fields does the PLUS Scraper output?

Source: PLUS = PLUS's value unchanged. Derived = computed by this actor. Fixed = same in every item. File = the barcode file the actor carries. Input = from your input. Missing values are null, never an empty string.

FieldSourceMeaning
chainFixedAlways plus.
storeFixedAlways null: plus.nl's prices with no store chosen.
externalIdPLUSPLUS product id, such as 454439.
eanFileBarcode, mostly EAN-13.
gtinsDerivedThe barcode in a list, for the same field on other chains.
namePLUSProduct name.
brandPLUSBrand.
sizeTextPLUSSize as PLUS writes it, such as Per 750 ml or Per 30 st.
packCountDerivedUnits in a multipack; 1 when not a multipack.
quantityDerivedSize of one unit: Per 750 ml gives 750.
unitDerivedUnit of quantity: g, kg, ml, cl, l, stuk or m.
pricePLUSRegular price in EUR.
currencyFixedAlways EUR.
unitPriceDerivedRegular price per kg, litre, piece or metre, equal to PLUS's own on 99.6% of products.
unitPriceUnitDerivedUnit of unitPrice: kg, l, stuk or m.
promoPricePLUSDeal price in EUR, rounded to the cent, when lower than price.
promoTextPLUSThe deal as shown, such as 30 % KORTING, 1+1 GRATIS or 2 VOOR 2.99.
promoTypePLUSPLUS's second label, such as OP=OP.
promoLabelsFixedAlways null on PLUS; kept for the same field on other chains.
promoStartPLUSFirst day of the deal, YYYY-MM-DD.
promoEndPLUSLast day of the deal, YYYY-MM-DD.
organicDerivedtrue when in PLUS's organic filter, named organic, or with an organic logo in the details.
nutriScorePLUSNutri-Score A to E, with withDetails.
badgesPLUSPLUS's logos, such as Laagblijver; with withDetails also VEGAN, Beter Leven 1 Ster, MSC Label.
veganDerivedVegan logo (with withDetails) or vegan in the name.
vegetarianDerivedVegetarian logo (with withDetails), vegan, or vegetarisch in the name.
depositPLUSDeposit (statiegeld) logo, with withDetails; otherwise null.
storeOnlyPLUStrue when sold in PLUS shops only, not online.
categoryPathPLUSCategory path, such as Zuivel, eieren, boter/Melk/Houdbare melk.
categoryIdsFixedAlways null: PLUS gives no category ids.
categoryPLUSTop-level category.
urlDerivedProduct page on plus.nl.
imageUrlPLUSProduct image.
inStockPLUStrue when the product can be ordered online.
availabilityLabelFixedAlways null on PLUS.
detailsReadDerivedtrue when the product's details are in the item, from the details file or read live (withDetails).
detailsDateDerivedDate the details were read: the details file's date, or the run's date when read live.
searchTermInputThe keyword or barcode that found the product; null in full-catalog mode.
scrapedAtFixedTime the product was read, ISO 8601.

PLUS Scraper output example

With withDetails:

{
"chain": "plus",
"store": null,
"externalId": "762827",
"ean": "8718989755867",
"gtins": ["8718989755867"],
"name": "PLUS Cashewnoten Extra Groot (ongz)",
"brand": "PLUS",
"sizeText": "Per 170 g",
"packCount": 1,
"quantity": 170,
"unit": "g",
"price": 3.99,
"currency": "EUR",
"unitPrice": 23.47,
"unitPriceUnit": "kg",
"promoPrice": null,
"promoText": "2E HALVE PRIJS",
"promoType": null,
"promoLabels": null,
"promoStart": "2026-11-04",
"promoEnd": "2026-11-10",
"organic": false,
"nutriScore": "B",
"badges": ["Nutri-Score B", "VEGAN", "VEGETARIAN"],
"vegan": true,
"vegetarian": true,
"deposit": false,
"storeOnly": false,
"categoryPath": "Borrel, chips, noten, snacks/Noten/Ongezouten noten gebrand",
"categoryIds": null,
"category": "Borrel, chips, noten, snacks",
"url": "https://www.plus.nl/product/plus-cashewnoten-extra-groot-ongz-bakje-170-g-762827",
"imageUrl": "https://images.ctfassets.net/s0lodsnpsezb/762827_M/fcb08d2fc462caa7c915b4b55baf1bce/762827.png",
"inStock": true,
"availabilityLabel": null,
"detailsRead": true,
"detailsDate": "2026-11-04",
"searchTerm": null,
"scrapedAt": "2026-11-04T19:35:29.450Z"
}

How does the PLUS Scraper report on its run?

Every run saves a SUMMARY record in its key-value store. From the last full run:

{
"mode": "catalog",
"itemsPushed": 17326,
"distinctIds": 17326,
"productsRead": 17326,
"expectedTotal": 17326,
"coverage": 1,
"organicCount": 930,
"barcodesFromFile": 17326,
"barcodesFetched": 0,
"barcodesMissing": 0,
"detailsRead": 0,
"detailsFromFile": 0,
"detailsFileDate": null,
"stoppedAtChargeLimit": false,
"blocked": false,
"concurrencyReduced": false,
"versionsRefreshed": 0,
"durationSec": 129,
"requests": 1524,
"secondPassRequests": 0,
"statusCodes": { "200": 1524 },
"errors": [],
"retries": [],
"searches": []
}
FieldMeaning
itemsPushed, distinctIdsProducts stored. Only products Apify accepted count.
productsReadDistinct products read from PLUS, including those left out by onlyBonus, maxItems or your charge limit.
expectedTotal, coveragePLUS's own product count, and productsRead / expectedTotal. null in search mode.
organicCountProducts in PLUS's organic filter.
barcodesFromFileBarcodes taken from the file the actor carries.
barcodesFetchedBarcodes read from PLUS in this run, for products new since the file was written.
barcodesMissingProducts without a barcode.
detailsReadProducts whose details were read live in this run.
detailsFromFile, detailsFileDateProducts whose details came from the actor's details file, and the file's date.
searchesIn search mode, PLUS's count and the collected count per keyword or barcode.
stoppedAtChargeLimittrue when the run stopped at your maximum charge.
blockedtrue when PLUS refused twice in a row (HTTP 403); the run then fails with the products it already had.
concurrencyReducedtrue when PLUS answered 403 or 429; the actor then sends fewer requests at a time.
versionsRefreshedTimes the actor re-read PLUS's site version, because PLUS released during the run.
statusCodes, retries, errorsEvery HTTP status received, every retry with its reason, and requests that failed after 3 retries.

A full-catalog run is suspect when coverage is below 1 while stoppedAtChargeLimit is false, when barcodesMissing is above 0, when blocked or concurrencyReduced is true, or when statusCodes holds anything other than 200. Set minItems to make a bad run fail outright.

How does the PLUS Scraper compare to other PLUS scrapers?

PLUS Scraperstudio-amba/plus-nl-scraperharvestedge/dutch-supermarkets-all-11
Price per 1,000$1.50, details $1.00from $1.20 on top plans, $2.00 on free$5.00
Full catalogyes, defaultno, one keyword per runno, keyword search
EAN barcodeyes, every productyes, can be emptyno
Barcode lookupyes, eansnono
Deal datesyesnono
Nutri-Score, vegan, deposityes, withDetailsnono
Organic flagyesnono
Completeness check against PLUS's countyes, every runnono
Proxynone neededNL residential by defaultnot stated

Figures read from each actor's public page on 2026-11-04.

Things to know about PLUS data from the PLUS Scraper

  • PLUS's list holds no barcodes, and its search does not find them. Only each product's details do, one product per request. So the actor carries a barcode file: 17,425 products, which covered all 17,326 products listed on 4 November. A product new since then gets its barcode from its details during the run.
  • Barcodes can change. In the run of 4 November, 7 of 17,326 products had a new barcode since the file was written on 31 October (Oatly Haver cuisine bio, four Derlon products). With withDetails the barcode read in the run wins; the file is updated with each release of the actor.
  • Webshop prices are advice prices. PLUS says the price at the till can differ, because of local price differences.
  • PLUS's deal week runs Wednesday to Tuesday. In the run of Wednesday 4 November, 1,287 of 1,587 deals ran 4 to 10 November.
  • Multi-buy deals usually have no deal price. 2 VOOR 2.99 or 1+1 GRATIS leave the single price unchanged; the deal is in promoText.
  • Some deals carry no label. 611 deals have dates and often a deal price, but no text from PLUS, such as Royal Club Lemon soda at 2.00 instead of 4.69.
  • Deal prices are rounded to the cent. PLUS sometimes sends unrounded ones, such as 1.183.
  • Free-delivery offers are left out. PLUS marks them, and they appear in no deal field and not with onlyBonus.
  • unitPrice matches PLUS's own. Computed from the regular price and size, it equalled PLUS's unit price on 12,292 of 12,345 products compared and was within 2 cents on the rest. Small packs have real but high unit prices, such as โ‚ฌ1,081.67 per litre for 6 ml of eye drops.
  • Vegan and vegetarian come from PLUS's logos and the product name. 12 products named vegan and 17 named vegetarian, such as Hands off Vegan Seriously Dark and Vegetarische Slager products, have no logo at PLUS; a vegan product is vegetarian too, though 1,168 lack PLUS's vegetarian logo. Without withDetails, only the name counts, and the fields are otherwise null.
  • Organic is PLUS's organic filter plus names. 930 products are in the filter; 100 more are named bio, biologisch or organic. With withDetails, PLUS's EU Organic Farming logo counts too.
  • Prices are those with no store chosen. A chosen store shows its own range (10,795 products in store 747), with the same prices in the sample checked.
  • Details come from a file, dated. With withDetails, logos come from the details file the actor ships with (detailsDate), and products the file does not know are read live. In-store availability is not kept in the file: inStock then comes from the product list, as without details. freshDetails reads every detail live, with availability.
  • PLUS gives no category ids, so categoryIds is null. Seasonal categories such as Kerst and Sinterklaas appear in their season.

This actor reads publicly available data only. PLUS product data contains no personal data. It sends a limited number of requests at a time, respects plus.nl's robots.txt, and does not bypass any login or paywall. You are responsible for how you use the data, including any terms that apply to you. See Apify's guide to web scraping legality.

Frequently asked questions about the PLUS Scraper

Can I get PLUS products as CSV or Excel?

Yes. Every run's dataset downloads as CSV, Excel, JSON or XML from Apify, or through the API.

How often should I run it?

PLUS's deals change every Wednesday. Run the full catalog once a week on Wednesday for that week's prices and aanbiedingen.

Does it need proxies?

No. Requests go straight to PLUS: the last full run got HTTP 200 on all 1,524. If PLUS answers 403 or 429, the actor sends fewer requests at a time; after a 403 it also pauses 60 seconds and tries once more, and a second 403 ends the run with blocked: true.

Can I schedule it and send results somewhere?

Yes. Use Apify Schedules, and a webhook or integration to send each run's dataset to your database, Google Sheets, Slack or Notion.

Does it work with the Apify API and SDK?

Yes. Any Apify client (JavaScript, Python, REST) can start the actor and read the dataset.

Is there an official PLUS supermarket API?

No public one. PLUS's webshop runs on actions that are not documented for outside use. This actor reads them for you and returns a stable set of fields, so you do not maintain the integration.

Does every PLUS product have a barcode?

Yes, in the last full run all 17,326. PLUS's list has none, so the actor carries a barcode file and reads the details of products new since it was written.

Can I get vegan PLUS products?

Yes. Run with withDetails and filter on vegan: true. PLUS marks vegan products with a logo in their details, not in the list.

Can I compare PLUS prices with Albert Heijn, Jumbo and Dirk?

Yes. The Albert Heijn, Jumbo and Dirk scrapers by Sleep Mode Systems output the same fields. Match on ean (Albert Heijn writes it with a leading zero, so compare without leading zeros) and compare unitPrice.

Does it give prices per PLUS store?

No. It gives plus.nl's prices with no store chosen. PLUS says shop prices can differ locally.

Does it show next week's PLUS aanbiedingen?

No. PLUS lists a deal once it runs; next week's deals were not published on its site on the Wednesday checked.

Other scrapers by Sleep Mode Systems

ActorWhat it extractsPrice per 1,000
PLUS ScraperPLUS products: prices, deals with dates, EAN, Nutri-Score, vegan$1.50you are here
Albert Heijn ScraperAlbert Heijn products: prices, Bonus deals, EAN, Nutri-Score$1.00
Jumbo ScraperJumbo products: prices, deals with dates, EAN, organic, shelf life$1.50
Dirk ScraperDirk products: prices, next week's deals, EAN, Nutri-Score$2.00
DekaMarkt ScraperDekaMarkt products: prices, next week's deals, EAN, organic$2.00
Hoogvliet ScraperHoogvliet products: prices, next week's deals, EAN, ingredients, vegan$2.00
Vomar ScraperVomar products: prices, every EAN barcode, BIO, categories$1.00
Poiesz ScraperPoiesz products: prices, deals with dates, EAN, deposit, ingredients$1.50
Ekoplaza ScraperEkoplaza products: prices, next week's deals, EAN, allergens, Ekoscope$2.00
Aldi NL ScraperAldi products: prices, next week's deals, special buys, seals$1.00

All of them share the same output fields, so you can combine their datasets directly. The Aldi NL Scraper adds articleNumber, description, specialBuy, vegan, vegetarian, ageRestriction and priceDate, and has no barcodes; the Ekoplaza Scraper adds articleNumber, vegan, vegetarian, ekoscope, origin, shelfLifeDays, ageRestriction, soldByWeight, detailsDate, description, ingredients, allergens, mayContain, freeFrom, nutrition and priceDate; the Poiesz Scraper adds promoDescription, deposit, depositAmount, ageRestriction, alcoholPercentage, purchaseLimit, soldByWeight, detailsRead, detailsDate, ingredients, allergens, mayContain, freeFrom, nutrition and storage; the Vomar Scraper adds soldByWeight, and fills gtins with every barcode Vomar lists; the Hoogvliet Scraper adds promoDescription, vegan, vegetarian, shelfLifeDays, ageRestriction, soldByWeight, ingredients, nutrition, storage, origin, alcoholPercentage and priceDate; the DekaMarkt and Dirk Scrapers add soldByWeight and priceDate; PLUS adds vegan, vegetarian, deposit, storeOnly, detailsRead and detailsDate; Jumbo adds promotions and shelfLifeDays. Category ids are text on Jumbo, Dirk, DekaMarkt, Hoogvliet, Vomar, Poiesz, Ekoplaza and Aldi, numbers on Albert Heijn, and not given by PLUS.

Support for the PLUS Scraper

Questions, a missing field, or a custom pipeline on top of this data: write to Imad at imad@sleepmodesystems.com. Bugs go in the Issues tab of this actor.